mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-01 12:41:55 -07:00
Compare commits
66 Commits
v0.6.3beta
...
v0.7.1beta
Author | SHA1 | Date | |
---|---|---|---|
|
f9985a36b3 | ||
|
ad03360665 | ||
|
3914672dd5 | ||
|
78c6371743 | ||
|
f789a14527 | ||
|
b1e3430405 | ||
|
a4f82491b7 | ||
|
da83ef7b96 | ||
|
2d856ac4b0 | ||
|
29e2bb27f6 | ||
|
2f3b2db83d | ||
|
bf8bd87d11 | ||
|
c0c75db621 | ||
|
f461ea3105 | ||
|
668dc9bd9c | ||
|
b55b6c95f2 | ||
|
676e4c36c5 | ||
|
ad66c158ba | ||
|
ab44aabbd7 | ||
|
4c4c36096b | ||
|
c923b0e538 | ||
|
2936368e80 | ||
|
5eaf93697a | ||
|
11c88e2503 | ||
|
4b334594dc | ||
|
06c0be5ea6 | ||
|
6f7377f381 | ||
|
c44cafda97 | ||
|
ddc4cbbd7e | ||
|
e6872bddf4 | ||
|
a7a3c0fc1d | ||
|
c8c5e0b90a | ||
|
8482063157 | ||
|
92e17f2925 | ||
|
491b99c61e | ||
|
75a580feda | ||
|
91249675de | ||
|
46306e59eb | ||
|
cd0a01f4de | ||
|
75c2a378e3 | ||
|
96f19d706a | ||
|
3278db67a2 | ||
|
aa3bc65342 | ||
|
a7b595d968 | ||
|
05736bc1e3 | ||
|
3bf172a37e | ||
|
22c4ecf496 | ||
|
3f43f94dc4 | ||
|
4b796d30c1 | ||
|
5762e3b9e2 | ||
|
1cf2f378d4 | ||
|
6a16f11d63 | ||
|
a545992891 | ||
|
f5936f97d6 | ||
|
141f9810bb | ||
|
1599dc47d1 | ||
|
42d18143e5 | ||
|
f9756d10d4 | ||
|
0d7a8cca79 | ||
|
9655d0c138 | ||
|
5a22335b8d | ||
|
0277f4c6bd | ||
|
8d05dddb98 | ||
|
0d54451c67 | ||
|
cda0c4577e | ||
|
239aa2cec4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@ _deps
|
||||
build/
|
||||
result
|
||||
/.vscode/
|
||||
.envrc
|
||||
|
||||
*.o
|
||||
*-protocol.c
|
||||
|
@@ -37,7 +37,7 @@ execute_process(
|
||||
|
||||
include_directories(. PRIVATE "subprojects/wlroots/include/")
|
||||
include_directories(. PRIVATE "subprojects/wlroots/build/include/")
|
||||
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
|
@@ -26,6 +26,7 @@ If your bug is one that doesn't crash Hyprland, but feels like invalid behavior,
|
||||
If your bug crashes Hyprland, append additionally:
|
||||
- The Hyprland log
|
||||
- Coredump / Coredump analysis (with a stacktrace)
|
||||
- Your config
|
||||
|
||||
**Important**: Please do NOT use any package for reporting bugs! Clone and compile from source.
|
||||
|
||||
|
@@ -3,6 +3,11 @@
|
||||
#
|
||||
# Refer to the wiki for more information.
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
#
|
||||
|
||||
monitor=,1280x720@60,0x0,1
|
||||
workspace=DP-1,1
|
||||
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1656239181,
|
||||
"narHash": "sha256-wW1xRFBn376yGloXZ4QzBE4hjipMawpV18Lshd9QSPw=",
|
||||
"lastModified": 1657447684,
|
||||
"narHash": "sha256-FCP9AuU1q6PE3vOeM5SFf58f/UKPBAsoSGDUGamNBbo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f2537a505d45c31fe5d9c27ea9829b6f4c4e6ac5",
|
||||
"rev": "5f43d8b088d3771274bcfb69d3c7435b1121ac88",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1655824477,
|
||||
"narHash": "sha256-1kskHOLsnisR3kqIL5IHrQbQG/4xoXxeEf1ExMV6/RU=",
|
||||
"lastModified": 1656865312,
|
||||
"narHash": "sha256-xtQ0zwJZwN8sciruveM10CzKz6TWxBY8SyXa8E4jly4=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "5c4384a1330faedf975c8b8644881d50390f3613",
|
||||
"rev": "5dc1d4671dd2ca3c1f0f09587c463fdbb542f0a4",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
13
flake.nix
13
flake.nix
@@ -32,7 +32,8 @@
|
||||
src = inputs.wlroots;
|
||||
});
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
version = "0.6.2beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.7.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
@@ -47,6 +48,16 @@
|
||||
default = self.packages.${system}.hyprland;
|
||||
});
|
||||
|
||||
devShells = genSystems (system: {
|
||||
default = pkgsFor.${system}.mkShell.override {stdenv = pkgsFor.${system}.gcc12Stdenv;} {
|
||||
name = "hyprland-shell";
|
||||
inputsFrom = [
|
||||
self.packages.${system}.wlroots-hyprland
|
||||
self.packages.${system}.hyprland
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||
|
||||
nixosModules.default = import ./nix/module.nix self;
|
||||
|
@@ -27,6 +27,7 @@ const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
|
||||
keyword
|
||||
version
|
||||
kill
|
||||
splash
|
||||
hyprpaper
|
||||
reload)#";
|
||||
|
||||
@@ -201,6 +202,7 @@ int main(int argc, char** argv) {
|
||||
else if (!strcmp(argv[1], "layers")) request("layers");
|
||||
else if (!strcmp(argv[1], "version")) request("version");
|
||||
else if (!strcmp(argv[1], "kill")) request("kill");
|
||||
else if (!strcmp(argv[1], "splash")) request("splash");
|
||||
else if (!strcmp(argv[1], "devices")) request("devices");
|
||||
else if (!strcmp(argv[1], "reload")) request("reload");
|
||||
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.6.2beta',
|
||||
default_options : ['warning_level=2', 'cpp_std=c++20', 'default_library=static', 'optimization=3'])
|
||||
version : '0.7.0beta',
|
||||
default_options : ['warning_level=2', 'default_library=static', 'optimization=3'])
|
||||
|
||||
add_global_arguments('-std=c++23', language: 'cpp')
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
|
@@ -61,6 +61,11 @@ stdenv.mkDerivation {
|
||||
./meson-build.patch
|
||||
];
|
||||
|
||||
# Fix hardcoded paths to /usr installation
|
||||
postPatch = ''
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
'';
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
|
||||
meta = with lib; {
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#include "Compositor.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include <random>
|
||||
|
||||
CCompositor::CCompositor() {
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
@@ -22,29 +24,30 @@ CCompositor::CCompositor() {
|
||||
|
||||
Debug::log(INFO, "If you are crashing, or encounter any bugs, please consult https://github.com/hyprwm/Hyprland/wiki/Crashing-and-bugs\n\n");
|
||||
|
||||
setRandomSplash();
|
||||
|
||||
Debug::log(LOG, "\nCurrent splash: %s\n\n", m_szCurrentSplash.c_str());
|
||||
|
||||
m_sWLDisplay = wl_display_create();
|
||||
|
||||
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
|
||||
|
||||
if (!m_sWLRBackend) {
|
||||
Debug::log(CRIT, "m_sWLRBackend was NULL!");
|
||||
RIP("m_sWLRBackend NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_backend_autocreate() failed!");
|
||||
}
|
||||
|
||||
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
|
||||
if (m_iDRMFD < 0) {
|
||||
Debug::log(CRIT, "Couldn't query the DRM FD!");
|
||||
RIP("DRMFD NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_backend_get_drm_fd() failed!");
|
||||
}
|
||||
|
||||
m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD);
|
||||
|
||||
if (!m_sWLRRenderer) {
|
||||
Debug::log(CRIT, "m_sWLRRenderer was NULL!");
|
||||
RIP("m_sWLRRenderer NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_gles2_renderer_create_with_drm_fd() failed!");
|
||||
}
|
||||
|
||||
wlr_renderer_init_wl_display(m_sWLRRenderer, m_sWLDisplay);
|
||||
@@ -53,16 +56,14 @@ CCompositor::CCompositor() {
|
||||
|
||||
if (!m_sWLRAllocator) {
|
||||
Debug::log(CRIT, "m_sWLRAllocator was NULL!");
|
||||
RIP("m_sWLRAllocator NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_allocator_autocreate() failed!");
|
||||
}
|
||||
|
||||
m_sWLREGL = wlr_gles2_renderer_get_egl(m_sWLRRenderer);
|
||||
|
||||
if (!m_sWLREGL) {
|
||||
Debug::log(CRIT, "m_sWLREGL was NULL!");
|
||||
RIP("m_sWLREGL NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_gles2_renderer_get_egl() failed!");
|
||||
}
|
||||
|
||||
m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, m_sWLRRenderer);
|
||||
@@ -124,8 +125,12 @@ CCompositor::CCompositor() {
|
||||
|
||||
m_sWLRForeignRegistry = wlr_xdg_foreign_registry_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRIdleInhibitMgr = wlr_idle_inhibit_v1_create(m_sWLDisplay);
|
||||
|
||||
wlr_xdg_foreign_v1_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
|
||||
m_sWLRPointerGestures = wlr_pointer_gestures_v1_create(m_sWLDisplay);
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
@@ -137,6 +142,14 @@ void handleCritSignal(int signo) {
|
||||
exit(signo);
|
||||
}
|
||||
|
||||
void CCompositor::setRandomSplash() {
|
||||
std::random_device dev;
|
||||
std::mt19937 engine(dev());
|
||||
std::uniform_int_distribution<> distribution(0, SPLASHES.size() - 1);
|
||||
|
||||
m_szCurrentSplash = SPLASHES[distribution(engine)];
|
||||
}
|
||||
|
||||
void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend");
|
||||
addWLSignal(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGSurface, m_sWLRXDGShell, "XDG Shell");
|
||||
@@ -145,6 +158,9 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_begin, &Events::listen_swipeBegin, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_update, &Events::listen_swipeUpdate, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_end, &Events::listen_swipeEnd, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
|
||||
@@ -160,6 +176,7 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
|
||||
|
||||
signal(SIGINT, handleCritSignal);
|
||||
signal(SIGTERM, handleCritSignal);
|
||||
@@ -245,7 +262,7 @@ void CCompositor::startCompositor() {
|
||||
if (!m_szWLDisplaySocket) {
|
||||
Debug::log(CRIT, "m_szWLDisplaySocket NULL!");
|
||||
wlr_backend_destroy(m_sWLRBackend);
|
||||
RIP("m_szWLDisplaySocket NULL!");
|
||||
throw std::runtime_error("m_szWLDisplaySocket was null! (wl_display_add_socket_auto failed)");
|
||||
}
|
||||
|
||||
setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket, 1);
|
||||
@@ -258,7 +275,7 @@ void CCompositor::startCompositor() {
|
||||
Debug::log(CRIT, "Backend did not start!");
|
||||
wlr_backend_destroy(m_sWLRBackend);
|
||||
wl_display_destroy(m_sWLDisplay);
|
||||
RIP("Backend did not start!");
|
||||
throw std::runtime_error("The backend could not start!");
|
||||
}
|
||||
|
||||
wlr_xcursor_manager_set_cursor_image(m_sWLRXCursorMgr, "left_ptr", m_sWLRCursor);
|
||||
@@ -361,6 +378,12 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
||||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->m_bHidden)
|
||||
@@ -404,14 +427,29 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void findExtensionForVector2D(wlr_surface* surface, int x, int y, void* data) {
|
||||
const auto DATA = (SExtensionFindingData*)data;
|
||||
|
||||
wlr_box box = {DATA->origin.x + x, DATA->origin.y + y, surface->current.width, surface->current.height};
|
||||
|
||||
if (wlr_box_contains_point(&box, DATA->vec.x, DATA->vec.y))
|
||||
*DATA->found = surface;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
// special workspace
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden)
|
||||
if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden && w->m_iX11Type != 2)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
@@ -419,13 +457,37 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
return w->get();
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2) {
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||
return w->get();
|
||||
|
||||
if (!(*w)->m_bIsX11) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin =(*w)->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface((*w)->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
|
||||
if (resultSurf)
|
||||
return w->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for windows, we need to check their extensions too, first.
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin = w->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface(w->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
|
||||
if (resultSurf)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden)
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -436,6 +498,12 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
const auto PMONITOR = getMonitorFromCursor();
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->m_bHidden)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped)
|
||||
@@ -536,7 +604,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
|
||||
if (windowValidMapped(PLASTWINDOW)) {
|
||||
updateWindowBorderColor(PLASTWINDOW);
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
|
||||
if (PLASTWINDOW->m_bIsX11) {
|
||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||
@@ -559,7 +627,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.goalv();
|
||||
wlr_seat_pointer_notify_enter(m_sSeat.seat, PWINDOWSURFACE, POINTERLOCAL.x, POINTERLOCAL.y);
|
||||
|
||||
updateWindowBorderColor(pWindow);
|
||||
updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
// Send an event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle));
|
||||
@@ -573,12 +641,16 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
if (m_sSeat.seat->keyboard_state.focused_surface == pSurface || (pWindowOwner && m_sSeat.seat->keyboard_state.focused_surface == g_pXWaylandManager->getWindowSurface(pWindowOwner)))
|
||||
return; // Don't focus when already focused on this.
|
||||
|
||||
if (!pSurface)
|
||||
return;
|
||||
|
||||
// Unfocus last surface if should
|
||||
if (m_pLastFocus && m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus))
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(m_pLastFocus)->toplevel, false);
|
||||
if (m_pLastFocus && ((m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus)) || !pSurface))
|
||||
g_pXWaylandManager->activateSurface(m_pLastFocus, false);
|
||||
|
||||
if (!pSurface) {
|
||||
wlr_seat_keyboard_clear_focus(m_sSeat.seat);
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", ",")); // unfocused
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat);
|
||||
|
||||
@@ -598,6 +670,9 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x, with window name: %s", pSurface, pWindowOwner->m_szTitle.c_str());
|
||||
else
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x", pSurface);
|
||||
|
||||
g_pXWaylandManager->activateSurface(pSurface, false);
|
||||
m_pLastFocus = pSurface;
|
||||
}
|
||||
|
||||
bool CCompositor::windowValidMapped(CWindow* pWindow) {
|
||||
@@ -689,6 +764,8 @@ void CCompositor::sanityCheckWorkspaces() {
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iID == SPECIAL_WORKSPACE_ID && WINDOWSONWORKSPACE == 0) {
|
||||
@@ -700,6 +777,8 @@ void CCompositor::sanityCheckWorkspaces() {
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -910,6 +989,29 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
||||
bool gotToWindow = false;
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && !gotToWindow)
|
||||
continue;
|
||||
|
||||
if (it->get() == pWindow) {
|
||||
gotToWindow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
return it->get();
|
||||
}
|
||||
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
return it->get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CCompositor::getNextAvailableNamedWorkspace() {
|
||||
int lowest = -1337 + 1;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
@@ -1032,25 +1134,50 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::updateAllWindowsBorders() {
|
||||
void CCompositor::updateAllWindowsAnimatedDecorationValues() {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
updateWindowBorderColor(w.get());
|
||||
updateWindowAnimatedDecorationValues(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
|
||||
void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
// optimization
|
||||
static int64_t* ACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.active_border")->intValue;
|
||||
static int64_t* INACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.inactive_border")->intValue;
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
static auto *const PFULLSCREENALPHA = &g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity")->floatValue;
|
||||
|
||||
|
||||
// border
|
||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
||||
if (RENDERDATA.isBorderColor)
|
||||
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
|
||||
else
|
||||
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
|
||||
|
||||
|
||||
// opacity
|
||||
if (pWindow->m_bIsFullscreen) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
|
||||
else {
|
||||
if (pWindow == m_pLastWindow)
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha != -1 ? pWindow->m_sSpecialRenderData.alpha : *PACTIVEALPHA;
|
||||
else
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive : *PINACTIVEALPHA;
|
||||
}
|
||||
} else {
|
||||
if (pWindow == m_pLastWindow)
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha != -1 ? pWindow->m_sSpecialRenderData.alpha : *PACTIVEALPHA;
|
||||
else
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive : *PINACTIVEALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
|
||||
@@ -1188,4 +1315,13 @@ CWindow* CCompositor::getX11Parent(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::updateWorkspaceWindowDecos(const int& id) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID != id)
|
||||
continue;
|
||||
|
||||
w->updateWindowDecos();
|
||||
}
|
||||
}
|
||||
|
@@ -61,11 +61,14 @@ public:
|
||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||
wlr_idle_inhibit_manager_v1* m_sWLRIdleInhibitMgr;
|
||||
wlr_pointer_gestures_v1* m_sWLRPointerGestures;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
const char* m_szWLDisplaySocket;
|
||||
std::string m_szInstanceSignature = "";
|
||||
std::string m_szCurrentSplash = "error";
|
||||
|
||||
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
||||
std::vector<std::unique_ptr<CWindow>> m_vWindows;
|
||||
@@ -99,7 +102,7 @@ public:
|
||||
bool windowExists(CWindow*);
|
||||
bool windowValidMapped(CWindow*);
|
||||
CWindow* vectorToWindow(const Vector2D&);
|
||||
CWindow* vectorToWindowIdeal(const Vector2D&);
|
||||
CWindow* vectorToWindowIdeal(const Vector2D&); // used only for finding a window to focus on, basically a "findFocusableWindow"
|
||||
CWindow* vectorToWindowTiled(const Vector2D&);
|
||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::list<SLayerSurface*>*, Vector2D*, SLayerSurface**);
|
||||
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||
@@ -113,6 +116,7 @@ public:
|
||||
CWorkspace* getWorkspaceByName(const std::string&);
|
||||
CWorkspace* getWorkspaceByString(const std::string&);
|
||||
void sanityCheckWorkspaces();
|
||||
void updateWorkspaceWindowDecos(const int&);
|
||||
int getWindowsOnWorkspace(const int&);
|
||||
CWindow* getFirstWindowOnWorkspace(const int&);
|
||||
void fixXWaylandWindowsOnWorkspace(const int&);
|
||||
@@ -124,12 +128,13 @@ public:
|
||||
CWindow* getWindowInDirection(CWindow*, char);
|
||||
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
|
||||
CWindow* getNextWindowOnWorkspace(CWindow*);
|
||||
CWindow* getPrevWindowOnWorkspace(CWindow*);
|
||||
int getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
CWindow* getConstraintWindow(SMouse*);
|
||||
SMonitor* getMonitorInDirection(const char&);
|
||||
void updateAllWindowsBorders();
|
||||
void updateWindowBorderColor(CWindow*);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
void moveWindowToWorkspace(CWindow*, const std::string&);
|
||||
int getNextAvailableMonitorID();
|
||||
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
|
||||
@@ -140,6 +145,7 @@ public:
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -7,6 +7,7 @@ CWindow::CWindow() {
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
|
||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ public:
|
||||
DYNLISTENER(unmapWindow);
|
||||
DYNLISTENER(destroyWindow);
|
||||
DYNLISTENER(setTitleWindow);
|
||||
DYNLISTENER(setGeometryX11U);
|
||||
DYNLISTENER(fullscreenWindow);
|
||||
DYNLISTENER(newPopupXDG);
|
||||
// DYNLISTENER(newSubsurfaceWindow);
|
||||
@@ -105,6 +106,9 @@ public:
|
||||
SWindowSpecialRenderData m_sSpecialRenderData;
|
||||
SWindowAdditionalConfigData m_sAdditionalConfigData;
|
||||
|
||||
// for alpha
|
||||
CAnimatedVariable m_fActiveInactiveAlpha;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;
|
||||
|
@@ -36,6 +36,10 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["general:col.active_border"].intValue = 0xffffffff;
|
||||
configValues["general:col.inactive_border"].intValue = 0xff444444;
|
||||
configValues["general:cursor_inactive_timeout"].intValue = 0;
|
||||
|
||||
configValues["misc:disable_hyprland_logo"].intValue = 0;
|
||||
configValues["misc:disable_splash_rendering"].intValue = 0;
|
||||
configValues["misc:no_vfr"].intValue = 1;
|
||||
|
||||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
@@ -43,8 +47,6 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["debug:damage_blink"].intValue = 0;
|
||||
configValues["debug:disable_logs"].intValue = 0;
|
||||
|
||||
configValues["experimental:vfr"].intValue = 0;
|
||||
|
||||
configValues["decoration:rounding"].intValue = 1;
|
||||
configValues["decoration:blur"].intValue = 1;
|
||||
configValues["decoration:blur_size"].intValue = 8;
|
||||
@@ -104,6 +106,13 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
|
||||
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
|
||||
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||
|
||||
configValues["gestures:workspace_swipe"].intValue = 0;
|
||||
configValues["gestures:workspace_swipe_distance"].intValue = 300;
|
||||
configValues["gestures:workspace_swipe_invert"].intValue = 1;
|
||||
configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30;
|
||||
configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f;
|
||||
|
||||
configValues["input:follow_mouse"].intValue = 1;
|
||||
|
||||
@@ -126,6 +135,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
cfgValues["clickfinger_behavior"].intValue = 0;
|
||||
cfgValues["middle_button_emulation"].intValue = 0;
|
||||
cfgValues["tap-to-click"].intValue = 1;
|
||||
cfgValues["drag_lock"].intValue = 0;
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
@@ -149,17 +159,15 @@ void CConfigManager::init() {
|
||||
|
||||
void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) {
|
||||
if (configValues.find(COMMAND) == configValues.end()) {
|
||||
if (COMMAND[0] == '$') {
|
||||
// register a dynamic var
|
||||
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
|
||||
configDynamicVars[COMMAND.substr(1)] = VALUE;
|
||||
} else {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
}
|
||||
if (COMMAND.find("device:") != 0 /* devices parsed later */) {
|
||||
if (COMMAND[0] == '$') {
|
||||
// register a dynamic var
|
||||
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
|
||||
configDynamicVars[COMMAND.substr(1)] = VALUE;
|
||||
} else {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
}
|
||||
|
||||
if (COMMAND.find("device:") == 0 /* devices parsed later */) {
|
||||
parseError = "";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -193,7 +201,12 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else
|
||||
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
|
||||
CONFIGENTRY->intValue = 1;
|
||||
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
|
||||
CONFIGENTRY->intValue = 0;
|
||||
}
|
||||
else
|
||||
CONFIGENTRY->intValue = stol(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
@@ -356,7 +369,7 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
||||
|
||||
if (curitem.find_first_of('@') != std::string::npos)
|
||||
if (curitem.contains("@"))
|
||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
||||
|
||||
nextItem();
|
||||
@@ -505,8 +518,13 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
return;
|
||||
}
|
||||
|
||||
if (KEY != "")
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
if (KEY != "") {
|
||||
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
else
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
||||
@@ -552,6 +570,10 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
|
||||
}
|
||||
|
||||
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
|
||||
m_dBlurLSNamespaces.emplace_back(value);
|
||||
}
|
||||
|
||||
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
||||
|
||||
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
||||
@@ -577,6 +599,23 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
|
||||
|
||||
auto value = rawpath;
|
||||
|
||||
if (value.length() < 2) {
|
||||
Debug::log(ERR, "source= path garbage");
|
||||
parseError = "source path " + value + " bogus!";
|
||||
return;
|
||||
}
|
||||
|
||||
if (value[0] == '.') {
|
||||
auto currentDir = configCurrentPath.substr(0, configCurrentPath.find_last_of('/'));
|
||||
|
||||
if (value[1] == '.') {
|
||||
auto parentDir = currentDir.substr(0, currentDir.find_last_of('/'));
|
||||
value.replace(0, 2, parentDir);
|
||||
} else {
|
||||
value.replace(0, 1, currentDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (value[0] == '~') {
|
||||
value.replace(0, 1, std::string(ENVHOME));
|
||||
}
|
||||
@@ -653,6 +692,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
||||
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
|
||||
else
|
||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||
|
||||
@@ -665,7 +705,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -705,7 +745,7 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
if (line.find(" {") != std::string::npos) {
|
||||
if (line.contains(" {")) {
|
||||
auto cat = line.substr(0, line.find(" {"));
|
||||
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
|
||||
if (currentCategory.length() != 0) {
|
||||
@@ -719,7 +759,7 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.find("}") != std::string::npos && currentCategory != "") {
|
||||
if (line.contains("}") && currentCategory != "") {
|
||||
currentCategory = "";
|
||||
return;
|
||||
}
|
||||
@@ -755,6 +795,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
m_mAdditionalReservedAreas.clear();
|
||||
configDynamicVars.clear();
|
||||
deviceConfigs.clear();
|
||||
m_dBlurLSNamespaces.clear();
|
||||
|
||||
// paths
|
||||
configPaths.clear();
|
||||
@@ -856,7 +897,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
}
|
||||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
@@ -1086,3 +1127,12 @@ bool CConfigManager::deviceConfigExists(const std::string& dev) {
|
||||
return it != deviceConfigs.end();
|
||||
}
|
||||
|
||||
bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||
for (auto& bls : m_dBlurLSNamespaces) {
|
||||
if (bls == ns) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -65,6 +65,7 @@ public:
|
||||
float getDeviceFloat(const std::string&, const std::string&);
|
||||
std::string getDeviceString(const std::string&, const std::string&);
|
||||
bool deviceConfigExists(const std::string&);
|
||||
bool shouldBlurLS(const std::string&);
|
||||
|
||||
SConfigValue* getConfigValuePtr(std::string);
|
||||
|
||||
@@ -102,6 +103,7 @@ private:
|
||||
|
||||
std::deque<SMonitorRule> m_dMonitorRules;
|
||||
std::deque<SWindowRule> m_dWindowRules;
|
||||
std::deque<std::string> m_dBlurLSNamespaces;
|
||||
|
||||
bool firstExecDispatched = false;
|
||||
std::deque<std::string> firstExecRequests;
|
||||
@@ -127,6 +129,7 @@ private:
|
||||
void handleAnimation(const std::string&, const std::string&);
|
||||
void handleSource(const std::string&, const std::string&);
|
||||
void handleSubmap(const std::string&, const std::string&);
|
||||
void handleBlurLS(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
@@ -9,6 +9,12 @@ PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
|
||||
OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
########################################################################################
|
||||
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
#
|
||||
|
||||
autogenerated=1 # remove this line to get rid of the warning on top.
|
||||
|
||||
monitor=,1920x1080@60,0x0,1
|
||||
|
@@ -16,8 +16,8 @@
|
||||
std::string monitorsRequest() {
|
||||
std::string result = "";
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform);
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tactive: %s\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -58,13 +58,13 @@ std::string layersRequest() {
|
||||
std::string result = "";
|
||||
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s:\n");
|
||||
result += getFormat("Monitor %s:\n", mon->szName.c_str());
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat("\tLayer level %i:\n", layerLevel);
|
||||
|
||||
for (auto& layer : level) {
|
||||
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height);
|
||||
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i, namespace: %s\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height, layer->szNamespace.c_str());
|
||||
}
|
||||
|
||||
layerLevel++;
|
||||
@@ -87,7 +87,7 @@ std::string devicesRequest() {
|
||||
result += "\n\nKeyboards:\n";
|
||||
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n", &k, k.keyboard->name);
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n\t\t\trules: r \"%s\", m \"%s\", l \"%s\", v \"%s\", o \"%s\"\n", &k, k.keyboard->name, k.currentRules.rules.c_str(), k.currentRules.model.c_str(), k.currentRules.layout.c_str(), k.currentRules.variant.c_str(), k.currentRules.options.c_str());
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
@@ -158,7 +158,7 @@ std::string dispatchKeyword(std::string in) {
|
||||
if (COMMAND == "monitor")
|
||||
g_pConfigManager->m_bWantsMonitorReload = true; // for monitor keywords
|
||||
|
||||
if (COMMAND.find("input") != std::string::npos)
|
||||
if (COMMAND.contains("input"))
|
||||
g_pInputManager->setKeyboardLayout(); // update kb layout
|
||||
|
||||
Debug::log(LOG, "Hyprctl: keyword %s : %s", COMMAND.c_str(), VALUE.c_str());
|
||||
@@ -181,6 +181,10 @@ std::string killRequest() {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
std::string splashRequest() {
|
||||
return g_pCompositor->m_szCurrentSplash;
|
||||
}
|
||||
|
||||
std::string getReply(std::string);
|
||||
|
||||
std::string dispatchBatch(std::string request) {
|
||||
@@ -234,6 +238,8 @@ std::string getReply(std::string request) {
|
||||
return reloadRequest();
|
||||
else if (request == "devices")
|
||||
return devicesRequest();
|
||||
else if (request == "splash")
|
||||
return splashRequest();
|
||||
else if (request.find("dispatch") == 0)
|
||||
return dispatchRequest(request);
|
||||
else if (request.find("keyword") == 0)
|
||||
@@ -265,12 +271,14 @@ void HyprCtl::tickHyprCtl() {
|
||||
|
||||
std::string getRequestFromThread(std::string rq) {
|
||||
// we need to do something to wake hyprland up if VFR is enabled
|
||||
static auto *const VFRENABLED = &g_pConfigManager->getConfigValuePtr("experimental:vfr")->intValue;
|
||||
if (*VFRENABLED) {
|
||||
// TODO: is this safe...?
|
||||
// this might be a race condition
|
||||
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
// TODO: is this safe...?
|
||||
// this might be a race condition
|
||||
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
|
||||
if (!*PNOVFR)
|
||||
wlr_output_schedule_frame(g_pCompositor->m_vMonitors.front()->output);
|
||||
}
|
||||
|
||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
|
@@ -16,8 +16,6 @@
|
||||
#define ISDEBUG false
|
||||
#endif
|
||||
|
||||
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
|
||||
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
||||
#define DYNLISTENFUNC(name) void listener_##name(void*, void*);
|
||||
#define DYNLISTENER(name) CHyprWLListener hyprListener_##name;
|
||||
|
@@ -151,11 +151,29 @@ void Events::listener_newVirtPtr(wl_listener* listener, void* data) {
|
||||
const auto POINTER = EV->new_pointer;
|
||||
const auto DEVICE = &POINTER->pointer.base;
|
||||
|
||||
g_pInputManager->newMouse(DEVICE);
|
||||
g_pInputManager->newMouse(DEVICE, true);
|
||||
}
|
||||
|
||||
void Events::listener_destroyMouse(void* owner, void* data) {
|
||||
const auto PMOUSE = (SMouse*)owner;
|
||||
|
||||
g_pInputManager->destroyMouse(PMOUSE->mouse);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_swipeBegin(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_begin_event*)data;
|
||||
|
||||
g_pInputManager->onSwipeBegin(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_swipeUpdate(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_update_event*)data;
|
||||
|
||||
g_pInputManager->onSwipeUpdate(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_swipeEnd(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_end_event*)data;
|
||||
|
||||
g_pInputManager->onSwipeEnd(EVENT);
|
||||
}
|
||||
|
@@ -49,6 +49,7 @@ namespace Events {
|
||||
DYNLISTENFUNC(fullscreenWindow);
|
||||
DYNLISTENFUNC(activateX11);
|
||||
DYNLISTENFUNC(configureX11);
|
||||
DYNLISTENFUNC(unmanagedSetGeometry);
|
||||
|
||||
// Window subsurfaces
|
||||
// LISTENER(newSubsurfaceWindow);
|
||||
@@ -112,4 +113,10 @@ namespace Events {
|
||||
|
||||
// Renderer destroy
|
||||
LISTENER(RendererDestroy);
|
||||
|
||||
LISTENER(newIdleInhibitor);
|
||||
|
||||
LISTENER(swipeBegin);
|
||||
LISTENER(swipeEnd);
|
||||
LISTENER(swipeUpdate);
|
||||
};
|
@@ -32,8 +32,9 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
}
|
||||
|
||||
const auto PMONITOR = (SMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].push_back(new SLayerSurface());
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].back();
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].emplace_back(new SLayerSurface());
|
||||
|
||||
layerSurface->szNamespace = WLRLAYERSURFACE->_namespace;
|
||||
|
||||
if (!WLRLAYERSURFACE->output) {
|
||||
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors.front()->output; // TODO: current mon
|
||||
@@ -50,6 +51,8 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
WLRLAYERSURFACE->data = layerSurface;
|
||||
layerSurface->monitorID = PMONITOR->ID;
|
||||
|
||||
layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace);
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x (namespace %s layer %d) created on monitor %s", layerSurface->layerSurface, layerSurface->layerSurface->_namespace, layerSurface->layer, PMONITOR->szName.c_str());
|
||||
}
|
||||
|
||||
@@ -115,9 +118,14 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
|
||||
if (layersurface->layerSurface->current.keyboard_interactive)
|
||||
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) // don't focus if constrained
|
||||
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
|
||||
|
||||
// mouse enter always, keeb only when needed
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y);
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
|
||||
|
||||
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
@@ -150,14 +158,17 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
if (layersurface->layerSurface->mapped)
|
||||
layersurface->layerSurface->mapped = false;
|
||||
|
||||
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus)
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
// refocus if needed
|
||||
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) {
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
@@ -206,5 +217,8 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
|
||||
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
|
||||
|
||||
// update geom if it changed
|
||||
layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, layersurface->layerSurface->surface->current.width, layersurface->layerSurface->surface->current.height};
|
||||
|
||||
g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y);
|
||||
}
|
@@ -149,10 +149,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
|
||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||
PNEWWORKSPACE->setActive(true);
|
||||
//
|
||||
|
||||
if (!pMostHzMonitor || monitorRule.refreshRate > pMostHzMonitor->refreshRate)
|
||||
pMostHzMonitor = PNEWMONITOR;
|
||||
//
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||
g_pCompositor->m_pLastMonitor = PNEWMONITOR;
|
||||
@@ -173,7 +173,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
|
||||
static auto *const PDAMAGEBLINK = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
|
||||
static auto *const VFRENABLED = &g_pConfigManager->getConfigValuePtr("experimental:vfr")->intValue;
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
static int damageBlinkCleanup = 0; // because double-buffered
|
||||
|
||||
@@ -182,22 +182,22 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
g_pDebugOverlay->frameData(PMONITOR);
|
||||
}
|
||||
|
||||
// Hack: only check when monitor with top hz refreshes, saves a bit of resources.
|
||||
// This is for stuff that should be run every frame
|
||||
if (PMONITOR->ID == pMostHzMonitor->ID || *VFRENABLED) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
||||
// checks //
|
||||
if (PMONITOR->ID == pMostHzMonitor->ID || !*PNOVFR) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
||||
g_pCompositor->sanityCheckWorkspaces();
|
||||
g_pAnimationManager->tick();
|
||||
g_pCompositor->cleanupFadingOut();
|
||||
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
|
||||
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
|
||||
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
|
||||
|
||||
if (g_pConfigManager->m_bWantsMonitorReload)
|
||||
g_pConfigManager->performMonitorReload();
|
||||
|
||||
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
|
||||
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
|
||||
}
|
||||
// //
|
||||
|
||||
if (PMONITOR->framesToSkip > 0) {
|
||||
PMONITOR->framesToSkip -= 1;
|
||||
@@ -233,7 +233,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
pixman_region32_fini(&damage);
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
|
||||
if (!*VFRENABLED)
|
||||
if (*PDAMAGEBLINK || *PNOVFR)
|
||||
wlr_output_schedule_frame(PMONITOR->output);
|
||||
|
||||
return;
|
||||
@@ -270,7 +270,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
// potentially can save on resources.
|
||||
|
||||
g_pHyprOpenGL->begin(PMONITOR, &damage);
|
||||
g_pHyprOpenGL->clear(CColor(100, 11, 11, 255));
|
||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||
|
||||
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||
@@ -323,7 +323,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
wlr_output_commit(PMONITOR->output);
|
||||
|
||||
if (!*VFRENABLED)
|
||||
if (*PDAMAGEBLINK || *PNOVFR)
|
||||
wlr_output_schedule_frame(PMONITOR->output);
|
||||
|
||||
if (*PDEBUGOVERLAY == 1) {
|
||||
@@ -391,7 +391,6 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::unique_ptr<SMonitor>& el) { return el.get() == pMonitor; }));
|
||||
|
||||
// update the pMostHzMonitor
|
||||
if (pMostHzMonitor == pMonitor) {
|
||||
int mostHz = 0;
|
||||
SMonitor* pMonitorMostHz = nullptr;
|
||||
|
@@ -92,6 +92,9 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
|
||||
|
||||
ASSERT(PWINDOW);
|
||||
|
||||
if (!PWINDOW->m_bIsMapped)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "New layer popup created from XDG window %x -> %s", PWINDOW, PWINDOW->m_szTitle.c_str());
|
||||
|
||||
const auto WLRPOPUP = (wlr_xdg_popup*)data;
|
||||
|
@@ -32,6 +32,9 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
||||
void Events::listener_mapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
@@ -122,13 +125,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
requestedWorkspace = WORKSPACERQ;
|
||||
}
|
||||
|
||||
if (requestedWorkspace == "special") {
|
||||
requestedWorkspace = "";
|
||||
workspaceSilent = false;
|
||||
Debug::log(LOG, "windowrule=workspace special is not allowed!");
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
|
||||
} else if (r.szRule.find("float") == 0) {
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
@@ -152,7 +148,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
try {
|
||||
std::string alphaPart = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
|
||||
if (alphaPart.find_first_of(' ') != std::string::npos) {
|
||||
if (alphaPart.contains(' ')) {
|
||||
// we have a comma, 2 values
|
||||
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
|
||||
PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
|
||||
@@ -170,13 +166,17 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (requestedWorkspace != "") {
|
||||
// process requested workspace
|
||||
if (requestedWorkspace.find_first_of(' ') != std::string::npos) {
|
||||
if (requestedWorkspace.contains(' ')) {
|
||||
// check for silent
|
||||
if (requestedWorkspace.find("silent") != std::string::npos) {
|
||||
if (requestedWorkspace.contains("silent")) {
|
||||
workspaceSilent = true;
|
||||
}
|
||||
|
||||
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
|
||||
|
||||
if (requestedWorkspace == "special") {
|
||||
workspaceSilent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!workspaceSilent) {
|
||||
@@ -199,8 +199,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto SIZEX = SIZEXSTR.find('%') == std::string::npos ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto SIZEY = SIZEYSTR.find('%') == std::string::npos ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto SIZEX = !SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto SIZEY = !SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
|
||||
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
|
||||
|
||||
@@ -215,8 +215,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto POSX = POSXSTR.find('%') == std::string::npos ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto POSY = POSYSTR.find('%') == std::string::npos ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
|
||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||
|
||||
@@ -238,8 +238,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10);
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus)
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||
} else
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
||||
|
||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||
|
||||
@@ -253,6 +256,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_configureX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_configure, &Events::listener_configureX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late");
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
|
||||
}
|
||||
|
||||
// do the animation thing
|
||||
@@ -284,6 +290,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
|
||||
|
||||
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
||||
@@ -306,6 +315,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.removeCallback();
|
||||
PWINDOW->hyprListener_configureX11.removeCallback();
|
||||
PWINDOW->hyprListener_setTitleWindow.removeCallback();
|
||||
PWINDOW->hyprListener_setGeometryX11U.removeCallback();
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
@@ -363,12 +373,15 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// Destroy Foreign Toplevel
|
||||
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
|
||||
PWINDOW->m_phForeignToplevel = nullptr;
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
}
|
||||
|
||||
void Events::listener_commitWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
@@ -487,6 +500,29 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden)
|
||||
return;
|
||||
|
||||
const auto POS = PWINDOW->m_vRealPosition.goalv();
|
||||
const auto SIZ = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
if (abs(floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y));
|
||||
|
||||
if (abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2)
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
|
||||
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec());
|
||||
g_pCompositor->moveWindowToTop(PWINDOW);
|
||||
PWINDOW->updateWindowDecos();
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
|
||||
const auto XWSURFACE = (wlr_xwayland_surface*)data;
|
||||
|
||||
|
@@ -128,10 +128,10 @@ public:
|
||||
case AVARTYPE_COLOR:
|
||||
return m_cValue != m_cGoal;
|
||||
default:
|
||||
return false;
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
return false; // unreachable
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
void warp() {
|
||||
@@ -149,7 +149,7 @@ public:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
std::unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -137,7 +137,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
|
||||
if (source.find_first_of("+") == 0) {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = relative + std::stof(source.substr(1));
|
||||
else
|
||||
result = relative + std::stoi(source.substr(1));
|
||||
@@ -147,7 +147,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
}
|
||||
} else if (source.find_first_of("-") == 0) {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = relative - std::stof(source.substr(1));
|
||||
else
|
||||
result = relative - std::stoi(source.substr(1));
|
||||
@@ -157,7 +157,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = stof(source);
|
||||
else
|
||||
result = stoi(source);
|
||||
|
56
src/helpers/Splashes.hpp
Normal file
56
src/helpers/Splashes.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
inline const std::vector<std::string> SPLASHES = {
|
||||
"Woo, animations!",
|
||||
"It's like Hypr, but better.",
|
||||
"Release 1.0 when?",
|
||||
"It's not awesome, it's Hyprland!",
|
||||
"\"I commit too often, people can't catch up lmao\" - Vaxry",
|
||||
"This text is random.",
|
||||
"\"There are reasons to not use rust.\" - Boga",
|
||||
"Read the wiki.",
|
||||
"\"Hello everyone this is YOUR daily dose of ‘read the wiki’\" - Vaxry",
|
||||
"h",
|
||||
"\"‘why no work’, bro I haven't hacked your pc to get live feeds yet\" - Vaxry",
|
||||
"Compile, wait for 20 minutes, notice a new commit, compile again.",
|
||||
"To rice, or not to rice, that is the question.",
|
||||
"Now available on Fedora!",
|
||||
// music reference / quote section
|
||||
"J'remue le ciel, le jour, la nuit.",
|
||||
"aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi!",
|
||||
"Wir sind schon sehr lang zusammen...",
|
||||
"I see a red door and I want it painted black.",
|
||||
"Take on me, take me on...",
|
||||
"You spin me right round baby right round",
|
||||
"Stayin' alive, stayin' alive",
|
||||
"Say no way, say no way ya, no way!",
|
||||
"Ground control to Major Tom...",
|
||||
"Alors on danse",
|
||||
"And all that I can see, is just a yellow lemon tree.",
|
||||
"Got a one-way ticket to the blues",
|
||||
"Is this the real life, is this just fantasy",
|
||||
"What's in your head, in your head?",
|
||||
"We're all living in America, America, America.",
|
||||
"I'm still standing, better than I ever did",
|
||||
"Here comes the sun, bringing you love and shining on everyone",
|
||||
"Two trailer park girls go round the outside",
|
||||
"With the lights out, it's less dangerous",
|
||||
"Here we go back, this is the moment, tonight is the night",
|
||||
"Now you're just somebody that I used to know...",
|
||||
"Black bird, black moon, black sky",
|
||||
"Some legends are told, some turn to dust or to gold",
|
||||
"Your brain gets smart, but your head gets dumb.",
|
||||
"Save your mercy for someone who needs it more",
|
||||
"You're gonna hear my voice when I shout it out loud",
|
||||
"Ding ding pch n daa, bam-ba-ba-re-bam baram bom bom baba-bam-bam-bommm",
|
||||
"Súbeme la radio que esta es mi canción",
|
||||
"I'm beggin', beggin' you",
|
||||
//
|
||||
"Join the discord server!",
|
||||
"Thanks ThatOneCalculator!",
|
||||
"The AUR packages always work, except for the times they don't.",
|
||||
"Funny animation compositor woo"
|
||||
};
|
@@ -25,10 +25,14 @@ struct SLayerSurface {
|
||||
|
||||
int monitorID = -1;
|
||||
|
||||
std::string szNamespace = "";
|
||||
|
||||
CAnimatedVariable alpha;
|
||||
bool fadingOut = false;
|
||||
bool readyToDelete = false;
|
||||
|
||||
bool forceBlur = false;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const SLayerSurface& rhs) {
|
||||
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
|
||||
@@ -60,6 +64,26 @@ struct SRenderData {
|
||||
|
||||
// for custom round values
|
||||
int rounding = -1; // -1 means not set
|
||||
|
||||
// for blurring
|
||||
bool blur = false;
|
||||
|
||||
// for windows that animate poorly
|
||||
bool squishOversized = false;
|
||||
};
|
||||
|
||||
struct SExtensionFindingData {
|
||||
Vector2D origin;
|
||||
Vector2D vec;
|
||||
wlr_surface** found;
|
||||
};
|
||||
|
||||
struct SStringRuleNames {
|
||||
std::string layout = "";
|
||||
std::string model = "";
|
||||
std::string variant = "";
|
||||
std::string options = "";
|
||||
std::string rules = "";
|
||||
};
|
||||
|
||||
struct SKeyboard {
|
||||
@@ -73,7 +97,7 @@ struct SKeyboard {
|
||||
|
||||
std::string name = "";
|
||||
|
||||
xkb_rule_names currentRules = {0};
|
||||
SStringRuleNames currentRules;
|
||||
int repeatRate = 0;
|
||||
int repeatDelay = 0;
|
||||
int numlockOn = -1;
|
||||
@@ -94,6 +118,8 @@ struct SMouse {
|
||||
|
||||
std::string name = "";
|
||||
|
||||
bool virt = false;
|
||||
|
||||
DYNLISTENER(commitConstraint);
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
@@ -221,3 +247,25 @@ struct STabletPad {
|
||||
return wlrTabletPadV2 == b.wlrTabletPadV2;
|
||||
}
|
||||
};
|
||||
|
||||
struct SIdleInhibitor {
|
||||
wlr_idle_inhibitor_v1* pWlrInhibitor = nullptr;
|
||||
CWindow* pWindow = nullptr;
|
||||
|
||||
DYNLISTENER(Destroy);
|
||||
|
||||
bool operator==(const SIdleInhibitor& b) {
|
||||
return pWlrInhibitor == b.pWlrInhibitor;
|
||||
}
|
||||
};
|
||||
|
||||
struct SSwipeGesture {
|
||||
CWorkspace* pWorkspaceBegin = nullptr;
|
||||
|
||||
double delta = 0;
|
||||
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
|
||||
SMonitor* pMonitor = nullptr;
|
||||
};
|
@@ -28,6 +28,7 @@ public:
|
||||
// for animations
|
||||
CAnimatedVariable m_vRenderOffset;
|
||||
CAnimatedVariable m_fAlpha;
|
||||
bool m_bForceRendering = false;
|
||||
|
||||
// "scratchpad"
|
||||
bool m_bIsSpecialWorkspace = false;
|
||||
|
@@ -14,7 +14,7 @@ void CHyprError::createQueued() {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
@@ -27,12 +27,12 @@ void CHyprError::createQueued() {
|
||||
const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n');
|
||||
|
||||
cairo_set_source_rgba(CAIRO, m_cQueued.r / 255.f, m_cQueued.g / 255.f, m_cQueued.b / 255.f, m_cQueued.a / 255.f);
|
||||
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecSize.x, 10 * LINECOUNT);
|
||||
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecPixelSize.x, 10 * LINECOUNT);
|
||||
|
||||
// outline
|
||||
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecSize.y); // left
|
||||
cairo_rectangle(CAIRO, PMONITOR->vecSize.x - 1, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // right
|
||||
cairo_rectangle(CAIRO, 0, PMONITOR->vecSize.y - 1, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // bottom
|
||||
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecPixelSize.y); // left
|
||||
cairo_rectangle(CAIRO, PMONITOR->vecPixelSize.x - 1, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // right
|
||||
cairo_rectangle(CAIRO, 0, PMONITOR->vecPixelSize.y - 1, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // bottom
|
||||
|
||||
cairo_fill(CAIRO);
|
||||
|
||||
@@ -70,7 +70,7 @@ void CHyprError::createQueued() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecSize.x, PMONITOR->vecSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
@@ -104,7 +104,7 @@ void CHyprError::draw() {
|
||||
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
|
||||
return; // wrong mon
|
||||
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
|
||||
g_pHyprOpenGL->renderTexture(m_tTexture, &windowBox, 255.f, 0);
|
||||
}
|
||||
|
@@ -74,6 +74,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/xwayland.h>
|
||||
#include <wlr/util/region.h>
|
||||
@@ -91,6 +92,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_xdg_foreign_registry.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
#include <wlr/types/wlr_pointer_gestures_v1.h>
|
||||
}
|
||||
|
||||
#undef class
|
||||
@@ -118,4 +120,5 @@ extern "C" {
|
||||
|
||||
#include "ext-workspace-unstable-v1-protocol.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
@@ -387,6 +387,8 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
||||
if (!PWORKSPACE)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
const auto TOPNODE = getMasterNodeOnWorkspace(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
@@ -397,9 +399,26 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore any recalc events if we have a fullscreen window.
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||
// Ignore any recalc events if we have a fullscreen window, but process if fullscreen mode 2
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
return;
|
||||
|
||||
// massive hack from the fullscreen func
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
SDwindleNodeData fakeNode;
|
||||
fakeNode.pWindow = PFULLWINDOW;
|
||||
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
|
||||
fakeNode.workspaceID = PWORKSPACE->m_iID;
|
||||
PFULLWINDOW->m_vPosition = fakeNode.position;
|
||||
PFULLWINDOW->m_vSize = fakeNode.size;
|
||||
|
||||
applyNodeDataToWindow(&fakeNode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
@@ -522,6 +541,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||
pWindow->m_bIsFullscreen = on;
|
||||
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)on)));
|
||||
|
||||
if (!pWindow->m_bIsFullscreen) {
|
||||
// if it got its fullscreen disabled, set back its node if it had one
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
@@ -571,6 +592,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||
// we need to fix XWayland windows by sending them to NARNIA
|
||||
// because otherwise they'd still be recieving mouse events
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
recalculateMonitor(PMONITOR->ID);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::recalculateWindow(CWindow* pWindow) {
|
||||
@@ -646,6 +669,8 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
PPARENT->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
|
@@ -45,7 +45,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
|
||||
// TODO: detect a popup in a more consistent way.
|
||||
if (!g_pCompositor->isPointOnAnyMonitor(middlePoint) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
// if it's not, fall back to the center placement
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||
} else {
|
||||
@@ -65,10 +65,12 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv());
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
if (pWindow->m_iX11Type != 2) {
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void IHyprLayout::onBeginDragWindow() {
|
||||
@@ -210,9 +212,23 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
} else {
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.vec();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
||||
|
||||
onWindowRemovedTiling(pWindow);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
|
||||
const auto POS = pWindow->m_vRealPosition.goalv();
|
||||
const auto SIZ = pWindow->m_vRealSize.goalv();
|
||||
|
||||
pWindow->m_vRealPosition.setValueAndWarp(POS + Vector2D(5, 5));
|
||||
pWindow->m_vRealSize.setValueAndWarp(SIZ - Vector2D(10, 10));
|
||||
|
||||
pWindow->m_vRealPosition = POS;
|
||||
pWindow->m_vRealSize = SIZ;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@ bool ignoreSudo = false;
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
if (!getenv("XDG_RUNTIME_DIR"))
|
||||
RIP("XDG_RUNTIME_DIR not set!");
|
||||
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
|
||||
|
||||
// parse some args
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
|
@@ -191,7 +191,7 @@ void CAnimationManager::tick() {
|
||||
|
||||
|
||||
// set size and pos if valid, but only if damage policy entire (dont if border for example)
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE)
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
// manually schedule a frame
|
||||
@@ -309,7 +309,7 @@ void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle != "") {
|
||||
// the window has config'd special anim
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.find(' ') != std::string::npos) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.contains(' ')) {
|
||||
// has a direction
|
||||
animationSlide(pWindow, pWindow->m_sAdditionalConfigData.animationStyle.substr(pWindow->m_sAdditionalConfigData.animationStyle.find(' ') + 1), close);
|
||||
} else {
|
||||
|
@@ -41,35 +41,48 @@ void CKeybindManager::addKeybind(SKeybind kb) {
|
||||
|
||||
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) {
|
||||
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
|
||||
if (it->modmask == mod && it->key == key) {
|
||||
if (isNumber(key) && std::stoi(key) > 9) {
|
||||
const auto KEYNUM = std::stoi(key);
|
||||
|
||||
if (it->modmask == mod && it->keycode == KEYNUM) {
|
||||
it = m_lKeybinds.erase(it);
|
||||
|
||||
if (it == m_lKeybinds.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (it->modmask == mod && it->key == key) {
|
||||
it = m_lKeybinds.erase(it);
|
||||
|
||||
if (it == m_lKeybinds.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CKeybindManager::stringToModMask(std::string mods) {
|
||||
uint32_t modMask = 0;
|
||||
if (mods.find("SHIFT") != std::string::npos)
|
||||
if (mods.contains("SHIFT"))
|
||||
modMask |= WLR_MODIFIER_SHIFT;
|
||||
if (mods.find("CAPS") != std::string::npos)
|
||||
if (mods.contains("CAPS"))
|
||||
modMask |= WLR_MODIFIER_CAPS;
|
||||
if (mods.find("CTRL") != std::string::npos || mods.find("CONTROL") != std::string::npos)
|
||||
if (mods.contains("CTRL") || mods.contains("CONTROL"))
|
||||
modMask |= WLR_MODIFIER_CTRL;
|
||||
if (mods.find("ALT") != std::string::npos)
|
||||
if (mods.contains("ALT"))
|
||||
modMask |= WLR_MODIFIER_ALT;
|
||||
if (mods.find("MOD2") != std::string::npos)
|
||||
if (mods.contains("MOD2"))
|
||||
modMask |= WLR_MODIFIER_MOD2;
|
||||
if (mods.find("MOD3") != std::string::npos)
|
||||
if (mods.contains("MOD3"))
|
||||
modMask |= WLR_MODIFIER_MOD3;
|
||||
if (mods.find("SUPER") != std::string::npos || mods.find("WIN") != std::string::npos || mods.find("LOGO") != std::string::npos || mods.find("MOD4") != std::string::npos)
|
||||
if (mods.contains("SUPER") || mods.contains("WIN") || mods.contains("LOGO") || mods.contains("MOD4"))
|
||||
modMask |= WLR_MODIFIER_LOGO;
|
||||
if (mods.find("MOD5") != std::string::npos)
|
||||
if (mods.contains("MOD5"))
|
||||
modMask |= WLR_MODIFIER_MOD5;
|
||||
|
||||
return modMask;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key) {
|
||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key, const int& keycode) {
|
||||
bool found = false;
|
||||
|
||||
if (handleInternalKeybinds(key))
|
||||
@@ -82,15 +95,24 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap)
|
||||
continue;
|
||||
|
||||
// oMg such performance hit!!11!
|
||||
// this little maneouver is gonna cost us 4µs
|
||||
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||
// small TODO: fix 0-9 keys and other modified ones with shift
|
||||
|
||||
if (key != KBKEY && key != KBKEYUPPER)
|
||||
continue;
|
||||
|
||||
if (k.keycode != -1) {
|
||||
if (keycode != k.keycode)
|
||||
continue;
|
||||
|
||||
} else {
|
||||
if (key == 0)
|
||||
continue; // this is a keycode check run
|
||||
|
||||
// oMg such performance hit!!11!
|
||||
// this little maneouver is gonna cost us 4µs
|
||||
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||
// small TODO: fix 0-9 keys and other modified ones with shift
|
||||
|
||||
if (key != KBKEY && key != KBKEYUPPER)
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto DISPATCHER = m_mDispatchers.find(k.handler);
|
||||
|
||||
@@ -99,7 +121,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
||||
Debug::log(ERR, "Inavlid handler in a keybind! (handler %s does not exist)", k.handler.c_str());
|
||||
} else {
|
||||
// call the dispatcher
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, KBKEYUPPER);
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, key);
|
||||
DISPATCHER->second(k.arg);
|
||||
}
|
||||
|
||||
@@ -231,9 +253,6 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(ACTIVEWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
}
|
||||
|
||||
ACTIVEWINDOW->m_vRealPosition.setValue(ACTIVEWINDOW->m_vRealPosition.vec() + Vector2D(5, 5));
|
||||
ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition.vec() - Vector2D(10, 10);
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW);
|
||||
}
|
||||
}
|
||||
@@ -253,7 +272,14 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
int workspaceToChangeTo = 0;
|
||||
std::string workspaceName = "";
|
||||
|
||||
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
|
||||
if (args.find("[internal]") == 0) {
|
||||
workspaceToChangeTo = std::stoi(args.substr(10));
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToChangeTo);
|
||||
if (PWORKSPACE)
|
||||
workspaceName = PWORKSPACE->m_szName;
|
||||
} else {
|
||||
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
|
||||
}
|
||||
|
||||
if (workspaceToChangeTo == INT_MAX) {
|
||||
Debug::log(ERR, "Error in changeworkspace, invalid value");
|
||||
@@ -277,8 +303,6 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
|
||||
|
||||
// change it
|
||||
PMONITOR->specialWorkspaceOpen = false;
|
||||
|
||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||
else
|
||||
@@ -451,7 +475,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
// undo the damage if we are moving to the special workspace
|
||||
if (WORKSPACEID == SPECIAL_WORKSPACE_ID) {
|
||||
changeworkspace(std::to_string(OLDWORKSPACE->m_iID));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACE->m_iID));
|
||||
OLDWORKSPACE->startAnim(true, true, true);
|
||||
toggleSpecialWorkspace("");
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false, true);
|
||||
@@ -503,8 +527,8 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
|
||||
PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
|
||||
|
||||
changeworkspace(std::to_string(OLDWORKSPACEIDONMONITOR));
|
||||
changeworkspace(std::to_string(OLDWORKSPACEIDRETURN));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDONMONITOR));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDRETURN));
|
||||
|
||||
// revert animations
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
|
||||
@@ -663,7 +687,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
||||
}
|
||||
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
|
||||
changeworkspace(std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
changeworkspace("[internal]" + std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
} else {
|
||||
Debug::log(ERR, "Error in focusMonitor: invalid arg 1");
|
||||
}
|
||||
@@ -683,7 +707,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == arg) {
|
||||
changeworkspace(std::to_string(m->activeWorkspace));
|
||||
changeworkspace("[internal]" + std::to_string(m->activeWorkspace));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -816,7 +840,7 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||
@@ -891,7 +915,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||
}
|
||||
} else {
|
||||
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
|
||||
if (!PSPECIALWORKSPACE) {
|
||||
// ??? happens sometimes...?
|
||||
PSPECIALWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(g_pCompositor->m_pLastMonitor->ID, "special", true)).get();
|
||||
}
|
||||
|
||||
g_pCompositor->m_pLastMonitor->specialWorkspaceOpen = true;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
||||
|
||||
@@ -918,7 +947,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::resizeActive(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string x = args.substr(0, args.find_first_of(' '));
|
||||
@@ -967,7 +996,7 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveActive(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string x = args.substr(0, args.find_first_of(' '));
|
||||
@@ -1015,11 +1044,14 @@ void CKeybindManager::moveActive(std::string args) {
|
||||
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(Vector2D(X, Y));
|
||||
}
|
||||
|
||||
void CKeybindManager::circleNext(std::string) {
|
||||
void CKeybindManager::circleNext(std::string arg) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
return;
|
||||
|
||||
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
g_pCompositor->focusWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
else
|
||||
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
|
||||
const auto MIDPOINT = g_pCompositor->m_pLastWindow->m_vRealPosition.goalv() + g_pCompositor->m_pLastWindow->m_vRealSize.goalv() / 2.f;
|
||||
|
||||
@@ -1051,7 +1083,7 @@ void CKeybindManager::focusWindow(std::string regexp) {
|
||||
|
||||
Debug::log(LOG, "Focusing to window name: %s", w->m_szTitle.c_str());
|
||||
|
||||
changeworkspace(std::to_string(w->m_iWorkspaceID));
|
||||
changeworkspace("[internal]" + std::to_string(w->m_iWorkspaceID));
|
||||
|
||||
g_pCompositor->focusWindow(w.get());
|
||||
|
||||
|
@@ -7,7 +7,8 @@
|
||||
#include <functional>
|
||||
|
||||
struct SKeybind {
|
||||
std::string key = 0;
|
||||
std::string key = "";
|
||||
int keycode = -1;
|
||||
uint32_t modmask = 0;
|
||||
std::string handler = "";
|
||||
std::string arg = "";
|
||||
@@ -19,7 +20,7 @@ class CKeybindManager {
|
||||
public:
|
||||
CKeybindManager();
|
||||
|
||||
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&);
|
||||
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&, const int&);
|
||||
void addKeybind(SKeybind);
|
||||
void removeKeybind(uint32_t, const std::string&);
|
||||
uint32_t stringToModMask(std::string);
|
||||
|
@@ -36,7 +36,9 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(pSurface)->toplevel, activate);
|
||||
else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||
wlr_xwayland_surface_activate(wlr_xwayland_surface_from_wlr_surface(pSurface), activate);
|
||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
|
||||
|
||||
if (activate)
|
||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -153,7 +155,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
||||
if (pWindow->m_uSurface.xwayland->role) {
|
||||
try {
|
||||
std::string winrole = std::string(pWindow->m_uSurface.xwayland->role);
|
||||
if (winrole.find("pop-up") != std::string::npos || winrole.find("task_dialog") != std::string::npos) {
|
||||
if (winrole.contains("pop-up") || winrole.contains("task_dialog")) {
|
||||
return true;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
@@ -221,6 +223,4 @@ void CHyprXWaylandManager::setWindowFullscreen(CWindow* pWindow, bool fullscreen
|
||||
|
||||
if (pWindow->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_fullscreen(pWindow->m_phForeignToplevel, fullscreen);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)fullscreen)));
|
||||
}
|
54
src/managers/input/IdleInhibitor.cpp
Normal file
54
src/managers/input/IdleInhibitor.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void Events::listener_newIdleInhibitor(wl_listener* listener, void* data) {
|
||||
const auto WLRIDLEINHIBITOR = (wlr_idle_inhibitor_v1*)data;
|
||||
|
||||
if (!WLRIDLEINHIBITOR)
|
||||
return;
|
||||
|
||||
g_pInputManager->newIdleInhibitor(WLRIDLEINHIBITOR);
|
||||
}
|
||||
|
||||
void CInputManager::newIdleInhibitor(wlr_idle_inhibitor_v1* pInhibitor) {
|
||||
const auto PINHIBIT = &m_lIdleInhibitors.emplace_back();
|
||||
|
||||
Debug::log(LOG, "New idle inhibitor registered");
|
||||
|
||||
PINHIBIT->pWlrInhibitor = pInhibitor;
|
||||
|
||||
PINHIBIT->hyprListener_Destroy.initCallback(&pInhibitor->events.destroy, [](void* owner, void* data){
|
||||
|
||||
const auto PINH = (SIdleInhibitor*)owner;
|
||||
|
||||
g_pInputManager->m_lIdleInhibitors.remove(*PINH);
|
||||
|
||||
Debug::log(LOG, "Destroyed an idleinhibitor");
|
||||
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
}, PINHIBIT, "IdleInhibitor");
|
||||
|
||||
PINHIBIT->pWindow = g_pCompositor->getWindowFromSurface(pInhibitor->surface);
|
||||
|
||||
if (PINHIBIT->pWindow)
|
||||
Debug::log(LOG, "IdleInhibitor got window %x (%s)", PINHIBIT->pWindow, PINHIBIT->pWindow->m_szTitle.c_str());
|
||||
|
||||
recheckIdleInhibitorStatus();
|
||||
}
|
||||
|
||||
void CInputManager::recheckIdleInhibitorStatus() {
|
||||
|
||||
for (auto& ii : m_lIdleInhibitors) {
|
||||
if (!ii.pWindow) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
} else if (g_pHyprRenderer->shouldRenderWindow(ii.pWindow)) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, true);
|
||||
return;
|
||||
}
|
@@ -28,6 +28,8 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
|
||||
|
||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess)
|
||||
return;
|
||||
|
||||
@@ -36,6 +38,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pCompositor->m_sSeat.mouse->virt)
|
||||
return; // don't refocus on virt
|
||||
|
||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
@@ -139,6 +144,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
surfacePos = Vector2D(-1337, -1337);
|
||||
} else {
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
@@ -154,9 +160,18 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
// then windows
|
||||
if (!foundSurface) {
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED)
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
else
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (pFoundWindow && pFoundWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
}
|
||||
} else {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
}
|
||||
} else
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (pFoundWindow) {
|
||||
@@ -184,6 +199,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (refocus) { // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -201,7 +222,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
|
||||
if (pFoundWindow) {
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
|
||||
// enter if change floating style
|
||||
@@ -367,8 +387,8 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
Debug::log(ERR, "Keyboard had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
if (m_pActiveKeyboard)
|
||||
@@ -377,7 +397,7 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->keyboard);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
|
||||
Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard);
|
||||
}
|
||||
@@ -392,7 +412,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
|
||||
ASSERT(pKeyboard);
|
||||
|
||||
if (!pKeyboard->keyboard->keyboard)
|
||||
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
|
||||
return;
|
||||
|
||||
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
|
||||
@@ -407,7 +427,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == std::string(pKeyboard->currentRules.rules) && MODEL == std::string(pKeyboard->currentRules.model) && LAYOUT == std::string(pKeyboard->currentRules.layout) && VARIANT == std::string(pKeyboard->currentRules.variant) && OPTIONS == std::string(pKeyboard->currentRules.options)) {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
|
||||
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
|
||||
return;
|
||||
}
|
||||
@@ -416,7 +436,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
// we can ignore those and just apply
|
||||
}
|
||||
|
||||
wlr_keyboard_set_repeat_info(pKeyboard->keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
wlr_keyboard_set_repeat_info(wlr_keyboard_from_input_device(pKeyboard->keyboard), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
|
||||
pKeyboard->repeatDelay = REPEATDELAY;
|
||||
pKeyboard->repeatRate = REPEATRATE;
|
||||
@@ -429,7 +449,11 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
.variant = VARIANT.c_str(),
|
||||
.options = OPTIONS.c_str()};
|
||||
|
||||
pKeyboard->currentRules = rules;
|
||||
pKeyboard->currentRules.rules = RULES;
|
||||
pKeyboard->currentRules.model = MODEL;
|
||||
pKeyboard->currentRules.variant = VARIANT;
|
||||
pKeyboard->currentRules.options = OPTIONS;
|
||||
pKeyboard->currentRules.layout = LAYOUT;
|
||||
|
||||
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
@@ -446,12 +470,16 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
Debug::log(ERR, "Keyboard layout %s with variant %s (rules: %s, model: %s, options: %s) couldn't have been loaded.", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
|
||||
memset(&rules, 0, sizeof(rules));
|
||||
|
||||
pKeyboard->currentRules = rules;
|
||||
pKeyboard->currentRules.rules = "";
|
||||
pKeyboard->currentRules.model = "";
|
||||
pKeyboard->currentRules.variant = "";
|
||||
pKeyboard->currentRules.options = "";
|
||||
pKeyboard->currentRules.layout = "";
|
||||
|
||||
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
wlr_keyboard_set_keymap(pKeyboard->keyboard->keyboard, KEYMAP);
|
||||
wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
|
||||
|
||||
wlr_keyboard_modifiers wlrMods = {0};
|
||||
|
||||
@@ -464,7 +492,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
}
|
||||
|
||||
if (wlrMods.locked != 0) {
|
||||
wlr_keyboard_notify_modifiers(pKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
|
||||
wlr_keyboard_notify_modifiers(wlr_keyboard_from_input_device(pKeyboard->keyboard), 0, 0, wlrMods.locked, 0);
|
||||
}
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
@@ -473,11 +501,12 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name);
|
||||
}
|
||||
|
||||
void CInputManager::newMouse(wlr_input_device* mouse) {
|
||||
void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
m_lMice.emplace_back();
|
||||
const auto PMOUSE = &m_lMice.back();
|
||||
|
||||
PMOUSE->mouse = mouse;
|
||||
PMOUSE->virt = virt;
|
||||
try {
|
||||
PMOUSE->name = std::string(mouse->name);
|
||||
} catch(std::exception& e) {
|
||||
@@ -501,6 +530,11 @@ void CInputManager::newMouse(wlr_input_device* mouse) {
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
|
||||
else
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
|
||||
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
@@ -568,29 +602,31 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
||||
const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
|
||||
const xkb_keysym_t* keysyms;
|
||||
int syms = xkb_state_key_get_syms(pKeyboard->keyboard->keyboard->xkb_state, KEYCODE, &keysyms);
|
||||
int syms = xkb_state_key_get_syms(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE, &keysyms);
|
||||
|
||||
const auto MODS = wlr_keyboard_get_modifiers(pKeyboard->keyboard->keyboard);
|
||||
const auto MODS = accumulateModsFromAllKBs();
|
||||
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
|
||||
bool found = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
for (int i = 0; i < syms; ++i)
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i]) || found;
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE) || found;
|
||||
} else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
// hee hee
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &pKeyboard->keyboard->keyboard->modifiers);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
@@ -708,4 +744,15 @@ void CInputManager::updateCapabilities(wlr_input_device* pDev) {
|
||||
}
|
||||
|
||||
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, m_uiCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CInputManager::accumulateModsFromAllKBs() {
|
||||
|
||||
uint32_t finalMask = 0;
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||
}
|
||||
|
||||
return finalMask;
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ public:
|
||||
void onKeyboardMod(void*, SKeyboard*);
|
||||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void destroyKeyboard(SKeyboard*);
|
||||
void destroyMouse(wlr_input_device*);
|
||||
|
||||
@@ -56,9 +56,20 @@ public:
|
||||
std::list<STabletTool> m_lTabletTools;
|
||||
std::list<STabletPad> m_lTabletPads;
|
||||
|
||||
// idle inhibitors
|
||||
std::list<SIdleInhibitor> m_lIdleInhibitors;
|
||||
|
||||
void newTabletTool(wlr_input_device*);
|
||||
void newTabletPad(wlr_input_device*);
|
||||
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||
void newIdleInhibitor(wlr_idle_inhibitor_v1*);
|
||||
void recheckIdleInhibitorStatus();
|
||||
|
||||
void onSwipeBegin(wlr_pointer_swipe_begin_event*);
|
||||
void onSwipeEnd(wlr_pointer_swipe_end_event*);
|
||||
void onSwipeUpdate(wlr_pointer_swipe_update_event*);
|
||||
|
||||
SSwipeGesture m_sActiveSwipe;
|
||||
|
||||
SKeyboard* m_pActiveKeyboard = nullptr;
|
||||
|
||||
@@ -80,6 +91,9 @@ private:
|
||||
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||
|
||||
void applyConfigToKeyboard(SKeyboard*);
|
||||
|
||||
// for shared mods
|
||||
uint32_t accumulateModsFromAllKBs();
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
152
src/managers/input/Swipe.cpp
Normal file
152
src/managers/input/Swipe.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
|
||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||
|
||||
if (e->fingers < 3 || *PSWIPE == 0)
|
||||
return;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
Debug::log(LOG, "Starting a swipe from %s", PWORKSPACE->m_szName.c_str());
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin = PWORKSPACE;
|
||||
m_sActiveSwipe.delta = 0;
|
||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
||||
m_sActiveSwipe.avgSpeed = 0;
|
||||
m_sActiveSwipe.speedPoints = 0;
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||
return; // no valid swipe
|
||||
|
||||
static auto *const PSWIPEPERC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_cancel_ratio")->floatValue;
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEFORC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_min_speed_to_force")->intValue;
|
||||
|
||||
// commit
|
||||
std::string wsname = "";
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
||||
|
||||
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
|
||||
// revert
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
// to left
|
||||
PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
} else {
|
||||
// to right
|
||||
PWORKSPACER->m_vRenderOffset = Vector2D({m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
}
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
|
||||
} else if (m_sActiveSwipe.delta < 0) {
|
||||
// switch to left
|
||||
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
|
||||
|
||||
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDLeft));
|
||||
|
||||
PWORKSPACEL->m_vRenderOffset.setValue(RENDEROFFSET);
|
||||
PWORKSPACEL->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the left");
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
||||
|
||||
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDRight));
|
||||
|
||||
PWORKSPACER->m_vRenderOffset.setValue(RENDEROFFSET);
|
||||
PWORKSPACER->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the right");
|
||||
}
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE);
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false;
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin = nullptr;
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||
return;
|
||||
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEINVR = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert")->intValue;
|
||||
|
||||
m_sActiveSwipe.delta += *PSWIPEINVR ? -e->dx : e->dx;
|
||||
|
||||
m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1);
|
||||
m_sActiveSwipe.speedPoints++;
|
||||
|
||||
std::string wsname = "";
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)
|
||||
return;
|
||||
|
||||
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST);
|
||||
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
|
||||
} else {
|
||||
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
|
||||
}
|
@@ -10,7 +10,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
Debug::log(ERR, "Tablet had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWTABLET->wlrTablet = pDevice->tablet;
|
||||
PNEWTABLET->wlrTablet = wlr_tablet_from_input_device(pDevice);
|
||||
PNEWTABLET->wlrDevice = pDevice;
|
||||
PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
PNEWTABLET->wlrTablet->data = PNEWTABLET;
|
||||
@@ -27,7 +27,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
Debug::log(LOG, "Removed a tablet");
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Axis.initCallback(&pDevice->tablet->events.axis, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Axis.initCallback(&wlr_tablet_from_input_device(pDevice)->events.axis, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_tool_axis_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
@@ -80,7 +80,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Tip.initCallback(&pDevice->tablet->events.tip, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Tip.initCallback(&wlr_tablet_from_input_device(pDevice)->events.tip, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_tip_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
|
||||
@@ -98,7 +98,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Button.initCallback(&pDevice->tablet->events.button, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Button.initCallback(&wlr_tablet_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_button_event*)data;
|
||||
|
||||
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||
@@ -107,7 +107,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Proximity.initCallback(&pDevice->tablet->events.proximity, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Proximity.initCallback(&wlr_tablet_from_input_device(pDevice)->events.proximity, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_proximity_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
|
||||
@@ -165,7 +165,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
|
||||
PNEWPAD->hyprListener_Button.initCallback(&pDevice->tablet_pad->events.button, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Button.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_button_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@@ -175,7 +175,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Strip.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Strip.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_strip_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@@ -184,7 +184,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Ring.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Ring.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_ring_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@@ -193,7 +193,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Attach.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Attach.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto TABLET = (wlr_tablet_tool*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
|
@@ -717,7 +717,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders);
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
@@ -915,9 +915,28 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
|
||||
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
|
||||
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
||||
cairo_set_font_size(CAIRO, FONTSIZE);
|
||||
|
||||
cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
|
||||
|
||||
cairo_text_extents_t textExtents;
|
||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
|
||||
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
|
||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
|
||||
|
||||
static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
|
||||
|
||||
// release the last tex if exists
|
||||
const auto PTEX = &m_mMonitorBGTextures[pMonitor];
|
||||
PTEX->destroyTexture();
|
||||
@@ -926,6 +945,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
|
||||
Debug::log(LOG, "Allocated texture for BGTex");
|
||||
|
||||
// TODO: use relative paths to the installation
|
||||
// or configure the paths at build time
|
||||
|
||||
// check if wallpapers exist
|
||||
if (!std::filesystem::exists("/usr/share/hyprland/wall_8K.png"))
|
||||
return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
|
||||
@@ -949,6 +971,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
if (!*PNOSPLASH)
|
||||
renderSplash(CAIRO, CAIROSURFACE);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID);
|
||||
@@ -969,9 +994,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
void CHyprOpenGLImpl::clearWithTex() {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
|
||||
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
|
||||
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
if (!*PRENDERTEX) {
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) {
|
||||
|
@@ -6,6 +6,8 @@
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
#include "Shaders.hpp"
|
||||
#include "Shader.hpp"
|
||||
#include "Texture.hpp"
|
||||
@@ -121,6 +123,8 @@ private:
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false);
|
||||
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
@@ -16,6 +16,15 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
|
||||
else // here we clamp to 2, these might be some tiny specks
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
|
||||
|
||||
// squish all oversized
|
||||
if (RDATA->squishOversized) {
|
||||
if (x + windowBox.width > RDATA->w)
|
||||
windowBox.width = RDATA->w - x;
|
||||
if (y + windowBox.height > RDATA->h)
|
||||
windowBox.height = RDATA->h - y;
|
||||
}
|
||||
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
@@ -23,7 +32,10 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
if (RDATA->blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
|
||||
if (RDATA->decorate) {
|
||||
auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
|
||||
@@ -60,8 +72,8 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||
return true;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
return true;
|
||||
|
||||
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
@@ -99,7 +111,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
continue;
|
||||
|
||||
// found it!
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
|
||||
|
||||
pWorkspaceWindow = w.get();
|
||||
}
|
||||
@@ -109,7 +121,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and then special windows
|
||||
@@ -124,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and the overlay layers
|
||||
@@ -146,7 +158,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
|
||||
if (pWindow->m_bHidden)
|
||||
return;
|
||||
|
||||
@@ -166,9 +178,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
|
||||
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
||||
renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
|
||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||
renderdata.blur = true; // if it shouldn't, it will be ignored later
|
||||
renderdata.squishOversized = pWindow->m_vRealPosition.isBeingAnimated();
|
||||
|
||||
// apply window special data
|
||||
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
|
||||
@@ -179,35 +193,40 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first, if not fullscreen full
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
if (!pWindow->m_bIsX11) {
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
} else {
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
renderdata.dontRound = false; // restore dontround
|
||||
renderdata.pMonitor = pMonitor;
|
||||
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
|
||||
if (!pWindow->m_bIsX11) {
|
||||
renderdata.dontRound = false; // restore dontround
|
||||
renderdata.pMonitor = pMonitor;
|
||||
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
|
||||
@@ -221,6 +240,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
|
||||
renderdata.fadeAlpha = pLayer->alpha.fl();
|
||||
renderdata.blur = pLayer->forceBlur;
|
||||
renderdata.surface = pLayer->layerSurface->surface;
|
||||
renderdata.decorate = false;
|
||||
renderdata.w = pLayer->layerSurface->surface->current.width;
|
||||
renderdata.h = pLayer->layerSurface->surface->current.height;
|
||||
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
@@ -247,7 +271,25 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Non-floating
|
||||
// Non-floating main
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFloating)
|
||||
continue; // floating are in the second pass
|
||||
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
continue; // special are in the third pass
|
||||
|
||||
if (!shouldRenderWindow(w.get(), PMONITOR))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_MAIN);
|
||||
}
|
||||
|
||||
// Non-floating popup
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
@@ -262,7 +304,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_POPUP);
|
||||
}
|
||||
|
||||
// floating on top
|
||||
@@ -280,7 +322,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and then special
|
||||
@@ -295,7 +337,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// Render surfaces above windows for monitor
|
||||
@@ -808,4 +850,4 @@ void CHyprRenderer::ensureCursorRenderingMode() {
|
||||
|
||||
bool CHyprRenderer::shouldRenderCursor() {
|
||||
return m_bHasARenderedCursor;
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,12 @@ enum DAMAGETRACKINGMODES {
|
||||
DAMAGE_TRACKING_FULL
|
||||
};
|
||||
|
||||
enum eRenderPassMode {
|
||||
RENDER_PASS_ALL = 0,
|
||||
RENDER_PASS_MAIN,
|
||||
RENDER_PASS_POPUP
|
||||
};
|
||||
|
||||
class CHyprRenderer {
|
||||
public:
|
||||
|
||||
@@ -41,7 +47,7 @@ public:
|
||||
private:
|
||||
void arrangeLayerArray(SMonitor*, const std::list<SLayerSurface*>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
|
||||
void renderWindow(CWindow*, SMonitor*, timespec*, bool);
|
||||
void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode);
|
||||
void renderLayer(SLayerSurface*, SMonitor*, timespec*);
|
||||
void renderDragIcon(SMonitor*, timespec*);
|
||||
|
||||
|
Submodule subprojects/wlroots updated: 5c4384a133...5dc1d4671d
Reference in New Issue
Block a user