From 0b902b95e468ca7f4a625b13aa325e3508e3f7f4 Mon Sep 17 00:00:00 2001 From: Youwen Wu Date: Sat, 24 Aug 2024 11:28:02 -0700 Subject: [PATCH] fix: use better patch on asahi for hyprland --- ...x-dmabuf-allow-on-split-node-systems.patch | 15 + hosts/callisto/asahi-fix.patch | 5062 ----------------- hosts/callisto/configuration.nix | 2 +- 3 files changed, 16 insertions(+), 5063 deletions(-) create mode 100644 hosts/callisto/0001-linux-dmabuf-allow-on-split-node-systems.patch delete mode 100644 hosts/callisto/asahi-fix.patch diff --git a/hosts/callisto/0001-linux-dmabuf-allow-on-split-node-systems.patch b/hosts/callisto/0001-linux-dmabuf-allow-on-split-node-systems.patch new file mode 100644 index 0000000..8079104 --- /dev/null +++ b/hosts/callisto/0001-linux-dmabuf-allow-on-split-node-systems.patch @@ -0,0 +1,15 @@ +diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp +index 0fbf832e..c6077114 100644 +--- a/src/protocols/LinuxDMABUF.cpp ++++ b/src/protocols/LinuxDMABUF.cpp +@@ -492,9 +492,8 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const + return; + } + } else { +- protoLog(ERR, "DRM device {} has no render node, disabling linux dmabuf", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); ++ protoLog(ERR, "DRM device {} has no render node, disabling linux dmabuf checks", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); + drmFreeDevice(&device); +- removeGlobal(); + } + }); + } diff --git a/hosts/callisto/asahi-fix.patch b/hosts/callisto/asahi-fix.patch deleted file mode 100644 index 03c87c8..0000000 --- a/hosts/callisto/asahi-fix.patch +++ /dev/null @@ -1,5062 +0,0 @@ -diff --git a/.gitignore b/.gitignore -index 78f794fc..2e158a4e 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -37,3 +37,5 @@ gmon.out - PKGBUILD - - src/version.h -+hyprpm/Makefile -+hyprctl/Makefile -diff --git a/CMakeLists.txt b/CMakeLists.txt -index fc8eafd5..f26a5c3c 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -62,7 +62,7 @@ else() - endif() - - include_directories(. "src/" "subprojects/udis86/" "protocols/") --set(CMAKE_CXX_STANDARD 23) -+set(CMAKE_CXX_STANDARD 26) - add_compile_options( - -Wall - -Wextra -@@ -117,6 +117,7 @@ pkg_check_modules( - libliftoff - libudev - gbm -+ gio-2.0 - hyprlang>=0.3.2 - hyprcursor>=0.1.7 - hyprutils>=0.2.1) -@@ -329,7 +330,7 @@ install( - CODE "execute_process( \ - COMMAND ${CMAKE_COMMAND} -E create_symlink \ - ${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \ -- ${CMAKE_INSTALL_FULL_BINDIR}/hyprland -+ \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \ - )") - - # session file -diff --git a/README.md b/README.md -index fc2bd206..f271c29c 100644 ---- a/README.md -+++ b/README.md -@@ -1,6 +1,6 @@ -
- --banner -+banner - -
- -@@ -125,7 +125,6 @@ easy IPC, much more QoL stuff than other compositors and more... - - - --[Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg - [Preview A]: https://i.ibb.co/C1yTb0r/falf.png - [Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png - [Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png -diff --git a/flake.lock b/flake.lock -index 5c384d4d..c70d31d1 100644 ---- a/flake.lock -+++ b/flake.lock -@@ -16,11 +16,11 @@ - ] - }, - "locked": { -- "lastModified": 1722347739, -- "narHash": "sha256-rAoh+K6KG+b1DwSWtqRVocdojnH6nGk6q07mNltoUSM=", -+ "lastModified": 1723920171, -+ "narHash": "sha256-dVCMrAe+D/5S91erhwQj2DSzHOVzAanWqoy+vPWB9DY=", - "owner": "hyprwm", - "repo": "aquamarine", -- "rev": "7c3565f9bedc7cb601cc0baa14792247e4dc1d5a", -+ "rev": "71d49670fe246cdaff4860b0effba0ab9f163b72", - "type": "github" - }, - "original": { -@@ -42,11 +42,11 @@ - ] - }, - "locked": { -- "lastModified": 1721330371, -- "narHash": "sha256-aYlHTWylczLt6ERJyg6E66Y/XSCbVL7leVcRuJmVbpI=", -+ "lastModified": 1722623071, -+ "narHash": "sha256-sLADpVgebpCBFXkA1FlCXtvEPu1tdEsTfqK1hfeHySE=", - "owner": "hyprwm", - "repo": "hyprcursor", -- "rev": "4493a972b48f9c3014befbbf381ed5fff91a65dc", -+ "rev": "912d56025f03d41b1ad29510c423757b4379eb1c", - "type": "github" - }, - "original": { -@@ -116,11 +116,11 @@ - ] - }, - "locked": { -- "lastModified": 1722098849, -- "narHash": "sha256-D3wIZlBNh7LuZ0NaoCpY/Pvu+xHxIVtSN+KkWZYvvVs=", -+ "lastModified": 1722869141, -+ "narHash": "sha256-0KU4qhyMp441qfwbirNg3+wbm489KnEjXOz2I/RbeFs=", - "owner": "hyprwm", - "repo": "hyprutils", -- "rev": "5dcbbc1e3de40b2cecfd2007434d86e924468f1f", -+ "rev": "0252fd13e78e60fb0da512a212e56007515a49f7", - "type": "github" - }, - "original": { -@@ -154,11 +154,11 @@ - }, - "nixpkgs": { - "locked": { -- "lastModified": 1722185531, -- "narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=", -+ "lastModified": 1723637854, -+ "narHash": "sha256-med8+5DSWa2UnOqtdICndjDAEjxr5D7zaIiK4pn0Q7c=", - "owner": "NixOS", - "repo": "nixpkgs", -- "rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d", -+ "rev": "c3aa7b8938b17aebd2deecf7be0636000d62a2b9", - "type": "github" - }, - "original": { -diff --git a/flake.nix b/flake.nix -index 9c20b3f5..9e1e3ab4 100644 ---- a/flake.nix -+++ b/flake.nix -@@ -95,7 +95,7 @@ - devShells = eachSystem (system: { - default = - pkgsFor.${system}.mkShell.override { -- stdenv = pkgsFor.${system}.gcc13Stdenv; -+ stdenv = pkgsFor.${system}.gcc14Stdenv; - } { - name = "hyprland-shell"; - nativeBuildInputs = with pkgsFor.${system}; [ -diff --git a/hyprctl/Makefile b/hyprctl/Makefile -deleted file mode 100644 -index 9798320c..00000000 ---- a/hyprctl/Makefile -+++ /dev/null -@@ -1,4 +0,0 @@ --all: -- $(CXX) $(CXXFLAGS) -std=c++2b ./main.cpp -o ./hyprctl --clean: -- rm ./hyprctl -diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp -index 336d479e..5d5113b8 100644 ---- a/hyprctl/main.cpp -+++ b/hyprctl/main.cpp -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - using namespace Hyprutils::String; - - #include "Strings.hpp" -@@ -113,7 +114,7 @@ int rollingRead(const int socket) { - - constexpr size_t BUFFER_SIZE = 8192; - std::array buffer = {0}; -- int sizeWritten = 0; -+ long sizeWritten = 0; - std::cout << "[hyprctl] reading from socket following up log:" << std::endl; - while (!sigintReceived) { - sizeWritten = read(socket, buffer.data(), BUFFER_SIZE); -diff --git a/meson.build b/meson.build -index 886f4f9c..6a9b7ac5 100644 ---- a/meson.build -+++ b/meson.build -@@ -6,7 +6,7 @@ project('Hyprland', 'cpp', 'c', - 'optimization=3', - 'buildtype=release', - 'debug=false', -- 'cpp_std=c++23', -+ 'cpp_std=c++26', - ]) - - datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"' -@@ -34,6 +34,8 @@ xcb_render_dep = dependency('xcb-render', required: get_option('xwayland')) - xcb_res_dep = dependency('xcb-res', required: get_option('xwayland')) - xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland')) - -+gio_dep = dependency('gio-2.0', required:true) -+ - cmake = import('cmake') - udis = cmake.subproject('udis86') - udis86 = udis.dependency('libudis86') -diff --git a/nix/default.nix b/nix/default.nix -index e4e12f43..9bae9d83 100644 ---- a/nix/default.nix -+++ b/nix/default.nix -@@ -71,6 +71,11 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov - src = lib.cleanSource ../.; - }; - -+ patches = [ -+ # forces GCC to use -std=c++26 -+ ./stdcxx.patch -+ ]; -+ - postPatch = '' - # Fix hardcoded paths to /usr installation - sed -i "s#/usr#$out#" src/render/OpenGL.cpp -diff --git a/nix/overlays.nix b/nix/overlays.nix -index d8979b45..36206f46 100644 ---- a/nix/overlays.nix -+++ b/nix/overlays.nix -@@ -31,7 +31,7 @@ in { - date = mkDate (self.lastModifiedDate or "19700101"); - in { - hyprland = final.callPackage ./default.nix { -- stdenv = final.gcc13Stdenv; -+ stdenv = final.gcc14Stdenv; - version = "${version}+date=${date}_${self.shortRev or "dirty"}"; - commit = self.rev or ""; - inherit date; -diff --git a/nix/stdcxx.patch b/nix/stdcxx.patch -new file mode 100644 -index 00000000..032e494d ---- /dev/null -+++ b/nix/stdcxx.patch -@@ -0,0 +1,12 @@ -+diff --git a/CMakeLists.txt b/CMakeLists.txt -+index cfbd431f..73e8e0c2 100644 -+--- a/CMakeLists.txt -++++ b/CMakeLists.txt -+@@ -64,6 +64,7 @@ endif() -+ include_directories(. "src/" "subprojects/udis86/" "protocols/") -+ set(CMAKE_CXX_STANDARD 26) -+ add_compile_options( -++ -std=c++26 -+ -Wall -+ -Wextra -+ -Wno-unused-parameter -diff --git a/src/Compositor.cpp b/src/Compositor.cpp -index 49408597..9d247a56 100644 ---- a/src/Compositor.cpp -+++ b/src/Compositor.cpp -@@ -305,6 +305,10 @@ void CCompositor::initServer(std::string socketName, int socketFd) { - - setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket.c_str(), 1); - setenv("XDG_SESSION_TYPE", "wayland", 1); -+ if (!getenv("XDG_CURRENT_DESKTOP")) { -+ setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1); -+ m_bDesktopEnvSet = true; -+ } - - initManagers(STAGE_BASICINIT); - -@@ -393,6 +397,7 @@ void CCompositor::initAllSignals() { - } - - g_pConfigManager->m_bWantsMonitorReload = true; -+ g_pCursorManager->syncGsettings(); - } else { - Debug::log(LOG, "Session got deactivated!"); - -@@ -421,9 +426,10 @@ void CCompositor::cleanEnvironment() { - // in main - unsetenv("HYPRLAND_CMD"); - unsetenv("XDG_BACKEND"); -- unsetenv("XDG_CURRENT_DESKTOP"); -+ if (m_bDesktopEnvSet) -+ unsetenv("XDG_CURRENT_DESKTOP"); - -- if (m_pAqBackend->hasSession()) { -+ if (m_pAqBackend->hasSession() && !envEnabled("HYPRLAND_NO_SD_VARS")) { - const auto CMD = - #ifdef USES_SYSTEMD - "systemctl --user unset-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash " -@@ -552,6 +558,10 @@ void CCompositor::initManagers(eManagersInitStage stage) { - - g_pConfigManager->init(); - g_pWatchdog = std::make_unique(); // requires config -+ // wait for watchdog to initialize to not hit data races in reading config values. -+ while (!g_pWatchdog->m_bWatchdogInitialized) { -+ std::this_thread::yield(); -+ } - - Debug::log(LOG, "Creating the PointerManager!"); - g_pPointerManager = std::make_unique(); -@@ -649,7 +659,11 @@ void CCompositor::prepareFallbackOutput() { - void CCompositor::startCompositor() { - signal(SIGPIPE, SIG_IGN); - -- if (m_pAqBackend->hasSession() /* Session-less Hyprland usually means a nest, don't update the env in that case */) { -+ if ( -+ /* Session-less Hyprland usually means a nest, don't update the env in that case */ -+ m_pAqBackend->hasSession() && -+ /* Activation environment management is not disabled */ -+ !envEnabled("HYPRLAND_NO_SD_VARS")) { - const auto CMD = - #ifdef USES_SYSTEMD - "systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash " -@@ -683,9 +697,9 @@ void CCompositor::startCompositor() { - g_pEventLoopManager->enterLoop(); - } - --CMonitor* CCompositor::getMonitorFromID(const int& id) { -+CMonitor* CCompositor::getMonitorFromID(const MONITORID& id) { - for (auto& m : m_vMonitors) { -- if (m->ID == (uint64_t)id) { -+ if (m->ID == id) { - return m.get(); - } - } -@@ -845,8 +859,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper - if (properties & FLOATING_ONLY) - return floating(false); - -- const int64_t WORKSPACEID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); -- const auto PWORKSPACE = getWorkspaceByID(WORKSPACEID); -+ const WORKSPACEID WSPID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); -+ const auto PWORKSPACE = getWorkspaceByID(WSPID); - - if (PWORKSPACE->m_bHasFullscreenWindow) - return getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); -@@ -860,7 +874,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper - if (special != w->onSpecialWorkspace()) - continue; - -- if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && -+ if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus && - !w->m_sWindowData.noFocus.valueOrDefault() && w != pIgnoreWindow) { - if (w->hasPopupAt(pos)) - return w; -@@ -872,7 +886,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper - continue; - - CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize}; -- if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && -+ if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus && - !w->m_sWindowData.noFocus.valueOrDefault() && w != pIgnoreWindow) - return w; - } -@@ -1207,7 +1221,7 @@ PHLWINDOW CCompositor::getWindowFromHandle(uint32_t handle) { - return nullptr; - } - --PHLWINDOW CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { -+PHLWINDOW CCompositor::getFullscreenWindowOnWorkspace(const WORKSPACEID& ID) { - for (auto& w : m_vWindows) { - if (w->workspaceID() == ID && w->isFullscreen()) - return w; -@@ -1231,7 +1245,7 @@ bool CCompositor::isWorkspaceVisibleNotCovered(PHLWORKSPACE w) { - return PMONITOR->activeWorkspace->m_iID == w->m_iID; - } - --PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { -+PHLWORKSPACE CCompositor::getWorkspaceByID(const WORKSPACEID& id) { - for (auto& w : m_vWorkspaces) { - if (w->m_iID == id && !w->inert()) - return w; -@@ -1255,7 +1269,7 @@ void CCompositor::sanityCheckWorkspaces() { - } - } - --int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTiled, std::optional onlyVisible) { -+int CCompositor::getWindowsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled, std::optional onlyVisible) { - int no = 0; - for (auto& w : m_vWindows) { - if (w->workspaceID() != id || !w->m_bIsMapped) -@@ -1270,7 +1284,7 @@ int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTi - return no; - } - --int CCompositor::getGroupsOnWorkspace(const int& id, std::optional onlyTiled, std::optional onlyVisible) { -+int CCompositor::getGroupsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled, std::optional onlyVisible) { - int no = 0; - for (auto& w : m_vWindows) { - if (w->workspaceID() != id || !w->m_bIsMapped) -@@ -1295,7 +1309,7 @@ PHLWINDOW CCompositor::getUrgentWindow() { - return nullptr; - } - --bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { -+bool CCompositor::hasUrgentWindowOnWorkspace(const WORKSPACEID& id) { - for (auto& w : m_vWindows) { - if (w->workspaceID() == id && w->m_bIsMapped && w->m_bIsUrgent) - return true; -@@ -1304,7 +1318,7 @@ bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { - return false; - } - --PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const int& id) { -+PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const WORKSPACEID& id) { - for (auto& w : m_vWindows) { - if (w->workspaceID() == id && w->m_bIsMapped && !w->isHidden()) - return w; -@@ -1313,7 +1327,7 @@ PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const int& id) { - return nullptr; - } - --PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const int& id) { -+PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const WORKSPACEID& id) { - const auto PWORKSPACE = getWorkspaceByID(id); - - if (!PWORKSPACE) -@@ -1401,12 +1415,12 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { - } - } - --void CCompositor::cleanupFadingOut(const int& monid) { -+void CCompositor::cleanupFadingOut(const MONITORID& monid) { - for (auto& ww : m_vWindowsFadingOut) { - - auto w = ww.lock(); - -- if (w->m_iMonitorID != (long unsigned int)monid) -+ if (w->m_iMonitorID != monid) - continue; - - if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) { -@@ -1702,8 +1716,8 @@ PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusabl - return nullptr; - } - --int CCompositor::getNextAvailableNamedWorkspace() { -- int lowest = -1337 + 1; -+WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { -+ WORKSPACEID lowest = -1337 + 1; - for (auto& w : m_vWorkspaces) { - if (w->m_iID < -1 && w->m_iID < lowest) - lowest = w->m_iID; -@@ -1927,18 +1941,18 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { - pWindow->updateWindowDecos(); - } - --int CCompositor::getNextAvailableMonitorID(std::string const& name) { -+MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { - // reuse ID if it's already in the map, and the monitor with that ID is not being used by another monitor - if (m_mMonitorIDMap.contains(name) && !std::any_of(m_vRealMonitors.begin(), m_vRealMonitors.end(), [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) - return m_mMonitorIDMap[name]; - - // otherwise, find minimum available ID that is not in the map -- std::unordered_set usedIDs; -+ std::unordered_set usedIDs; - for (auto const& monitor : m_vRealMonitors) { - usedIDs.insert(monitor->ID); - } - -- uint64_t nextID = 0; -+ MONITORID nextID = 0; - while (usedIDs.count(nextID) > 0) { - nextID++; - } -@@ -2078,7 +2092,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) { - return m_vMonitors[currentPlace].get(); - } else if (isNumber(name)) { - // change by ID -- int monID = -1; -+ MONITORID monID = MONITOR_INVALID; - try { - monID = std::stoi(name); - } catch (std::exception& e) { -@@ -2087,7 +2101,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) { - return nullptr; - } - -- if (monID > -1 && monID < (int)m_vMonitors.size()) { -+ if (monID > -1 && monID < (MONITORID)m_vMonitors.size()) { - return getMonitorFromID(monID); - } else { - Debug::log(ERR, "Error in getMonitorFromString: invalid arg 1"); -@@ -2121,7 +2135,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon - const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace : false; - - // fix old mon -- int nextWorkspaceOnMonitorID = -1; -+ WORKSPACEID nextWorkspaceOnMonitorID = WORKSPACE_INVALID; - if (!SWITCHINGISACTIVE) - nextWorkspaceOnMonitorID = pWorkspace->m_iID; - else { -@@ -2132,7 +2146,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon - } - } - -- if (nextWorkspaceOnMonitorID == -1) { -+ if (nextWorkspaceOnMonitorID == WORKSPACE_INVALID) { - nextWorkspaceOnMonitorID = 1; - - while (getWorkspaceByID(nextWorkspaceOnMonitorID) || [&]() -> bool { -@@ -2219,9 +2233,9 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon - EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); - } - --bool CCompositor::workspaceIDOutOfBounds(const int64_t& id) { -- int64_t lowestID = INT64_MAX; -- int64_t highestID = INT64_MIN; -+bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) { -+ WORKSPACEID lowestID = INT64_MAX; -+ WORKSPACEID highestID = INT64_MIN; - - for (auto& w : m_vWorkspaces) { - if (w->m_bIsSpecialWorkspace) -@@ -2370,7 +2384,7 @@ PHLWINDOW CCompositor::getX11Parent(PHLWINDOW pWindow) { - return nullptr; - } - --void CCompositor::updateWorkspaceWindowDecos(const int& id) { -+void CCompositor::updateWorkspaceWindowDecos(const WORKSPACEID& id) { - for (auto& w : m_vWindows) { - if (w->workspaceID() != id) - continue; -@@ -2379,7 +2393,7 @@ void CCompositor::updateWorkspaceWindowDecos(const int& id) { - } - } - --void CCompositor::updateWorkspaceWindowData(const int& id) { -+void CCompositor::updateWorkspaceWindowData(const WORKSPACEID& id) { - const auto PWORKSPACE = getWorkspaceByID(id); - const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{}; - -@@ -2599,7 +2613,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con - return Vector2D(X, Y); - } - --void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { -+void CCompositor::forceReportSizesToWindowsOnWorkspace(const WORKSPACEID& wid) { - for (auto& w : m_vWindows) { - if (w->workspaceID() == wid && w->m_bIsMapped && !w->isHidden()) { - g_pXWaylandManager->setWindowSize(w, w->m_vRealSize.value(), true); -@@ -2607,7 +2621,7 @@ void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { - } - } - --PHLWORKSPACE CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name, bool isEmtpy) { -+PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITORID& monid, const std::string& name, bool isEmtpy) { - const auto NAME = name == "" ? std::to_string(id) : name; - auto monID = monid; - -@@ -2625,7 +2639,7 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const int& id, const int& monid, co - return PWORKSPACE; - } - --void CCompositor::renameWorkspace(const int& id, const std::string& name) { -+void CCompositor::renameWorkspace(const WORKSPACEID& id, const std::string& name) { - const auto PWORKSPACE = getWorkspaceByID(id); - - if (!PWORKSPACE) -@@ -2656,12 +2670,12 @@ void CCompositor::setActiveMonitor(CMonitor* pMonitor) { - m_pLastMonitor = pMonitor->self; - } - --bool CCompositor::isWorkspaceSpecial(const int& id) { -+bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) { - return id >= SPECIAL_WORKSPACE_START && id <= -2; - } - --int CCompositor::getNewSpecialID() { -- int highest = SPECIAL_WORKSPACE_START; -+WORKSPACEID CCompositor::getNewSpecialID() { -+ WORKSPACEID highest = SPECIAL_WORKSPACE_START; - for (auto& ws : m_vWorkspaces) { - if (ws->m_bIsSpecialWorkspace && ws->m_iID > highest) { - highest = ws->m_iID; -@@ -2918,39 +2932,6 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) { - return {}; - } - --static void checkDefaultCursorWarp(SP PNEWMONITOR, std::string monitorName) { -- static auto PCURSORMONITOR = CConfigValue("cursor:default_monitor"); -- static auto firstMonitorAdded = std::chrono::system_clock::now(); -- static bool cursorDefaultDone = false; -- static bool firstLaunch = true; -- -- const auto POS = PNEWMONITOR->middle(); -- -- // by default, cursor should be set to first monitor detected -- // this is needed as a default if the monitor given in config above doesn't exist -- if (firstLaunch) { -- firstLaunch = false; -- g_pCompositor->warpCursorTo(POS, true); -- g_pInputManager->refocus(); -- } -- -- if (cursorDefaultDone || *PCURSORMONITOR == STRVAL_EMPTY) -- return; -- -- // after 10s, don't set cursor to default monitor -- auto timePassedSec = std::chrono::duration_cast(std::chrono::system_clock::now() - firstMonitorAdded); -- if (timePassedSec.count() > 10) { -- cursorDefaultDone = true; -- return; -- } -- -- if (*PCURSORMONITOR == monitorName) { -- cursorDefaultDone = true; -- g_pCompositor->warpCursorTo(POS, true); -- g_pInputManager->refocus(); -- } --} -- - void CCompositor::onNewMonitor(SP output) { - // add it to real - auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared()); -@@ -2965,7 +2946,7 @@ void CCompositor::onNewMonitor(SP output) { - PNEWMONITOR->output = output; - PNEWMONITOR->self = PNEWMONITOR; - const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false; -- PNEWMONITOR->ID = FALLBACK ? -1 : g_pCompositor->getNextAvailableMonitorID(output->name); -+ PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name); - PNEWMONITOR->isUnsafeFallback = FALLBACK; - - EMIT_HOOK_EVENT("newMonitor", PNEWMONITOR); -@@ -2986,11 +2967,9 @@ void CCompositor::onNewMonitor(SP output) { - g_pConfigManager->m_bWantsMonitorReload = true; - g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR); - -- checkDefaultCursorWarp(PNEWMONITOR, output->name); -- - for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iMonitorID == PNEWMONITOR->ID) { -- w->m_iLastSurfaceMonitorID = -1; -+ w->m_iLastSurfaceMonitorID = MONITOR_INVALID; - w->updateSurfaceScaleTransformDetails(); - } - } -diff --git a/src/Compositor.hpp b/src/Compositor.hpp -index 295935c4..a570a06e 100644 ---- a/src/Compositor.hpp -+++ b/src/Compositor.hpp -@@ -46,55 +46,56 @@ class CCompositor { - CCompositor(); - ~CCompositor(); - -- wl_display* m_sWLDisplay; -- wl_event_loop* m_sWLEventLoop; -- int m_iDRMFD = -1; -- bool m_bInitialized = false; -- SP m_pAqBackend; -- -- std::string m_szHyprTempDataRoot = ""; -- -- std::string m_szWLDisplaySocket = ""; -- std::string m_szInstanceSignature = ""; -- std::string m_szInstancePath = ""; -- std::string m_szCurrentSplash = "error"; -- -- std::vector> m_vMonitors; -- std::vector> m_vRealMonitors; // for all monitors, even those turned off -- std::vector m_vWindows; -- std::vector m_vLayers; -- std::vector m_vWorkspaces; -- std::vector m_vWindowsFadingOut; -- std::vector m_vSurfacesFadingOut; -- -- std::unordered_map m_mMonitorIDMap; -- -- void initServer(std::string socketName, int socketFd); -- void startCompositor(); -- void stopCompositor(); -- void cleanup(); -- void createLockFile(); -- void removeLockFile(); -- void bumpNofile(); -- void restoreNofile(); -- -- WP m_pLastFocus; -- PHLWINDOWREF m_pLastWindow; -- WP m_pLastMonitor; -- -- std::vector m_vWindowFocusHistory; // first element is the most recently focused. -- -- bool m_bReadyToProcess = false; -- bool m_bSessionActive = true; -- bool m_bDPMSStateON = true; -- bool m_bUnsafeState = false; // unsafe state is when there is no monitors. -- bool m_bNextIsUnsafe = false; -- CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state -- bool m_bIsShuttingDown = false; -+ wl_display* m_sWLDisplay; -+ wl_event_loop* m_sWLEventLoop; -+ int m_iDRMFD = -1; -+ bool m_bInitialized = false; -+ SP m_pAqBackend; -+ -+ std::string m_szHyprTempDataRoot = ""; -+ -+ std::string m_szWLDisplaySocket = ""; -+ std::string m_szInstanceSignature = ""; -+ std::string m_szInstancePath = ""; -+ std::string m_szCurrentSplash = "error"; -+ -+ std::vector> m_vMonitors; -+ std::vector> m_vRealMonitors; // for all monitors, even those turned off -+ std::vector m_vWindows; -+ std::vector m_vLayers; -+ std::vector m_vWorkspaces; -+ std::vector m_vWindowsFadingOut; -+ std::vector m_vSurfacesFadingOut; -+ -+ std::unordered_map m_mMonitorIDMap; -+ -+ void initServer(std::string socketName, int socketFd); -+ void startCompositor(); -+ void stopCompositor(); -+ void cleanup(); -+ void createLockFile(); -+ void removeLockFile(); -+ void bumpNofile(); -+ void restoreNofile(); -+ -+ WP m_pLastFocus; -+ PHLWINDOWREF m_pLastWindow; -+ WP m_pLastMonitor; -+ -+ std::vector m_vWindowFocusHistory; // first element is the most recently focused. -+ -+ bool m_bReadyToProcess = false; -+ bool m_bSessionActive = true; -+ bool m_bDPMSStateON = true; -+ bool m_bUnsafeState = false; // unsafe state is when there is no monitors. -+ bool m_bNextIsUnsafe = false; -+ CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state -+ bool m_bIsShuttingDown = false; -+ bool m_bDesktopEnvSet = false; - - // ------------------------------------------------- // - -- CMonitor* getMonitorFromID(const int&); -+ CMonitor* getMonitorFromID(const MONITORID&); - CMonitor* getMonitorFromName(const std::string&); - CMonitor* getMonitorFromDesc(const std::string&); - CMonitor* getMonitorFromCursor(); -@@ -114,38 +115,38 @@ class CCompositor { - PHLWINDOW getWindowFromHandle(uint32_t); - bool isWorkspaceVisible(PHLWORKSPACE); - bool isWorkspaceVisibleNotCovered(PHLWORKSPACE); -- PHLWORKSPACE getWorkspaceByID(const int&); -+ PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&); - PHLWORKSPACE getWorkspaceByName(const std::string&); - PHLWORKSPACE getWorkspaceByString(const std::string&); - void sanityCheckWorkspaces(); -- void updateWorkspaceWindowDecos(const int&); -- void updateWorkspaceWindowData(const int&); -- int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); -- int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); -+ void updateWorkspaceWindowDecos(const WORKSPACEID&); -+ void updateWorkspaceWindowData(const WORKSPACEID&); -+ int getWindowsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); -+ int getGroupsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); - PHLWINDOW getUrgentWindow(); -- bool hasUrgentWindowOnWorkspace(const int&); -- PHLWINDOW getFirstWindowOnWorkspace(const int&); -- PHLWINDOW getTopLeftWindowOnWorkspace(const int&); -- PHLWINDOW getFullscreenWindowOnWorkspace(const int&); -+ bool hasUrgentWindowOnWorkspace(const WORKSPACEID&); -+ PHLWINDOW getFirstWindowOnWorkspace(const WORKSPACEID&); -+ PHLWINDOW getTopLeftWindowOnWorkspace(const WORKSPACEID&); -+ PHLWINDOW getFullscreenWindowOnWorkspace(const WORKSPACEID&); - bool isWindowActive(PHLWINDOW); - void changeWindowZOrder(PHLWINDOW, bool); -- void cleanupFadingOut(const int& monid); -+ void cleanupFadingOut(const MONITORID& monid); - PHLWINDOW getWindowInDirection(PHLWINDOW, char); - PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); -- int getNextAvailableNamedWorkspace(); -+ WORKSPACEID getNextAvailableNamedWorkspace(); - bool isPointOnAnyMonitor(const Vector2D&); - bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr); - CMonitor* getMonitorInDirection(const char&); - CMonitor* getMonitorInDirection(CMonitor*, const char&); - void updateAllWindowsAnimatedDecorationValues(); -- void updateWorkspaceWindows(const int64_t& id); -+ void updateWorkspaceWindows(const WORKSPACEID& id); - void updateWindowAnimatedDecorationValues(PHLWINDOW); -- int getNextAvailableMonitorID(std::string const& name); -+ MONITORID getNextAvailableMonitorID(std::string const& name); - void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false); - void swapActiveWorkspaces(CMonitor*, CMonitor*); - CMonitor* getMonitorFromString(const std::string&); -- bool workspaceIDOutOfBounds(const int64_t&); -+ bool workspaceIDOutOfBounds(const WORKSPACEID&); - void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); - void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); - void setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state); -@@ -162,12 +163,13 @@ class CCompositor { - PHLLS getLayerSurfaceFromSurface(SP); - void closeWindow(PHLWINDOW); - Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); -- void forceReportSizesToWindowsOnWorkspace(const int&); -- PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused! -- void renameWorkspace(const int&, const std::string& name = ""); -+ void forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&); -+ PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "", -+ bool isEmtpy = true); // will be deleted next frame if left empty and unfocused! -+ void renameWorkspace(const WORKSPACEID&, const std::string& name = ""); - void setActiveMonitor(CMonitor*); -- bool isWorkspaceSpecial(const int&); -- int getNewSpecialID(); -+ bool isWorkspaceSpecial(const WORKSPACEID&); -+ WORKSPACEID getNewSpecialID(); - void performUserChecks(); - void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace); - PHLWINDOW getForceFocus(); -diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp -index 2a1546c6..9bee7150 100644 ---- a/src/SharedDefs.hpp -+++ b/src/SharedDefs.hpp -@@ -52,4 +52,8 @@ struct SHyprCtlCommand { - std::function fn; - }; - -+typedef int64_t WINDOWID; -+typedef int64_t MONITORID; -+typedef int64_t WORKSPACEID; -+ - typedef std::function HOOK_CALLBACK_FN; -diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp -new file mode 100644 -index 00000000..3c830132 ---- /dev/null -+++ b/src/config/ConfigDescriptions.hpp -@@ -0,0 +1,1344 @@ -+#pragma once -+ -+#include "ConfigManager.hpp" -+ -+inline static const std::vector CONFIG_OPTIONS = { -+ -+ /* -+ * general: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "general:border_size", -+ .description = "size of the border around windows", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:no_border_on_floating", -+ .description = "disable borders for floating windows", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:gaps_in", -+ .description = "gaps between windows\n\nsupports css style gaps (top, right, bottom, left -> 5 10 15 20)", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{"5"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:gaps_out", -+ .description = "gaps between windows and monitor edges\n\nsupports css style gaps (top, right, bottom, left -> 5 10 15 20)", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{"20"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:gaps_workspaces", -+ .description = "gaps between workspaces. Stacks with gaps_out.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 100}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.inactive_border", -+ .description = "border color for inactive windows", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0xff444444"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.active_border", -+ .description = "border color for the active window", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0xffffffff"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.nogroup_border", -+ .description = "inactive border color for window that cannot be added to a group (see denywindowfromgroup dispatcher)", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0xffffaaff"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.nogroup_border_active", -+ .description = "active border color for window that cannot be added to a group", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0xffff00ff"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:layout", -+ .description = "which layout to use. [dwindle/master]", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{"dwindle"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:no_focus_fallback", -+ .description = "if true, will not fall back to the next available window when moving focus in a direction where no window was found", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:resize_on_border", -+ .description = "enables resizing windows by clicking and dragging on borders and gaps", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:extend_border_grab_area", -+ .description = "extends the area around the border where you can click and drag on, only used when general:resize_on_border is on.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{15, 0, 100}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:hover_icon_on_border", -+ .description = "show a cursor icon when hovering over borders, only used when general:resize_on_border is on.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:allow_tearing", -+ .description = "master switch for allowing tearing to occur. See the Tearing page.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:resize_corner", -+ .description = "force floating windows to use a specific corner when being resized (1-4 going clockwise from top left, 0 to disable)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 4}, -+ }, -+ -+ /* -+ * decoration: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "decoration:rounding", -+ .description = "rounded corners' radius (in layout px)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:active_opacity", -+ .description = "opacity of active windows. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:inactive_opacity", -+ .description = "opacity of inactive windows. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:fullscreen_opacity", -+ .description = "opacity of fullscreen windows. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:drop_shadow", -+ .description = "enable drop shadows on windows", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:shadow_range", -+ .description = "Shadow range (size) in layout px", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{4, 0, 100}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:shadow_render_power", -+ .description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{3, 1, 4}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:shadow_ignore_window", -+ .description = "if true, the shadow will not be rendered behind the window itself, only around it.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:col.shadow", -+ .description = "shadow's color. Alpha dictates shadow's opacity.", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0xee1a1a1a}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:col.shadow_inactive", -+ .description = "inactive shadow color. (if not set, will fall back to col.shadow)", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:shadow_offset", -+ .description = "shadow's rendering offset.", -+ .type = CONFIG_OPTION_VECTOR, -+ .data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:shadow_scale", -+ .description = "shadow's scale. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:dim_inactive", -+ .description = "enables dimming of inactive windows", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:dim_strength", -+ .description = "how much inactive windows should be dimmed [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.5, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:dim_special", -+ .description = "how much to dim the rest of the screen by when a special workspace is open. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.2, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:dim_around", -+ .description = "how much the dimaround window rule should dim by. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.4, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "decoration:screen_shader", -+ .description = "screen_shader a path to a custom shader to be applied at the end of rendering. See examples/screenShader.frag for an example.", -+ .type = CONFIG_OPTION_STRING_LONG, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ -+ /* -+ * blur: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "blur:enabled", -+ .description = "enable kawase window background blur", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:size", -+ .description = "blur size (distance)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{8, 0, 100}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:passes", -+ .description = "the amount of passes to perform", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 10}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:ignore_opacity", -+ .description = "make the blur layer ignore the opacity of the window", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:new_optimizations", -+ .description = "whether to enable further optimizations to the blur. Recommended to leave on, as it will massively improve performance.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:xray", -+ .description = "if enabled, floating windows will ignore tiled windows in their blur. Only available if blur_new_optimizations is true. Will reduce overhead on floating " -+ "blur significantly.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:noise", -+ .description = "how much noise to apply. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.0117, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:contrast", -+ .description = "contrast modulation for blur. [0.0 - 2.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.8916, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:brightness", -+ .description = "brightness modulation for blur. [0.0 - 2.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.8172, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:vibrancy", -+ .description = "Increase saturation of blurred colors. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.1696, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:vibrancy_darkness", -+ .description = "How strong the effect of vibrancy is on dark areas . [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:special", -+ .description = "whether to blur behind the special workspace (note: expensive)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:popups", -+ .description = "whether to blur popups (e.g. right-click menus)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "blur:popups_ignorealpha", -+ .description = "works like ignorealpha in layer rules. If pixel opacity is below set value, will not blur. [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.2, 0, 1}, -+ }, -+ -+ /* -+ * animations: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "animations:enabled", -+ .description = "enable animations", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "animations:first_launch_animation", -+ .description = "enable first launch animation", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ -+ /* -+ * input: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "input:kb_model", -+ .description = "Appropriate XKB keymap parameter. See the note below.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:kb_layout", -+ .description = "Appropriate XKB keymap parameter", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{"us"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:kb_variant", -+ .description = "Appropriate XKB keymap parameter", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:kb_options", -+ .description = "Appropriate XKB keymap parameter", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:kb_rules", -+ .description = "Appropriate XKB keymap parameter", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:kb_file", -+ .description = "Appropriate XKB keymap parameter", -+ .type = CONFIG_OPTION_STRING_LONG, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:numlock_by_default", -+ .description = "Engage numlock by default.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:resolve_binds_by_sym", -+ .description = "Determines how keybinds act when multiple layouts are used. If false, keybinds will always act as if the first specified layout is active. If true, " -+ "keybinds specified by symbols are activated when you type the respective symbol with the current layout.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:repeat_rate", -+ .description = "The repeat rate for held-down keys, in repeats per second.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{25, 0, 200}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:repeat_delay", -+ .description = "Delay before a held-down key is repeated, in milliseconds.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{600, 0, 2000}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:sensitivity", -+ .description = "Sets the mouse input sensitivity. Value is clamped to the range -1.0 to 1.0.", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0, -1, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:accel_profile", -+ .description = "Sets the cursor acceleration profile. Can be one of adaptive, flat. Can also be custom, see below. Leave empty to use libinput's default mode for your " -+ "input device. [adaptive/flat/custom]", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:force_no_accel", -+ .description = "Force no cursor acceleration. This bypasses most of your pointer settings to get as raw of a signal as possible. Enabling this is not recommended due to " -+ "potential cursor desynchronization.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:left_handed", -+ .description = "Switches RMB and LMB", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:scroll_points", -+ .description = "Sets the scroll acceleration profile, when accel_profile is set to custom. Has to be in the form . Leave empty to have a flat scroll curve.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:scroll_method", -+ .description = "Sets the scroll method. Can be one of 2fg (2 fingers), edge, on_button_down, no_scroll. [2fg/edge/on_button_down/no_scroll]", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:scroll_button", -+ .description = "Sets the scroll button. Has to be an int, cannot be a string. Check wev if you have any doubts regarding the ID. 0 means default.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 300}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:scroll_button_lock", -+ .description = "If the scroll button lock is enabled, the button does not need to be held down. Pressing and releasing the button toggles the button lock, which logically " -+ "holds the button down or releases it. While the button is logically held down, motion events are converted to scroll events.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:scroll_factor", -+ .description = "Multiplier added to scroll movement for external mice. Note that there is a separate setting for touchpad scroll_factor.", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:natural_scroll", -+ .description = "Inverts scrolling direction. When enabled, scrolling moves content directly, rather than manipulating a scrollbar.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:follow_mouse", -+ .description = "Specify if and how cursor movement should affect window focus. See the note below. [0/1/2/3]", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 3}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:mouse_refocus", -+ .description = "if disabled, mouse focus won't switch to the hovered window unless the mouse crosses a window boundary when follow_mouse=1.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:float_switch_override_focus", -+ .description = "If enabled (1 or 2), focus will change to the window under the cursor when changing from tiled-to-floating and vice versa. If 2, focus will also follow " -+ "mouse on float-to-float switches.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:special_fallthrough", -+ .description = "if enabled, having only floating windows in the special workspace will not block focusing windows in the regular workspace.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:off_window_axis_events", -+ .description = "Handles axis events around (gaps/border for tiled, dragarea/border for floated) a focused window. 0 ignores axis events 1 sends out-of-bound coordinates 2 " -+ "fakes pointer coordinates to the closest point inside the window 3 warps the cursor to the closest point inside the window", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 3}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:emulate_discrete_scroll", -+ .description = "Emulates discrete scrolling from high resolution scrolling events. 0 disables it, 1 enables handling of non-standard events only, and 2 force enables all " -+ "scroll wheel events to be handled", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, -+ }, -+ -+ /* -+ * input:touchpad: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "input:touchpad:disable_while_typing", -+ .description = "Disable the touchpad while typing.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:natural_scroll", -+ .description = "Inverts scrolling direction. When enabled, scrolling moves content directly, rather than manipulating a scrollbar.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:scroll_factor", -+ .description = "Multiplier applied to the amount of scroll movement.", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:middle_button_emulation", -+ .description = -+ "Sending LMB and RMB simultaneously will be interpreted as a middle click. This disables any touchpad area that would normally send a middle click based on location.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:tap_button_map", -+ .description = "Sets the tap button mapping for touchpad button emulation. Can be one of lrm (default) or lmr (Left, Middle, Right Buttons). [lrm/lmr]", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:clickfinger_behavior", -+ .description = -+ "Button presses with 1, 2, or 3 fingers will be mapped to LMB, RMB, and MMB respectively. This disables interpretation of clicks based on location on the touchpad.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:tap-to-click", -+ .description = "Tapping on the touchpad with 1, 2, or 3 fingers will send LMB, RMB, and MMB respectively.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:drag_lock", -+ .description = "When enabled, lifting the finger off for a short time while dragging will not drop the dragged item.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchpad:tap-and-drag", -+ .description = "Sets the tap and drag mode for the touchpad", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ -+ /* -+ * input:touchdevice: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "input:touchdevice:transform", -+ .description = "Transform the input from touchdevices. The possible transformations are the same as those of the monitors", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 6}, // ##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchdevice:output", -+ .description = "The monitor to bind touch devices. The default is auto-detection. To stop auto-detection, use an empty string or the [[Empty]] value.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:touchdevice:enabled", -+ .description = "Whether input is enabled for touch devices.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ -+ /* -+ * input:tablet: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "input:tablet:transform", -+ .description = "transform the input from tablets. The possible transformations are the same as those of the monitors", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 6}, // ##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:output", -+ .description = "the monitor to bind tablets. Empty means unbound..", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:region_position", -+ .description = "position of the mapped region in monitor layout.", -+ .type = CONFIG_OPTION_VECTOR, -+ .data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:region_size", -+ .description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.", -+ .type = CONFIG_OPTION_VECTOR, -+ .data = SConfigOptionDescription::SVectorData{{}, {-100, -100}, {4000, 4000}}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:relative_input", -+ .description = "whether the input should be relative", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:left_handed", -+ .description = "if enabled, the tablet will be rotated 180 degrees", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:active_area_size", -+ .description = "size of tablet's active area in mm", -+ .type = CONFIG_OPTION_VECTOR, -+ .data = SConfigOptionDescription::SVectorData{{}, {}, {500, 500}}, -+ }, -+ SConfigOptionDescription{ -+ .value = "input:tablet:active_area_position", -+ .description = "position of the active area in mm", -+ .type = CONFIG_OPTION_VECTOR, -+ .data = SConfigOptionDescription::SVectorData{{}, {}, {500, 500}}, -+ }, -+ -+ /* ##TODO -+ * -+ * PER DEVICE SETTINGS? -+ * -+ * */ -+ -+ /* -+ * gestures: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe", -+ .description = "enable workspace swipe gesture on touchpad", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_fingers", -+ .description = "how many fingers for the touchpad gesture", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{3, 0, 5}, //##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_min_fingers", -+ .description = "if enabled, workspace_swipe_fingers is considered the minimum number of fingers to swipe", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_distance", -+ .description = "in px, the distance of the touchpad gesture", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{300, 0, 2000}, //##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_touch", -+ .description = "enable workspace swiping from the edge of a touchscreen", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_invert", -+ .description = "invert the direction (touchpad only)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_touch_invert", -+ .description = "invert the direction (touchscreen only)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_min_speed_to_force", -+ .description = "minimum speed in px per timepoint to force the change ignoring cancel_ratio. Setting to 0 will disable this mechanic.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{30, 0, 200}, //##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_cancel_ratio", -+ .description = "how much the swipe has to proceed in order to commence it. (0.7 -> if > 0.7 * distance, switch, if less, revert) [0.0 - 1.0]", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{0.5, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_create_new", -+ .description = "whether a swipe right on the last workspace should create a new one.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_direction_lock", -+ .description = "if enabled, switching direction will be locked when you swipe past the direction_lock_threshold (touchpad only).", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_direction_lock_threshold", -+ .description = "in px, the distance to swipe before direction lock activates (touchpad only).", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{10, 0, 200}, //##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_forever", -+ .description = "if enabled, swiping will not clamp at the neighboring workspaces but continue to the further ones.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "gestures:workspace_swipe_use_r", -+ .description = "if enabled, swiping will use the r prefix instead of the m prefix for finding workspaces.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ -+ /* -+ * group: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "group:insert_after_current", -+ .description = "whether new windows in a group spawn after current or at group tail", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:focus_removed_window", -+ .description = "whether Hyprland should focus on the window that has just been moved out of the group", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.border_active", -+ .description = "border color for inactive windows", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0x66ffff00"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.border_inactive", -+ .description = "border color for the active window", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0x66777700"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.border_locked_active", -+ .description = "inactive border color for window that cannot be added to a group (see denywindowfromgroup dispatcher)", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0x66ff5500"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "general:col.border_locked_inactive", -+ .description = "active border color for window that cannot be added to a group", -+ .type = CONFIG_OPTION_GRADIENT, -+ .data = SConfigOptionDescription::SGradientData{"0x66775500"}, -+ }, -+ -+ /* -+ * group:groupbar: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "group:groupbar:enabled", -+ .description = "enables groupbars", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:font_family", -+ .description = "font used to display groupbar titles, use misc:font_family if not specified", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:font_size", -+ .description = "font size of groupbar title", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{8, 2, 64}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:gradients", -+ .description = "enables gradients", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:height", -+ .description = "height of the groupbar", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{14, 1, 64}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:stacked", -+ .description = "render the groupbar as a vertical stack", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:priority", -+ .description = "sets the decoration priority for groupbars", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{3, 0, 6}, //##TODO RANGE? -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:render_titles", -+ .description = "whether to render titles in the group bar decoration", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:scrolling", -+ .description = "whether scrolling in the groupbar changes group active window", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:text_color", -+ .description = "controls the group bar text color", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0xffffffff}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:col.active", -+ .description = "active group border color", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0x66ffff00}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:col.inactive", -+ .description = "inactive (out of focus) group border color", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0x66777700}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:col.locked_active", -+ .description = "active locked group border color", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0x66ff5500}, -+ }, -+ SConfigOptionDescription{ -+ .value = "group:groupbar:col.locked_inactive", -+ .description = "controls the group bar text color", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0x66775500}, -+ }, -+ -+ /* -+ * misc: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "misc:disable_hyprland_logo", -+ .description = "disables the random Hyprland logo / anime girl background. :(", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:disable_splash_rendering", -+ .description = "disables the Hyprland splash rendering. (requires a monitor reload to take effect)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:col.splash", -+ .description = "Changes the color of the splash text (requires a monitor reload to take effect).", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0xffffffff}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:font_family", -+ .description = "Set the global default font to render the text including debug fps/notification, config error messages and etc., selected from system fonts.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{"Sans"}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:splash_font_family", -+ .description = "Changes the font used to render the splash text, selected from system fonts (requires a monitor reload to take effect).", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:force_default_wallpaper", -+ .description = "Enforce any of the 3 default wallpapers. Setting this to 0 or 1 disables the anime background. -1 means “random”. [-1/0/1/2]", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{-1, -1, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:vfr", -+ .description = "controls the VFR status of Hyprland. Heavily recommended to leave enabled to conserve resources.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:vrr", -+ .description = " controls the VRR (Adaptive Sync) of your monitors. 0 - off, 1 - on, 2 - fullscreen only [0/1/2]", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:mouse_move_enables_dpms", -+ .description = "If DPMS is set to off, wake up the monitors if the mouse move", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:key_press_enables_dpms", -+ .description = "If DPMS is set to off, wake up the monitors if a key is pressed.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:always_follow_on_dnd", -+ .description = "Will make mouse focus follow the mouse when drag and dropping. Recommended to leave it enabled, especially for people using focus follows mouse at 0.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:layers_hog_keyboard_focus", -+ .description = "If true, will make keyboard-interactive layers keep their focus on mouse move (e.g. wofi, bemenu)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:animate_manual_resizes", -+ .description = "If true, will animate manual window resizes/moves", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:animate_mouse_windowdragging", -+ .description = "If true, will animate windows being dragged by mouse, note that this can cause weird behavior on some curves", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:disable_autoreload", -+ .description = "If true, the config will not reload automatically on save, and instead needs to be reloaded with hyprctl reload. Might save on battery.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:enable_swallow", -+ .description = "Enable window swallowing", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:swallow_regex", -+ .description = -+ "The class regex to be used for windows that should be swallowed (usually, a terminal). To know more about the list of regex which can be used use this cheatsheet.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:swallow_exception_regex", -+ .description = "The title regex to be used for windows that should not be swallowed by the windows specified in swallow_regex (e.g. wev). The regex is matched against the " -+ "parent (e.g. Kitty) window’s title on the assumption that it changes to whatever process it’s running.", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:focus_on_activate", -+ .description = "Whether Hyprland should focus an app that requests to be focused (an activate request)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:mouse_move_focuses_monitor", -+ .description = "Whether mouse moving into a different monitor should focus it", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:render_ahead_of_time", -+ .description = "[Warning: buggy] starts rendering before your monitor displays a frame in order to lower latency", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:render_ahead_safezone", -+ .description = "how many ms of safezone to add to rendering ahead of time. Recommended 1-2.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 1, 10}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:allow_session_lock_restore", -+ .description = "if true, will allow you to restart a lockscreen app in case it crashes (red screen of death)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:background_color", -+ .description = "change the background color. (requires enabled disable_hyprland_logo)", -+ .type = CONFIG_OPTION_COLOR, -+ .data = SConfigOptionDescription::SColorData{0x111111}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:close_special_on_empty", -+ .description = "close the special workspace if the last window is removed", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:new_window_takes_over_fullscreen", -+ .description = "if there is a fullscreen or maximized window, decide whether a new tiled window opened should replace it, stay behind or disable the fullscreen/maximized " -+ "state. 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize [0/1/2]", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:exit_window_retains_fullscreen", -+ .description = "if true, closing a fullscreen window makes the next focused window fullscreen", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:initial_workspace_tracking", -+ .description = "if enabled, windows will open on the workspace they were invoked on. 0 - disabled, 1 - single-shot, 2 - persistent (all children too)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "misc:middle_click_paste", -+ .description = "whether to enable middle-click-paste (aka primary selection)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ -+ /* -+ * binds: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "binds:pass_mouse_when_bound", -+ .description = "if disabled, will not pass the mouse events to apps / dragging windows around if a keybind has been triggered.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:scroll_event_delay", -+ .description = "in ms, how many ms to wait after a scroll event to allow passing another one for the binds.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{300, 0, 2000}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:workspace_back_and_forth", -+ .description = "If enabled, an attempt to switch to the currently focused workspace will instead switch to the previous workspace. Akin to i3’s auto_back_and_forth.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:allow_workspace_cycles", -+ .description = "If enabled, workspaces don’t forget their previous workspace, so cycles can be created by switching to the first workspace in a sequence, then endlessly " -+ "going to the previous workspace.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:workspace_center_on", -+ .description = "Whether switching workspaces should center the cursor on the workspace (0) or on the last active window for that workspace (1)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:focus_preferred_method", -+ .description = "sets the preferred focus finding method when using focuswindow/movewindow/etc with a direction. 0 - history (recent have priority), 1 - length (longer " -+ "shared edges have priority)", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:ignore_group_lock", -+ .description = "If enabled, dispatchers like moveintogroup, moveoutofgroup and movewindoworgroup will ignore lock per group.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:movefocus_cycles_fullscreen", -+ .description = "If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:disable_keybind_grabbing", -+ .description = "If enabled, apps that request keybinds to be disabled (e.g. VMs) will not be able to do so.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "binds:window_direction_monitor_fallback", -+ .description = "If enabled, moving a window or focus over the edge of a monitor with a direction will move it to the next monitor in that direction.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ -+ /* -+ * xwayland: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "xwayland:use_nearest_neighbor", -+ .description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "xwayland:force_zero_scaling", -+ .description = "forces a scale of 1 on xwayland windows on scaled displays.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ -+ /* -+ * opengl: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "opengl:nvidia_anti_flicker", -+ .description = "reduces flickering on nvidia at the cost of possible frame drops on lower-end GPUs. On non-nvidia, this is ignored.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "opengl:force_introspection", -+ .description = "forces introspection at all times. Introspection is aimed at reducing GPU usage in certain cases, but might cause graphical glitches on nvidia. 0 - " -+ "nothing, 1 - force always on, 2 - force always on if nvidia", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, -+ }, -+ -+ /* -+ * render: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "render:explicit_sync", -+ .description = "Whether to enable explicit sync support. Requires a hyprland restart. 0 - no, 1 - yes, 2 - auto based on the gpu driver", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "render:explicit_sync_kms", -+ .description = "Whether to enable explicit sync support for the KMS layer. Requires explicit_sync to be enabled. 0 - no, 1 - yes, 2 - auto based on the gpu driver", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "render:direct_scanout", -+ .description = "Enables direct scanout. Direct scanout attempts to reduce lag when there is only one fullscreen application on a screen (e.g. game). It is also " -+ "recommended to set this to false if the fullscreen application shows graphical glitches.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ -+ /* -+ * cursor: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "cursor:use_nearest_neighbor", -+ .description = "sync xcursor theme with gsettings, it applies cursor-theme and cursor-size on theme load to gsettings making most CSD gtk based clients use same xcursor " -+ "theme and size.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:no_hardware_cursors", -+ .description = "disables hardware cursors", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:no_break_fs_vrr", -+ .description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (requires no_hardware_cursors = true)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:min_refresh_rate", -+ .description = "minimum refresh rate for cursor movement when no_break_fs_vrr is active. Set to minimum supported refresh rate or higher", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{24, 10, 500}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:hotspot_padding", -+ .description = "the padding, in logical px, between screen edges and the cursor", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{1, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:inactive_timeout", -+ .description = "in seconds, after how many seconds of cursor’s inactivity to hide it. Set to 0 for never.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:no_warps", -+ .description = "if true, will not warp the cursor in many cases (focusing, keybinds, etc)", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:persistent_warps", -+ .description = "When a window is refocused, the cursor returns to its last position relative to that window, rather than to the centre.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:warp_on_change_workspace", -+ .description = "If true, move the cursor to the last focused window after changing the workspace.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:default_monitor", -+ .description = "the name of a default monitor for the cursor to be set to on startup (see hyprctl monitors for names)", -+ .type = CONFIG_OPTION_STRING_SHORT, -+ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:zoom_factor", -+ .description = "the factor to zoom by around the cursor. Like a magnifying glass. Minimum 1.0 (meaning no zoom)", -+ .type = CONFIG_OPTION_FLOAT, -+ .data = SConfigOptionDescription::SFloatData{1, 1, 10}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:zoom_rigid", -+ .description = "whether the zoom should follow the cursor rigidly (cursor is always centered if it can be) or loosely", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:enable_hyprcursor", -+ .description = "whether to enable hyprcursor support", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:hide_on_key_press", -+ .description = "Hides the cursor when you press any key until the mouse is moved.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:hide_on_touch", -+ .description = "Hides the cursor when the last input was a touch input until a mouse input is done.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "cursor:allow_dumb_copy", -+ .description = "Makes HW cursors work on Nvidia, at the cost of a possible hitch whenever the image changes", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ -+ /* -+ * debug: -+ */ -+ -+ SConfigOptionDescription{ -+ .value = "debug:overlay", -+ .description = "print the debug performance overlay. Disable VFR for accurate results.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:damage_blink", -+ .description = "disable logging to a file", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:disable_logs", -+ .description = "disable logging to a file", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:disable_time", -+ .description = "disables time logging", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:damage_tracking", -+ .description = "redraw only the needed bits of the display. Do not change. (default: full - 2) monitor - 1, none - 0", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:enable_stdout_logs", -+ .description = "enables logging to stdout", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:manual_crash", -+ .description = "set to 1 and then back to 0 to crash Hyprland.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:suppress_errors", -+ .description = "if true, do not display config file parsing errors.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:watchdog_timeout", -+ .description = "sets the timeout in seconds for watchdog to abort processing of a signal of the main thread. Set to 0 to disable.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{5, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:disable_scale_checks", -+ .description = "disables verification of the scale factors. Will result in pixel alignment and rounding errors.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{false}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:error_limit", -+ .description = "limits the number of displayed config file parsing errors.", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{5, 0, 20}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:error_position", -+ .description = "sets the position of the error bar. top - 0, bottom - 1", -+ .type = CONFIG_OPTION_INT, -+ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, -+ }, -+ SConfigOptionDescription{ -+ .value = "debug:colored_stdout_logs", -+ .description = "enables colors in the stdout logs.", -+ .type = CONFIG_OPTION_BOOL, -+ .data = SConfigOptionDescription::SBoolData{true}, -+ }, -+}; -\ No newline at end of file -diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp -index be6433fa..1856bd49 100644 ---- a/src/config/ConfigManager.cpp -+++ b/src/config/ConfigManager.cpp -@@ -28,7 +28,9 @@ - #include - using namespace Hyprutils::String; - --extern "C" char** environ; -+extern "C" char** environ; -+ -+#include "ConfigDescriptions.hpp" - - static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void** data) { - std::string V = VALUE; -@@ -312,8 +314,6 @@ CConfigManager::CConfigManager() { - configPaths.emplace_back(getMainConfigPath()); - m_pConfig = std::make_unique(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); - -- m_pConfig->addConfigValue("general:sensitivity", {1.0f}); -- m_pConfig->addConfigValue("general:apply_sens_to_raw", Hyprlang::INT{0}); - m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1}); - m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0}); - m_pConfig->addConfigValue("general:border_part_of_window", Hyprlang::INT{1}); -@@ -531,7 +531,7 @@ CConfigManager::CConfigManager() { - m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24}); - m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0}); -- m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0}); -+ m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f}); - m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:persistent_warps", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:warp_on_change_workspace", Hyprlang::INT{0}); -@@ -539,6 +539,7 @@ CConfigManager::CConfigManager() { - m_pConfig->addConfigValue("cursor:zoom_factor", {1.f}); - m_pConfig->addConfigValue("cursor:zoom_rigid", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:enable_hyprcursor", Hyprlang::INT{1}); -+ m_pConfig->addConfigValue("cursor:sync_gsettings_theme", Hyprlang::INT{1}); - m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1}); - m_pConfig->addConfigValue("cursor:allow_dumb_copy", Hyprlang::INT{0}); -@@ -821,9 +822,6 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { - if (!isFirstLaunch) - g_pHyprOpenGL->m_bReloadScreenShader = true; - -- if (!isFirstLaunch && *PENABLEEXPLICIT != prevEnabledExplicit) -- g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); -- - // parseError will be displayed next frame - - if (result.error) -@@ -836,6 +834,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { - else if (std::any_cast(m_pConfig->getConfigValue("autogenerated")) == 1) - g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland", - CColor(1.0, 1.0, 70.0 / 255.0, 1.0)); -+ else if (*PENABLEEXPLICIT != prevEnabledExplicit) -+ g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); - else - g_pHyprError->destroy(); - -@@ -924,7 +924,10 @@ void CConfigManager::init() { - } - - std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) { -- const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str()); -+ static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); -+ static int prevEnabledExplicit = *PENABLEEXPLICIT; -+ -+ const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str()); - - // invalidate layouts if they changed - if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) { -@@ -932,6 +935,13 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std:: - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID); - } - -+ if (COMMAND.contains("explicit")) { -+ if (*PENABLEEXPLICIT != prevEnabledExplicit) -+ g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); -+ else -+ g_pHyprError->destroy(); -+ } -+ - // Update window border colors - g_pCompositor->updateAllWindowsAnimatedDecorationValues(); - -@@ -2425,7 +2435,7 @@ std::optional CConfigManager::handleWorkspaceRules(const std::strin - // } - - const static std::string ruleOnCreatedEmpty = "on-created-empty:"; -- const static int ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length(); -+ const static auto ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length(); - - auto assignRule = [&](std::string rule) -> std::optional { - size_t delim = std::string::npos; -@@ -2597,3 +2607,60 @@ std::optional CConfigManager::handlePlugin(const std::string& comma - - return {}; - } -+ -+const std::vector& CConfigManager::getAllDescriptions() { -+ return CONFIG_OPTIONS; -+} -+ -+std::string SConfigOptionDescription::jsonify() const { -+ auto parseData = [this]() -> std::string { -+ return std::visit( -+ [](auto&& val) { -+ using T = std::decay_t; -+ if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": "{}")#", val.value); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": {}, -+ "min": {}, -+ "max": {})#", -+ val.value, val.min, val.max); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": {}, -+ "min": {}, -+ "max": {})#", -+ val.value, val.min, val.max); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": {})#", val.color.getAsHex()); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": {})#", val.value); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": {})#", val.choices); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "x": {}, -+ "y": {}, -+ "min_x": {}, -+ "min_y": {}, -+ "max_x": {}, -+ "max_y": {})#", -+ val.vec.x, val.vec.y, val.min.x, val.min.y, val.max.x, val.max.y); -+ } else if constexpr (std::is_same_v) { -+ return std::format(R"#( "value": "{}")#", val.gradient); -+ } -+ return std::string{""}; -+ }, -+ data); -+ }; -+ -+ std::string json = std::format(R"#({{ -+ "value": "{}", -+ "description": "{}", -+ "type": {}, -+ "flags": {}, -+ "data": {{ -+ {} -+ }} -+}})#", -+ value, description, (uint16_t)type, (uint32_t)flags, parseData()); -+ -+ return json; -+} -diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp -index 75dea9ef..4241031b 100644 ---- a/src/config/ConfigManager.hpp -+++ b/src/config/ConfigManager.hpp -@@ -33,7 +33,7 @@ struct SWorkspaceRule { - std::string monitor = ""; - std::string workspaceString = ""; - std::string workspaceName = ""; -- int workspaceId = -1; -+ WORKSPACEID workspaceId = -1; - bool isDefault = false; - bool isPersistent = false; - std::optional gapsIn; -@@ -83,6 +83,70 @@ struct SExecRequestedRule { - uint64_t iPid = 0; - }; - -+enum eConfigOptionType : uint16_t { -+ CONFIG_OPTION_BOOL = 0, -+ CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/ -+ CONFIG_OPTION_FLOAT = 2, -+ CONFIG_OPTION_STRING_SHORT = 3, /* e.g. "auto" */ -+ CONFIG_OPTION_STRING_LONG = 4, /* e.g. a command */ -+ CONFIG_OPTION_COLOR = 5, -+ CONFIG_OPTION_CHOICE = 6, /* e.g. "one", "two", "three" */ -+ CONFIG_OPTION_GRADIENT = 7, -+ CONFIG_OPTION_VECTOR = 8, -+}; -+ -+enum eConfigOptionFlags : uint32_t { -+ CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0), -+}; -+ -+struct SConfigOptionDescription { -+ -+ struct SBoolData { -+ bool value = false; -+ }; -+ -+ struct SRangeData { -+ int value = 0, min = 0, max = 2; -+ }; -+ -+ struct SFloatData { -+ float value = 0, min = 0, max = 100; -+ }; -+ -+ struct SStringData { -+ std::string value; -+ }; -+ -+ struct SColorData { -+ CColor color; -+ }; -+ -+ struct SChoiceData { -+ int firstIndex = 0; -+ std::string choices; // comma-separated -+ }; -+ -+ struct SGradientData { -+ std::string gradient; -+ }; -+ -+ struct SVectorData { -+ Vector2D vec, min, max; -+ }; -+ -+ std::string value; // e.g. general:gaps_in -+ std::string description; -+ std::string specialCategory; // if value is special (e.g. device:abc) value will be abc and special device -+ bool specialKey = false; -+ eConfigOptionType type = CONFIG_OPTION_BOOL; -+ uint32_t flags = 0; // eConfigOptionFlags -+ -+ std::string jsonify() const; -+ -+ // -+ std::variant data; -+}; -+ - class CConfigManager { - public: - CConfigManager(); -@@ -115,6 +179,8 @@ class CConfigManager { - std::vector getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false); - std::vector getMatchingRules(PHLLS); - -+ const std::vector& getAllDescriptions(); -+ - std::unordered_map m_mAdditionalReservedAreas; - - std::unordered_map getAnimationConfig(); -diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp -index d91a1cec..78c8504a 100644 ---- a/src/debug/HyprCtl.cpp -+++ b/src/debug/HyprCtl.cpp -@@ -71,7 +71,7 @@ static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFor - - std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer m, eHyprCtlOutputFormat format) { - std::string result; -- if (!m->output || m->ID == -1ull) -+ if (!m->output || m->ID == -1) - return ""; - - if (format == eHyprCtlOutputFormat::FORMAT_JSON) { -@@ -155,19 +155,19 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { - result += "]"; - } else { - for (auto& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) { -- if (!m->output || m->ID == -1ull) -+ if (!m->output || m->ID == -1) - continue; - -- result += -- std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t" -- "special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t" -- "dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n", -- m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription, -- m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName), -- m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, -- (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, -- (m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, (int)(m->output->state ? m->output->state->state().adaptiveSync : false), -- m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format)); -+ result += std::format( -+ "Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t" -+ "special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t" -+ "dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: A {} H {}\n\tavailableModes: {}\n\n", -+ m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription, -+ m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName), -+ m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, -+ (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), -+ (int)m->dpmsStatus, (int)(m->output->state ? m->output->state->state().adaptiveSync : false), m->tearingState.activelyTearing, !m->m_bEnabled, -+ formatToString(m->output->state->state().drmFormat), formatToString(m->drmFormat), availableModesForOutput(m.get(), format)); - } - } - -@@ -1561,6 +1561,21 @@ std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) { - return lockedStr; - } - -+std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) { -+ std::string json = "{"; -+ const auto& DESCS = g_pConfigManager->getAllDescriptions(); -+ -+ for (const auto& d : DESCS) { -+ json += d.jsonify() + ",\n"; -+ } -+ -+ json.pop_back(); -+ json.pop_back(); -+ -+ json += "}\n"; -+ return json; -+} -+ - CHyprCtl::CHyprCtl() { - registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest}); - registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest}); -@@ -1581,6 +1596,7 @@ CHyprCtl::CHyprCtl() { - registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest}); - registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest}); - registerCommand(SHyprCtlCommand{"locked", true, getIsLocked}); -+ registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions}); - - registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest}); - registerCommand(SHyprCtlCommand{"reload", false, reloadRequest}); -diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp -index 889be8ea..fbd8cd71 100644 ---- a/src/debug/HyprDebugOverlay.cpp -+++ b/src/debug/HyprDebugOverlay.cpp -@@ -7,8 +7,8 @@ CHyprDebugOverlay::CHyprDebugOverlay() { - m_pTexture = makeShared(); - } - --void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) { -- m_dLastRenderTimes.push_back(µs / 1000.f); -+void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) { -+ m_dLastRenderTimes.push_back(durationUs / 1000.f); - - if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate) - m_dLastRenderTimes.pop_front(); -@@ -17,8 +17,8 @@ void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) { - m_pMonitor = pMonitor; - } - --void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) { -- m_dLastRenderTimesNoOverlay.push_back(µs / 1000.f); -+void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) { -+ m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f); - - if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate) - m_dLastRenderTimesNoOverlay.pop_front(); -@@ -188,12 +188,12 @@ int CHyprMonitorDebugOverlay::draw(int offset) { - return posY - offset; - } - --void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float µs) { -- m_mMonitorOverlays[pMonitor].renderData(pMonitor, µs); -+void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) { -+ m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs); - } - --void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) { -- m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, µs); -+void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) { -+ m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs); - } - - void CHyprDebugOverlay::frameData(CMonitor* pMonitor) { -diff --git a/src/debug/HyprDebugOverlay.hpp b/src/debug/HyprDebugOverlay.hpp -index a6063ee9..e7742b35 100644 ---- a/src/debug/HyprDebugOverlay.hpp -+++ b/src/debug/HyprDebugOverlay.hpp -@@ -13,8 +13,8 @@ class CHyprMonitorDebugOverlay { - public: - int draw(int offset); - -- void renderData(CMonitor* pMonitor, float µs); -- void renderDataNoOverlay(CMonitor* pMonitor, float µs); -+ void renderData(CMonitor* pMonitor, float durationUs); -+ void renderDataNoOverlay(CMonitor* pMonitor, float durationUs); - void frameData(CMonitor* pMonitor); - - private: -@@ -33,8 +33,8 @@ class CHyprDebugOverlay { - public: - CHyprDebugOverlay(); - void draw(); -- void renderData(CMonitor*, float µs); -- void renderDataNoOverlay(CMonitor*, float µs); -+ void renderData(CMonitor*, float durationUs); -+ void renderDataNoOverlay(CMonitor*, float durationUs); - void frameData(CMonitor*); - - private: -diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp -index 8fd448ef..c352fa74 100644 ---- a/src/desktop/LayerSurface.cpp -+++ b/src/desktop/LayerSurface.cpp -@@ -432,8 +432,8 @@ void CLayerSurface::startAnimation(bool in, bool instant) { - PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, - }; - -- float closest = std::numeric_limits::max(); -- int leader = force; -+ float closest = std::numeric_limits::max(); -+ size_t leader = force; - if (leader == -1) { - for (size_t i = 0; i < 4; ++i) { - float dist = MIDDLE.distance(edgePoints[i]); -diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp -index 056f66a8..84935b34 100644 ---- a/src/desktop/LayerSurface.hpp -+++ b/src/desktop/LayerSurface.hpp -@@ -42,7 +42,7 @@ class CLayerSurface { - bool mapped = false; - uint32_t layer = 0; - -- int monitorID = -1; -+ MONITORID monitorID = -1; - - bool fadingOut = false; - bool readyToDelete = false; -@@ -51,7 +51,7 @@ class CLayerSurface { - - bool forceBlur = false; - bool forceBlurPopups = false; -- int xray = -1; -+ int64_t xray = -1; - bool ignoreAlpha = false; - float ignoreAlphaValue = 0.f; - bool dimAround = false; -diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp -index 93c208cf..dcdcb573 100644 ---- a/src/desktop/Window.cpp -+++ b/src/desktop/Window.cpp -@@ -1243,7 +1243,7 @@ bool CWindow::isEffectiveInternalFSMode(const eFullscreenMode MODE) { - return (eFullscreenMode)std::bit_floor((uint8_t)m_sFullscreenState.internal) == MODE; - } - --int CWindow::workspaceID() { -+WORKSPACEID CWindow::workspaceID() { - return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace; - } - -diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp -index 11bf662a..2e5b54b1 100644 ---- a/src/desktop/Window.hpp -+++ b/src/desktop/Window.hpp -@@ -270,7 +270,7 @@ class CWindow { - bool m_bDraggingTiled = false; // for dragging around tiled windows - bool m_bWasMaximized = false; - sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE}; -- uint64_t m_iMonitorID = -1; -+ MONITORID m_iMonitorID = -1; - std::string m_szTitle = ""; - std::string m_szClass = ""; - std::string m_szInitialTitle = ""; -@@ -358,8 +358,8 @@ class CWindow { - bool m_bStayFocused = false; - - // for toplevel monitor events -- uint64_t m_iLastToplevelMonitorID = -1; -- uint64_t m_iLastSurfaceMonitorID = -1; -+ MONITORID m_iLastToplevelMonitorID = -1; -+ MONITORID m_iLastSurfaceMonitorID = -1; - - // for idle inhibiting windows - eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE; -@@ -421,7 +421,7 @@ class CWindow { - bool canBeTorn(); - void setSuspended(bool suspend); - bool visibleOnMonitor(CMonitor* pMonitor); -- int workspaceID(); -+ WORKSPACEID workspaceID(); - bool onSpecialWorkspace(); - void activate(bool force = false); - int surfacesCount(); -@@ -490,9 +490,9 @@ class CWindow { - - private: - // For hidden windows and stuff -- bool m_bHidden = false; -- bool m_bSuspended = false; -- int m_iLastWorkspace = WORKSPACE_INVALID; -+ bool m_bHidden = false; -+ bool m_bSuspended = false; -+ WORKSPACEID m_iLastWorkspace = WORKSPACE_INVALID; - }; - - inline bool valid(PHLWINDOW w) { -diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp -index a08f1804..d9ac7927 100644 ---- a/src/desktop/Workspace.cpp -+++ b/src/desktop/Workspace.cpp -@@ -5,13 +5,13 @@ - #include - using namespace Hyprutils::String; - --PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool special, bool isEmtpy) { -+PHLWORKSPACE CWorkspace::create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmtpy) { - PHLWORKSPACE workspace = makeShared(id, monitorID, name, special, isEmtpy); - workspace->init(workspace); - return workspace; - } - --CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special, bool isEmtpy) { -+CWorkspace::CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmtpy) { - m_iMonitorID = monitorID; - m_iID = id; - m_szName = name; -@@ -190,7 +190,7 @@ void CWorkspace::setActive(bool on) { - ; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40 - } - --void CWorkspace::moveToMonitor(const int& id) { -+void CWorkspace::moveToMonitor(const MONITORID& id) { - ; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40 - } - -@@ -275,7 +275,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { - i = std::min(NEXTSPACE, std::string::npos - 1); - - if (cur == 'r') { -- int from = 0, to = 0; -+ WORKSPACEID from = 0, to = 0; - if (!prop.starts_with("r[") || !prop.ends_with("]")) { - Debug::log(LOG, "Invalid selector {}", selector); - return false; -@@ -365,7 +365,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { - } - - if (cur == 'w') { -- int from = 0, to = 0; -+ WORKSPACEID from = 0, to = 0; - if (!prop.starts_with("w[") || !prop.ends_with("]")) { - Debug::log(LOG, "Invalid selector {}", selector); - return false; -@@ -446,7 +446,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { - return false; - } - -- int count; -+ WORKSPACEID count; - if (wantsCountGroup) - count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), - wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); -@@ -506,7 +506,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { - void CWorkspace::markInert() { - m_bInert = true; - m_iID = WORKSPACE_INVALID; -- m_iMonitorID = -1; -+ m_iMonitorID = MONITOR_INVALID; - m_bVisible = false; - } - -diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp -index 3e9ac8a8..9cacb0cc 100644 ---- a/src/desktop/Workspace.hpp -+++ b/src/desktop/Workspace.hpp -@@ -17,16 +17,16 @@ class CWindow; - - class CWorkspace { - public: -- static PHLWORKSPACE create(int id, int monitorID, std::string name, bool special = false, bool isEmtpy = true); -+ static PHLWORKSPACE create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmtpy = true); - // use create() don't use this -- CWorkspace(int id, int monitorID, std::string name, bool special = false, bool isEmpty = true); -+ CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true); - ~CWorkspace(); - - // Workspaces ID-based have IDs > 0 - // and workspaces name-based have IDs starting with -1337 -- int m_iID = -1; -+ WORKSPACEID m_iID = WORKSPACE_INVALID; - std::string m_szName = ""; -- uint64_t m_iMonitorID = -1; -+ MONITORID m_iMonitorID = MONITOR_INVALID; - // Previous workspace ID and name is stored during a workspace change, allowing travel - // to the previous workspace. - SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor; -@@ -67,7 +67,7 @@ class CWorkspace { - void startAnim(bool in, bool left, bool instant = false); - void setActive(bool on); - -- void moveToMonitor(const int&); -+ void moveToMonitor(const MONITORID&); - - PHLWINDOW getLastFocusedWindow(); - void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); -diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp -index 5d29a3b7..2eb7038f 100644 ---- a/src/events/Windows.cpp -+++ b/src/events/Windows.cpp -@@ -148,7 +148,7 @@ void Events::listener_mapWindow(void* owner, void* data) { - PWINDOW->m_iMonitorID = PMONITOR->ID; - } else { - if (isNumber(MONITORSTR)) { -- const long int MONITOR = std::stoi(MONITORSTR); -+ const MONITORID MONITOR = std::stoi(MONITORSTR); - if (!g_pCompositor->getMonitorFromID(MONITOR)) - PWINDOW->m_iMonitorID = 0; - else -diff --git a/src/helpers/Color.cpp b/src/helpers/Color.cpp -index 67526dc7..f9a207bb 100644 ---- a/src/helpers/Color.cpp -+++ b/src/helpers/Color.cpp -@@ -21,6 +21,6 @@ CColor::CColor(uint64_t hex) { - this->a = ALPHA(hex); - } - --uint32_t CColor::getAsHex() { -+uint32_t CColor::getAsHex() const { - return (uint32_t)(a * 255.f) * 0x1000000 + (uint32_t)(r * 255.f) * 0x10000 + (uint32_t)(g * 255.f) * 0x100 + (uint32_t)(b * 255.f) * 0x1; - } -\ No newline at end of file -diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp -index 7ec55b0d..8abfe748 100644 ---- a/src/helpers/Color.hpp -+++ b/src/helpers/Color.hpp -@@ -10,7 +10,7 @@ class CColor { - - float r = 0, g = 0, b = 0, a = 1.f; - -- uint32_t getAsHex(); -+ uint32_t getAsHex() const; - - CColor operator-(const CColor& c2) const { - return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a); -diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp -index 53c0dc13..86f24e3a 100644 ---- a/src/helpers/MiscFunctions.cpp -+++ b/src/helpers/MiscFunctions.cpp -@@ -249,7 +249,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - return {WORKSPACE_INVALID}; - } - -- std::set invalidWSes; -+ std::set invalidWSes; - if (same_mon) { - for (auto& rule : g_pConfigManager->getAllWorkspaceRules()) { - const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor); -@@ -258,8 +258,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - } - } - -- int id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0; -- while (++id < INT_MAX) { -+ WORKSPACEID id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0; -+ while (++id < LONG_MAX) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id); - if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) { - result.id = id; -@@ -296,9 +296,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - - result.id = (int)PLUSMINUSRESULT.value(); - -- int remains = (int)result.id; -+ WORKSPACEID remains = result.id; - -- std::set invalidWSes; -+ std::set invalidWSes; - - // Collect all the workspaces we can't jump to. - for (auto& ws : g_pCompositor->m_vWorkspaces) { -@@ -318,7 +318,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - } - - // Prepare all named workspaces in case when we need them -- std::vector namedWSes; -+ std::vector namedWSes; - for (auto& ws : g_pCompositor->m_vWorkspaces) { - if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || ws->m_iID >= 0) - continue; -@@ -347,18 +347,18 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - } else { - - // Just take a blind guess at where we'll probably end up -- int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; -- int predictedWSID = activeWSID + remains; -- int remainingWSes = 0; -- char walkDir = in[1]; -+ WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; -+ WORKSPACEID predictedWSID = activeWSID + remains; -+ int remainingWSes = 0; -+ char walkDir = in[1]; - - // sanitize. 0 means invalid oob in - -- predictedWSID = std::max(predictedWSID, 0); -+ predictedWSID = std::max(predictedWSID, 0L); - - // Count how many invalidWSes are in between (how bad the prediction was) -- int beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID; -- int endID = in[1] == '+' ? predictedWSID : activeWSID; -- auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= -+ WORKSPACEID beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID; -+ WORKSPACEID endID = in[1] == '+' ? predictedWSID : activeWSID; -+ auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= - for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) { - remainingWSes++; - } -@@ -367,7 +367,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - if (activeWSID < 0) { - // Behaviour similar to 'm' - // Find current -- int currentItem = -1; -+ size_t currentItem = -1; - for (size_t i = 0; i < namedWSes.size(); i++) { - if (namedWSes[i] == activeWSID) { - currentItem = i; -@@ -376,14 +376,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - } - - currentItem += remains; -- currentItem = std::max(currentItem, 0); -- if (currentItem >= (int)namedWSes.size()) { -+ currentItem = std::max(currentItem, 0UL); -+ if (currentItem >= namedWSes.size()) { - // At the seam between namedWSes and normal WSes. Behave like r+[diff] at imaginary ws 0 -- int diff = currentItem - (namedWSes.size() - 1); -- predictedWSID = diff; -- int beginID = 1; -- int endID = predictedWSID; -- auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= -+ size_t diff = currentItem - (namedWSes.size() - 1); -+ predictedWSID = diff; -+ WORKSPACEID beginID = 1; -+ WORKSPACEID endID = predictedWSID; -+ auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= - for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) { - remainingWSes++; - } -@@ -397,10 +397,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - - // Go in the search direction for remainingWSes - // The performance impact is directly proportional to the number of open and bound workspaces -- int finalWSID = predictedWSID; -+ WORKSPACEID finalWSID = predictedWSID; - if (walkDir == '-') { -- int beginID = finalWSID; -- int curID = finalWSID; -+ WORKSPACEID beginID = finalWSID; -+ WORKSPACEID curID = finalWSID; - while (--curID > 0 && remainingWSes > 0) { - if (!invalidWSes.contains(curID)) { - remainingWSes--; -@@ -411,9 +411,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - if (namedWSes.size()) { - // Go to the named workspaces - // Need remainingWSes more -- int namedWSIdx = namedWSes.size() - remainingWSes; -+ auto namedWSIdx = namedWSes.size() - remainingWSes; - // Sanitze -- namedWSIdx = std::clamp(namedWSIdx, 0, (int)namedWSes.size() - 1); -+ namedWSIdx = std::clamp(namedWSIdx, 0UL, namedWSes.size() - 1); - finalWSID = namedWSes[namedWSIdx]; - } else { - // Couldn't find valid workspace in negative direction, search last first one back up positive direction -@@ -425,7 +425,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - } - } - if (walkDir == '+') { -- int curID = finalWSID; -+ WORKSPACEID curID = finalWSID; - while (++curID < INT32_MAX && remainingWSes > 0) { - if (!invalidWSes.contains(curID)) { - remainingWSes--; -@@ -460,9 +460,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - result.id = (int)PLUSMINUSRESULT.value(); - - // result now has +/- what we should move on mon -- int remains = (int)result.id; -+ int remains = (int)result.id; - -- std::vector validWSes; -+ std::vector validWSes; - for (auto& ws : g_pCompositor->m_vWorkspaces) { - if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors)) - continue; -@@ -472,7 +472,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - - std::sort(validWSes.begin(), validWSes.end()); - -- int currentItem = -1; -+ ssize_t currentItem = -1; - - if (absolute) { - // 1-index -@@ -481,7 +481,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - // clamp - if (currentItem < 0) { - currentItem = 0; -- } else if (currentItem >= (int)validWSes.size()) { -+ } else if (currentItem >= (ssize_t)validWSes.size()) { - currentItem = validWSes.size() - 1; - } - } else { -@@ -489,8 +489,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size(); - - // get the current item -- int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; -- for (size_t i = 0; i < validWSes.size(); i++) { -+ WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; -+ for (ssize_t i = 0; i < (ssize_t)validWSes.size(); i++) { - if (validWSes[i] == activeWSID) { - currentItem = i; - break; -@@ -501,7 +501,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { - currentItem += remains; - - // sanitize -- if (currentItem >= (int)validWSes.size()) { -+ if (currentItem >= (ssize_t)validWSes.size()) { - currentItem = currentItem % validWSes.size(); - } else if (currentItem < 0) { - currentItem = validWSes.size() + currentItem; -@@ -547,9 +547,9 @@ std::optional cleanCmdForWorkspace(const std::string& inWorkspaceNa - const std::string workspaceRule = "workspace " + inWorkspaceName; - - if (cmd[0] == '[') { -- const int closingBracketIdx = cmd.find_last_of(']'); -- auto tmpRules = cmd.substr(1, closingBracketIdx - 1); -- cmd = cmd.substr(closingBracketIdx + 1); -+ const auto closingBracketIdx = cmd.find_last_of(']'); -+ auto tmpRules = cmd.substr(1, closingBracketIdx - 1); -+ cmd = cmd.substr(closingBracketIdx + 1); - - auto rulesList = CVarList(tmpRules, 0, ';'); - -@@ -785,13 +785,13 @@ std::vector getBacktrace() { - - #ifdef HAS_EXECINFO - void* bt[1024]; -- size_t btSize; -+ int btSize; - char** btSymbols; - - btSize = backtrace(bt, 1024); - btSymbols = backtrace_symbols(bt, btSize); - -- for (size_t i = 0; i < btSize; ++i) { -+ for (auto i = 0; i < btSize; ++i) { - callstack.emplace_back(SCallstackFrameInfo{bt[i], std::string{btSymbols[i]}}); - } - #else -diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp -index 49e3bced..8b2ea0d1 100644 ---- a/src/helpers/MiscFunctions.hpp -+++ b/src/helpers/MiscFunctions.hpp -@@ -6,6 +6,8 @@ - #include "math/Math.hpp" - #include - #include -+#include "../SharedDefs.hpp" -+#include "../macros.hpp" - - struct SCallstackFrameInfo { - void* adr = nullptr; -@@ -13,7 +15,7 @@ struct SCallstackFrameInfo { - }; - - struct SWorkspaceIDName { -- int id = -1; -+ WORKSPACEID id = WORKSPACE_INVALID; - std::string name; - }; - -diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp -index 8f23c462..9542d2c4 100644 ---- a/src/helpers/Monitor.cpp -+++ b/src/helpers/Monitor.cpp -@@ -389,8 +389,8 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const { - } - } - --int CMonitor::findAvailableDefaultWS() { -- for (size_t i = 1; i < INT32_MAX; ++i) { -+WORKSPACEID CMonitor::findAvailableDefaultWS() { -+ for (WORKSPACEID i = 1; i < LONG_MAX; ++i) { - if (g_pCompositor->getWorkspaceByID(i)) - continue; - -@@ -400,7 +400,7 @@ int CMonitor::findAvailableDefaultWS() { - return i; - } - -- return INT32_MAX; // shouldn't be reachable -+ return LONG_MAX; // shouldn't be reachable - } - - void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { -@@ -638,7 +638,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo - g_pCompositor->updateFullscreenFadeOnWorkspace(activeSpecialWorkspace); - } - --void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) { -+void CMonitor::changeWorkspace(const WORKSPACEID& id, bool internal, bool noMouseMove, bool noFocus) { - changeWorkspace(g_pCompositor->getWorkspaceByID(id), internal, noMouseMove, noFocus); - } - -@@ -745,7 +745,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { - g_pCompositor->updateSuspendedStates(); - } - --void CMonitor::setSpecialWorkspace(const int& id) { -+void CMonitor::setSpecialWorkspace(const WORKSPACEID& id) { - setSpecialWorkspace(g_pCompositor->getWorkspaceByID(id)); - } - -@@ -766,11 +766,11 @@ void CMonitor::updateMatrix() { - } - } - --int64_t CMonitor::activeWorkspaceID() { -+WORKSPACEID CMonitor::activeWorkspaceID() { - return activeWorkspace ? activeWorkspace->m_iID : 0; - } - --int64_t CMonitor::activeSpecialWorkspaceID() { -+WORKSPACEID CMonitor::activeSpecialWorkspaceID() { - return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0; - } - -@@ -946,7 +946,7 @@ bool CMonitorState::updateSwapchain() { - Debug::log(WARN, "updateSwapchain: No mode?"); - return true; - } -- options.format = STATE.drmFormat; -+ options.format = m_pOwner->drmFormat; - options.scanout = true; - options.length = 2; - options.size = MODE->pixelSize; -diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp -index fbe26f67..dcfcb63b 100644 ---- a/src/helpers/Monitor.hpp -+++ b/src/helpers/Monitor.hpp -@@ -70,7 +70,7 @@ class CMonitor { - - bool primary = false; - -- uint64_t ID = -1; -+ MONITORID ID = MONITOR_INVALID; - PHLWORKSPACE activeWorkspace = nullptr; - PHLWORKSPACE activeSpecialWorkspace = nullptr; - float setScale = 1; // scale set by cfg -@@ -100,6 +100,7 @@ class CMonitor { - std::optional forceSize; - SP currentMode; - SP cursorSwapchain; -+ uint32_t drmFormat = DRM_FORMAT_INVALID; - - bool dpmsStatus = true; - bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. -@@ -155,31 +156,31 @@ class CMonitor { - std::array, 4> m_aLayerSurfaceLayers; - - // methods -- void onConnect(bool noRule); -- void onDisconnect(bool destroy = false); -- void addDamage(const pixman_region32_t* rg); -- void addDamage(const CRegion* rg); -- void addDamage(const CBox* box); -- bool shouldSkipScheduleFrameOnMouseEvent(); -- void setMirror(const std::string&); -- bool isMirror(); -- bool matchesStaticSelector(const std::string& selector) const; -- float getDefaultScale(); -- void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false); -- void changeWorkspace(const int& id, bool internal = false, bool noMouseMove = false, bool noFocus = false); -- void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace); -- void setSpecialWorkspace(const int& id); -- void moveTo(const Vector2D& pos); -- Vector2D middle(); -- void updateMatrix(); -- int64_t activeWorkspaceID(); -- int64_t activeSpecialWorkspaceID(); -- CBox logicalBox(); -- void scheduleDone(); -- bool attemptDirectScanout(); -- -- bool m_bEnabled = false; -- bool m_bRenderingInitPassed = false; -+ void onConnect(bool noRule); -+ void onDisconnect(bool destroy = false); -+ void addDamage(const pixman_region32_t* rg); -+ void addDamage(const CRegion* rg); -+ void addDamage(const CBox* box); -+ bool shouldSkipScheduleFrameOnMouseEvent(); -+ void setMirror(const std::string&); -+ bool isMirror(); -+ bool matchesStaticSelector(const std::string& selector) const; -+ float getDefaultScale(); -+ void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false); -+ void changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false); -+ void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace); -+ void setSpecialWorkspace(const WORKSPACEID& id); -+ void moveTo(const Vector2D& pos); -+ Vector2D middle(); -+ void updateMatrix(); -+ WORKSPACEID activeWorkspaceID(); -+ WORKSPACEID activeSpecialWorkspaceID(); -+ CBox logicalBox(); -+ void scheduleDone(); -+ bool attemptDirectScanout(); -+ -+ bool m_bEnabled = false; -+ bool m_bRenderingInitPassed = false; - - // For the list lookup - -@@ -189,7 +190,7 @@ class CMonitor { - - private: - void setupDefaultWS(const SMonitorRule&); -- int findAvailableDefaultWS(); -+ WORKSPACEID findAvailableDefaultWS(); - - wl_event_source* doneSource = nullptr; - -diff --git a/src/helpers/SdDaemon.cpp b/src/helpers/SdDaemon.cpp -index 25e0ca3b..48c23e6b 100644 ---- a/src/helpers/SdDaemon.cpp -+++ b/src/helpers/SdDaemon.cpp -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - namespace Systemd { - int SdBooted(void) { -diff --git a/src/helpers/Timer.cpp b/src/helpers/Timer.cpp -index ec530df4..7b1726df 100644 ---- a/src/helpers/Timer.cpp -+++ b/src/helpers/Timer.cpp -@@ -8,7 +8,7 @@ std::chrono::steady_clock::duration CTimer::getDuration() { - return std::chrono::steady_clock::now() - m_tpLastReset; - } - --int CTimer::getMillis() { -+long CTimer::getMillis() { - return std::chrono::duration_cast(getDuration()).count(); - } - -diff --git a/src/helpers/Timer.hpp b/src/helpers/Timer.hpp -index a6d1aeed..827e7625 100644 ---- a/src/helpers/Timer.hpp -+++ b/src/helpers/Timer.hpp -@@ -6,7 +6,7 @@ class CTimer { - public: - void reset(); - float getSeconds(); -- int getMillis(); -+ long getMillis(); - const std::chrono::steady_clock::time_point& chrono() const; - - private: -diff --git a/src/helpers/Watchdog.cpp b/src/helpers/Watchdog.cpp -index b9f654da..c7ff648b 100644 ---- a/src/helpers/Watchdog.cpp -+++ b/src/helpers/Watchdog.cpp -@@ -18,15 +18,14 @@ CWatchdog::CWatchdog() { - m_pWatchdog = std::make_unique([this] { - static auto PTIMEOUT = CConfigValue("debug:watchdog_timeout"); - -- while (1337) { -- std::unique_lock lk(m_mWatchdogMutex); -+ m_bWatchdogInitialized = true; -+ while (!m_bExitThread) { -+ std::unique_lock lk(m_mWatchdogMutex); - - if (!m_bWillWatch) -- m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified; }); -- else { -- if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified; }) == false) -- pthread_kill(m_iMainThreadPID, SIGUSR1); -- } -+ m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified || m_bExitThread; }); -+ else if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified || m_bExitThread; }) == false) -+ pthread_kill(m_iMainThreadPID, SIGUSR1); - - if (m_bExitThread) - break; -diff --git a/src/helpers/Watchdog.hpp b/src/helpers/Watchdog.hpp -index 7bb499d6..b16cb518 100644 ---- a/src/helpers/Watchdog.hpp -+++ b/src/helpers/Watchdog.hpp -@@ -11,21 +11,23 @@ class CWatchdog { - CWatchdog(); - ~CWatchdog(); - -- void startWatching(); -- void endWatching(); -+ void startWatching(); -+ void endWatching(); -+ -+ std::atomic m_bWatchdogInitialized{false}; - - private: - std::chrono::high_resolution_clock::time_point m_tTriggered; - - pthread_t m_iMainThreadPID = 0; - -- bool m_bWatching = false; -- bool m_bWillWatch = false; -+ std::atomic m_bWatching = false; -+ std::atomic m_bWillWatch = false; - - std::unique_ptr m_pWatchdog; - std::mutex m_mWatchdogMutex; -- bool m_bNotified = false; -- bool m_bExitThread = false; -+ std::atomic m_bNotified = false; -+ std::atomic m_bExitThread = false; - std::condition_variable m_cvWatchdogCondition; - }; - -diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp -index f287056f..20085ff7 100644 ---- a/src/layout/DwindleLayout.cpp -+++ b/src/layout/DwindleLayout.cpp -@@ -47,7 +47,7 @@ void SDwindleNodeData::getAllChildrenRecursive(std::deque* pD - } - } - --int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) { -+int CHyprDwindleLayout::getNodesOnWorkspace(const WORKSPACEID& id) { - int no = 0; - for (auto& n : m_lDwindleNodesData) { - if (n.workspaceID == id && n.valid) -@@ -56,7 +56,7 @@ int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) { - return no; - } - --SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const int& id) { -+SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const WORKSPACEID& id) { - for (auto& n : m_lDwindleNodesData) { - if (n.workspaceID == id && validMapped(n.pWindow)) - return &n; -@@ -64,7 +64,7 @@ SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const int& id) { - return nullptr; - } - --SDwindleNodeData* CHyprDwindleLayout::getClosestNodeOnWorkspace(const int& id, const Vector2D& point) { -+SDwindleNodeData* CHyprDwindleLayout::getClosestNodeOnWorkspace(const WORKSPACEID& id, const Vector2D& point) { - SDwindleNodeData* res = nullptr; - double distClosest = -1; - for (auto& n : m_lDwindleNodesData) { -@@ -88,7 +88,7 @@ SDwindleNodeData* CHyprDwindleLayout::getNodeFromWindow(PHLWINDOW pWindow) { - return nullptr; - } - --SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const int& id) { -+SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const WORKSPACEID& id) { - for (auto& n : m_lDwindleNodesData) { - if (!n.pParent && n.workspaceID == id) - return &n; -@@ -246,6 +246,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for - - g_pHyprRenderer->damageWindow(PWINDOW); - } -+ -+ PWINDOW->updateWindowDecos(); - } - - void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection direction) { -@@ -535,7 +537,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(PHLWINDOW pWindow) { - m_lDwindleNodesData.remove(*PNODE); - } - --void CHyprDwindleLayout::recalculateMonitor(const int& monid) { -+void CHyprDwindleLayout::recalculateMonitor(const MONITORID& monid) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); - - if (!PMONITOR || !PMONITOR->activeWorkspace) -@@ -872,7 +874,7 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir, - return; - - const auto PNODE = getNodeFromWindow(pWindow); -- const int originalWorkspaceID = pWindow->workspaceID(); -+ const auto originalWorkspaceID = pWindow->workspaceID(); - const Vector2D originalPos = pWindow->middle(); - - if (!PNODE) -diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp -index f638f6a2..bbd511c2 100644 ---- a/src/layout/DwindleLayout.hpp -+++ b/src/layout/DwindleLayout.hpp -@@ -24,7 +24,7 @@ struct SDwindleNodeData { - - CBox box = {0}; - -- int workspaceID = -1; -+ WORKSPACEID workspaceID = WORKSPACE_INVALID; - - float splitRatio = 1.f; - -@@ -48,7 +48,7 @@ class CHyprDwindleLayout : public IHyprLayout { - virtual void onWindowCreatedTiling(PHLWINDOW, eDirection direction = DIRECTION_DEFAULT); - virtual void onWindowRemovedTiling(PHLWINDOW); - virtual bool isWindowTiled(PHLWINDOW); -- virtual void recalculateMonitor(const int&); -+ virtual void recalculateMonitor(const MONITORID&); - virtual void recalculateWindow(PHLWINDOW); - virtual void onBeginDragWindow(); - virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, PHLWINDOW pWindow = nullptr); -@@ -77,13 +77,13 @@ class CHyprDwindleLayout : public IHyprLayout { - - std::optional m_vOverrideFocalPoint; // for onWindowCreatedTiling. - -- int getNodesOnWorkspace(const int&); -+ int getNodesOnWorkspace(const WORKSPACEID&); - void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); - void calculateWorkspace(const PHLWORKSPACE& pWorkspace); - SDwindleNodeData* getNodeFromWindow(PHLWINDOW); -- SDwindleNodeData* getFirstNodeOnWorkspace(const int&); -- SDwindleNodeData* getClosestNodeOnWorkspace(const int&, const Vector2D&); -- SDwindleNodeData* getMasterNodeOnWorkspace(const int&); -+ SDwindleNodeData* getFirstNodeOnWorkspace(const WORKSPACEID&); -+ SDwindleNodeData* getClosestNodeOnWorkspace(const WORKSPACEID&, const Vector2D&); -+ SDwindleNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&); - - void toggleSplit(PHLWINDOW); - void swapSplit(PHLWINDOW); -diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp -index 4b1b59e3..7e0d5704 100644 ---- a/src/layout/IHyprLayout.hpp -+++ b/src/layout/IHyprLayout.hpp -@@ -63,7 +63,7 @@ class IHyprLayout { - Called when the monitor requires a layout recalculation - this usually means reserved area changes - */ -- virtual void recalculateMonitor(const int&) = 0; -+ virtual void recalculateMonitor(const MONITORID&) = 0; - - /* - Called when the compositor requests a window -diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp -index be00168f..e0b48e98 100644 ---- a/src/layout/MasterLayout.cpp -+++ b/src/layout/MasterLayout.cpp -@@ -14,7 +14,7 @@ SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) { - return nullptr; - } - --int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) { -+int CHyprMasterLayout::getNodesOnWorkspace(const WORKSPACEID& ws) { - int no = 0; - for (auto& n : m_lMasterNodesData) { - if (n.workspaceID == ws) -@@ -24,7 +24,7 @@ int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) { - return no; - } - --int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) { -+int CHyprMasterLayout::getMastersOnWorkspace(const WORKSPACEID& ws) { - int no = 0; - for (auto& n : m_lMasterNodesData) { - if (n.workspaceID == ws && n.isMaster) -@@ -34,7 +34,7 @@ int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) { - return no; - } - --SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) { -+SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const WORKSPACEID& ws) { - for (auto& n : m_lMasterWorkspacesData) { - if (n.workspaceID == ws) - return &n; -@@ -63,7 +63,7 @@ std::string CHyprMasterLayout::getLayoutName() { - return "Master"; - } - --SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) { -+SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const WORKSPACEID& ws) { - for (auto& n : m_lMasterNodesData) { - if (n.isMaster && n.workspaceID == ws) - return &n; -@@ -304,7 +304,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) { - recalculateMonitor(pWindow->m_iMonitorID); - } - --void CHyprMasterLayout::recalculateMonitor(const int& monid) { -+void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); - - if (!PMONITOR || !PMONITOR->activeWorkspace) -@@ -732,6 +732,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { - - g_pHyprRenderer->damageWindow(PWINDOW); - } -+ -+ PWINDOW->updateWindowDecos(); - } - - bool CHyprMasterLayout::isWindowTiled(PHLWINDOW pWindow) { -diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp -index fdb916e5..b72be74f 100644 ---- a/src/layout/MasterLayout.hpp -+++ b/src/layout/MasterLayout.hpp -@@ -30,7 +30,7 @@ struct SMasterNodeData { - - float percSize = 1.f; // size multiplier for resizing children - -- int workspaceID = -1; -+ WORKSPACEID workspaceID = WORKSPACE_INVALID; - - bool ignoreFullscreenChecks = false; - -@@ -41,7 +41,7 @@ struct SMasterNodeData { - }; - - struct SMasterWorkspaceData { -- int workspaceID = -1; -+ WORKSPACEID workspaceID = WORKSPACE_INVALID; - eOrientation orientation = ORIENTATION_LEFT; - - // -@@ -55,7 +55,7 @@ class CHyprMasterLayout : public IHyprLayout { - virtual void onWindowCreatedTiling(PHLWINDOW, eDirection direction = DIRECTION_DEFAULT); - virtual void onWindowRemovedTiling(PHLWINDOW); - virtual bool isWindowTiled(PHLWINDOW); -- virtual void recalculateMonitor(const int&); -+ virtual void recalculateMonitor(const MONITORID&); - virtual void recalculateWindow(PHLWINDOW); - virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, PHLWINDOW pWindow = nullptr); - virtual void fullscreenRequestForWindow(PHLWINDOW pWindow, const eFullscreenMode CURRENT_EFFECTIVE_MODE, const eFullscreenMode EFFECTIVE_MODE); -@@ -81,14 +81,14 @@ class CHyprMasterLayout : public IHyprLayout { - void buildOrientationCycleVectorFromEOperation(std::vector& cycle); - void runOrientationCycle(SLayoutMessageHeader& header, CVarList* vars, int next); - eOrientation getDynamicOrientation(PHLWORKSPACE); -- int getNodesOnWorkspace(const int&); -+ int getNodesOnWorkspace(const WORKSPACEID&); - void applyNodeDataToWindow(SMasterNodeData*); - SMasterNodeData* getNodeFromWindow(PHLWINDOW); -- SMasterNodeData* getMasterNodeOnWorkspace(const int&); -- SMasterWorkspaceData* getMasterWorkspaceData(const int&); -+ SMasterNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&); -+ SMasterWorkspaceData* getMasterWorkspaceData(const WORKSPACEID&); - void calculateWorkspace(PHLWORKSPACE); - PHLWINDOW getNextWindow(PHLWINDOW, bool); -- int getMastersOnWorkspace(const int&); -+ int getMastersOnWorkspace(const WORKSPACEID&); - - friend struct SMasterNodeData; - friend struct SMasterWorkspaceData; -diff --git a/src/macros.hpp b/src/macros.hpp -index b2adb036..44014085 100644 ---- a/src/macros.hpp -+++ b/src/macros.hpp -@@ -27,6 +27,8 @@ - #define WORKSPACE_INVALID -1L - #define WORKSPACE_NOT_CHANGED -101 - -+#define MONITOR_INVALID -1L -+ - #define LISTENER(name) \ - void listener_##name(wl_listener*, void*); \ - inline wl_listener listen_##name = {.notify = listener_##name} -diff --git a/src/main.cpp b/src/main.cpp -index e85b0a22..820a248c 100644 ---- a/src/main.cpp -+++ b/src/main.cpp -@@ -36,7 +36,6 @@ int main(int argc, char** argv) { - setenv("XDG_BACKEND", "wayland", 1); - setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1); - setenv("MOZ_ENABLE_WAYLAND", "1", 1); -- setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1); - - // parse some args - std::string configPath; -diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp -index 3f3a25f6..1c047f85 100644 ---- a/src/managers/CursorManager.cpp -+++ b/src/managers/CursorManager.cpp -@@ -102,7 +102,7 @@ CCursorManager::CCursorManager() { - - // since we fallback to xcursor always load it on startup. otherwise we end up with a empty theme if hyprcursor is enabled in the config - // and then later is disabled. -- m_pXcursor->loadTheme(getenv("XCURSOR_THEME") ? getenv("XCURSOR_THEME") : "default", m_iSize * std::ceil(m_fCursorScale)); -+ m_pXcursor->loadTheme(getenv("XCURSOR_THEME") ? getenv("XCURSOR_THEME") : "default", m_iSize, m_fCursorScale); - - m_pAnimationTimer = makeShared(std::nullopt, cursorAnimTimer, this); - g_pEventLoopManager->addTimer(m_pAnimationTimer); -@@ -163,7 +163,7 @@ void CCursorManager::setCursorFromName(const std::string& name) { - auto setXCursor = [this](auto const& name) { - float scale = std::ceil(m_fCursorScale); - -- auto xcursor = m_pXcursor->getShape(name, m_iSize * scale); -+ auto xcursor = m_pXcursor->getShape(name, m_iSize, m_fCursorScale); - auto& icon = xcursor->images.front(); - auto buf = makeShared((uint8_t*)icon.pixels.data(), icon.size, icon.hotspot); - setCursorBuffer(buf, icon.hotspot / scale, scale); -@@ -277,7 +277,7 @@ void CCursorManager::setXWaylandCursor() { - g_pXWayland->setCursor(cairo_image_surface_get_data(CURSOR.surface), cairo_image_surface_get_stride(CURSOR.surface), {CURSOR.size, CURSOR.size}, - {CURSOR.hotspotX, CURSOR.hotspotY}); - else { -- auto xcursor = m_pXcursor->getShape("left_ptr", m_iSize * std::ceil(m_fCursorScale)); -+ auto xcursor = m_pXcursor->getShape("left_ptr", m_iSize, 1); - auto& icon = xcursor->images.front(); - - g_pXWayland->setCursor((uint8_t*)icon.pixels.data(), icon.size.x * 4, icon.size, icon.hotspot); -@@ -329,12 +329,16 @@ bool CCursorManager::changeTheme(const std::string& name, const int size) { - m_pHyprcursor = std::make_unique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options); - if (!m_pHyprcursor->valid()) { - Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to XCursor.", m_szTheme); -- m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize); -+ m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale); - } - } else -- m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize); -+ m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale); - - updateTheme(); - - return true; --} -\ No newline at end of file -+} -+ -+void CCursorManager::syncGsettings() { -+ m_pXcursor->syncGsettings(); -+} -diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp -index ceb4816b..796ab10e 100644 ---- a/src/managers/CursorManager.hpp -+++ b/src/managers/CursorManager.hpp -@@ -53,6 +53,7 @@ class CCursorManager { - void updateTheme(); - SCursorImageData dataFor(const std::string& name); // for xwayland - void setXWaylandCursor(); -+ void syncGsettings(); - - void tickAnimatedCursor(); - -@@ -75,4 +76,4 @@ class CCursorManager { - Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData; - }; - --inline std::unique_ptr g_pCursorManager; -\ No newline at end of file -+inline std::unique_ptr g_pCursorManager; -diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp -index 75c98e2a..079a6b68 100644 ---- a/src/managers/EventManager.cpp -+++ b/src/managers/EventManager.cpp -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - CEventManager::CEventManager() { - m_iSocketFD = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); -diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp -index c7b93730..38593497 100644 ---- a/src/managers/KeybindManager.cpp -+++ b/src/managers/KeybindManager.cpp -@@ -180,6 +180,9 @@ uint32_t CKeybindManager::stringToModMask(std::string mods) { - } - - uint32_t CKeybindManager::keycodeToModifier(xkb_keycode_t keycode) { -+ if (keycode == 0) -+ return 0; -+ - switch (keycode - 8) { - case KEY_LEFTMETA: return HL_MODIFIER_META; - case KEY_RIGHTMETA: return HL_MODIFIER_META; -@@ -1163,6 +1166,8 @@ void CKeybindManager::fullscreenStateActive(std::string args) { - if (!PWINDOW) - return; - -+ PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_SET_PROP); -+ - int internalMode, clientMode; - try { - internalMode = std::stoi(ARGS[0]); -@@ -1174,26 +1179,16 @@ void CKeybindManager::fullscreenStateActive(std::string args) { - const sFullscreenState STATE = sFullscreenState{.internal = (internalMode != -1 ? (eFullscreenMode)internalMode : PWINDOW->m_sFullscreenState.internal), - .client = (clientMode != -1 ? (eFullscreenMode)clientMode : PWINDOW->m_sFullscreenState.client)}; - -- if (internalMode != -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal && PWINDOW->m_sFullscreenState.client == STATE.client) { -+ if (internalMode != -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal && PWINDOW->m_sFullscreenState.client == STATE.client) - g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = FSMODE_NONE, .client = FSMODE_NONE}); -- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); -- return; -- } -- -- if (internalMode != -1 && clientMode == -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal) { -- g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.client, .client = PWINDOW->m_sFullscreenState.client}); -- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); -- return; -- } -- -- if (internalMode == -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.client == STATE.client) { -- g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.internal, .client = PWINDOW->m_sFullscreenState.internal}); -- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); -- return; -- } -+ else if (internalMode != -1 && clientMode == -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal) -+ g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = FSMODE_NONE, .client = PWINDOW->m_sFullscreenState.client}); -+ else if (internalMode == -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.client == STATE.client) -+ g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.internal, .client = FSMODE_NONE}); -+ else -+ g_pCompositor->setWindowFullscreenState(PWINDOW, STATE); - -- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_SET_PROP); -- g_pCompositor->setWindowFullscreenState(PWINDOW, STATE); -+ PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(PWINDOW->m_sFullscreenState.internal == PWINDOW->m_sFullscreenState.client, PRIORITY_SET_PROP); - } - - void CKeybindManager::moveActiveToWorkspace(std::string args) { -@@ -1738,7 +1733,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { - return; - } - -- const int WORKSPACEID = getWorkspaceIDNameFromString(workspace).id; -+ const auto WORKSPACEID = getWorkspaceIDNameFromString(workspace).id; - - if (WORKSPACEID == WORKSPACE_INVALID) { - Debug::log(ERR, "moveWorkspaceToMonitor invalid workspace!"); -@@ -1756,7 +1751,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { - } - - void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { -- int workspaceID = getWorkspaceIDNameFromString(args).id; -+ auto workspaceID = getWorkspaceIDNameFromString(args).id; - if (workspaceID == WORKSPACE_INVALID) { - Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!"); - return; -@@ -1816,7 +1811,7 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) { - - bool requestedWorkspaceIsAlreadyOpen = false; - const auto PMONITOR = g_pCompositor->m_pLastMonitor; -- int specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); -+ auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); - - for (auto& m : g_pCompositor->m_vMonitors) { - if (m->activeSpecialWorkspaceID() == workspaceID) { -diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp -index 3ba34c11..72ff5ae7 100644 ---- a/src/managers/PointerManager.cpp -+++ b/src/managers/PointerManager.cpp -@@ -11,13 +11,21 @@ - #include - - CPointerManager::CPointerManager() { -- hooks.monitorAdded = g_pHookSystem->hookDynamic("newMonitor", [this](void* self, SCallbackInfo& info, std::any data) { -- auto PMONITOR = std::any_cast>(data); -+ hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) { -+ auto PMONITOR = std::any_cast(data)->self.lock(); - - onMonitorLayoutChange(); - -- PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); -- PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); -+ PMONITOR->events.modeChanged.registerStaticListener( -+ [this, PMONITOR](void* owner, std::any data) { -+ g_pEventLoopManager->doLater([this, PMONITOR]() { -+ onMonitorLayoutChange(); -+ checkDefaultCursorWarp(PMONITOR, PMONITOR->output->name); -+ }); -+ }, -+ nullptr); -+ PMONITOR->events.disconnect.registerStaticListener( -+ [this, PMONITOR](void* owner, std::any data) { g_pEventLoopManager->doLater([this, PMONITOR]() { onMonitorLayoutChange(); }); }, nullptr); - PMONITOR->events.destroy.registerStaticListener( - [this](void* owner, std::any data) { - if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown) -@@ -35,6 +43,38 @@ CPointerManager::CPointerManager() { - }); - } - -+void CPointerManager::checkDefaultCursorWarp(SP monitor, std::string monitorName) { -+ static auto PCURSORMONITOR = CConfigValue("cursor:default_monitor"); -+ static bool cursorDefaultDone = false; -+ static bool firstLaunch = true; -+ -+ const auto POS = monitor->middle(); -+ -+ // by default, cursor should be set to first monitor detected -+ // this is needed as a default if the monitor given in config above doesn't exist -+ if (firstLaunch) { -+ firstLaunch = false; -+ g_pCompositor->warpCursorTo(POS, true); -+ g_pInputManager->refocus(); -+ return; -+ } -+ -+ if (!cursorDefaultDone && *PCURSORMONITOR != STRVAL_EMPTY) { -+ if (*PCURSORMONITOR == monitorName) { -+ cursorDefaultDone = true; -+ g_pCompositor->warpCursorTo(POS, true); -+ g_pInputManager->refocus(); -+ return; -+ } -+ } -+ -+ // modechange happend check if cursor is on that monitor and warp it to middle to not place it out of bounds if resolution changed. -+ if (g_pCompositor->getMonitorFromCursor() == monitor.get()) { -+ g_pCompositor->warpCursorTo(POS, true); -+ g_pInputManager->refocus(); -+ } -+} -+ - void CPointerManager::lockSoftwareAll() { - for (auto& state : monitorStates) - state->softwareLocks++; -diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp -index 4a4c4f61..082855b5 100644 ---- a/src/managers/PointerManager.hpp -+++ b/src/managers/PointerManager.hpp -@@ -26,6 +26,7 @@ class CPointerManager { - public: - CPointerManager(); - -+ void checkDefaultCursorWarp(SP monitor, std::string monitorName); - void attachPointer(SP pointer); - void attachTouch(SP touch); - void attachTablet(SP tablet); -diff --git a/src/managers/XCursorManager.cpp b/src/managers/XCursorManager.cpp -index f2a7ab53..6f000f9f 100644 ---- a/src/managers/XCursorManager.cpp -+++ b/src/managers/XCursorManager.cpp -@@ -1,7 +1,11 @@ - #include - #include - #include -+#include -+#include -+#include "config/ConfigValue.hpp" - #include "helpers/CursorShapes.hpp" -+#include "../managers/CursorManager.hpp" - #include "debug/Log.hpp" - #include "XCursorManager.hpp" - -@@ -96,12 +100,13 @@ CXCursorManager::CXCursorManager() { - defaultCursor = hyprCursor; - } - --void CXCursorManager::loadTheme(std::string const& name, int size) { -- if (lastLoadSize == size && themeName == name) -+void CXCursorManager::loadTheme(std::string const& name, int size, float scale) { -+ if (lastLoadSize == (size * std::ceil(scale)) && themeName == name && lastLoadScale == scale) - return; - -- lastLoadSize = size; -- themeName = name.empty() ? "default" : name; -+ lastLoadSize = size * std::ceil(scale); -+ lastLoadScale = scale; -+ themeName = name.empty() ? "default" : name; - defaultCursor.reset(); - cursors.clear(); - -@@ -146,12 +151,16 @@ void CXCursorManager::loadTheme(std::string const& name, int size) { - - cursors.emplace_back(cursor); - } -+ -+ static auto SYNCGSETTINGS = CConfigValue("cursor:sync_gsettings_theme"); -+ if (*SYNCGSETTINGS) -+ syncGsettings(); - } - --SP CXCursorManager::getShape(std::string const& shape, int size) { -+SP CXCursorManager::getShape(std::string const& shape, int size, float scale) { - // monitor scaling changed etc, so reload theme with new size. -- if (size != lastLoadSize) -- loadTheme(themeName, size); -+ if ((size * std::ceil(scale)) != lastLoadSize || scale != lastLoadScale) -+ loadTheme(themeName, size, scale); - - // try to get an icon we know if we have one - for (auto const& c : cursors) { -@@ -503,8 +512,11 @@ std::vector> CXCursorManager::loadAllFromDir(std::string const& pa - - if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { - for (const auto& entry : std::filesystem::directory_iterator(path)) { -- if (!entry.is_regular_file() && !entry.is_symlink()) -+ std::error_code e1, e2; -+ if ((!entry.is_regular_file(e1) && !entry.is_symlink(e2)) || e1 || e2) { -+ Debug::log(WARN, "XCursor failed to load shape {}: {}", entry.path().stem().string(), e1 ? e1.message() : e2.message()); - continue; -+ } - - auto const& full = entry.path().string(); - using PcloseType = int (*)(FILE*); -@@ -542,3 +554,56 @@ std::vector> CXCursorManager::loadAllFromDir(std::string const& pa - - return newCursors; - } -+ -+void CXCursorManager::syncGsettings() { -+ auto checkParamExists = [](std::string const& paramName, std::string const& category) { -+ auto* gSettingsSchemaSource = g_settings_schema_source_get_default(); -+ -+ if (!gSettingsSchemaSource) { -+ Debug::log(WARN, "GSettings default schema source does not exist, can't sync GSettings"); -+ return false; -+ } -+ -+ auto* gSettingsSchema = g_settings_schema_source_lookup(gSettingsSchemaSource, category.c_str(), true); -+ bool hasParam = false; -+ -+ if (gSettingsSchema != NULL) { -+ hasParam = gSettingsSchema && g_settings_schema_has_key(gSettingsSchema, paramName.c_str()); -+ g_settings_schema_unref(gSettingsSchema); -+ } -+ -+ return hasParam; -+ }; -+ -+ using SettingValue = std::variant; -+ auto setValue = [&checkParamExists](std::string const& paramName, const SettingValue& paramValue, std::string const& category) { -+ if (!checkParamExists(paramName, category)) { -+ Debug::log(WARN, "GSettings parameter doesnt exist {} in {}", paramName, category); -+ return; -+ } -+ -+ auto* gsettings = g_settings_new(category.c_str()); -+ -+ if (!gsettings) { -+ Debug::log(WARN, "GSettings failed to allocate new settings with category {}", category); -+ return; -+ } -+ -+ std::visit( -+ [&](auto&& value) { -+ using T = std::decay_t; -+ if constexpr (std::is_same_v) -+ g_settings_set_string(gsettings, paramName.c_str(), value.c_str()); -+ else if constexpr (std::is_same_v) -+ g_settings_set_int(gsettings, paramName.c_str(), value); -+ }, -+ paramValue); -+ -+ g_settings_sync(); -+ g_object_unref(gsettings); -+ }; -+ -+ int unscaledSize = lastLoadSize / std::ceil(lastLoadScale); -+ setValue("cursor-theme", themeName, "org.gnome.desktop.interface"); -+ setValue("cursor-size", unscaledSize, "org.gnome.desktop.interface"); -+} -diff --git a/src/managers/XCursorManager.hpp b/src/managers/XCursorManager.hpp -index 20637055..1f3c24db 100644 ---- a/src/managers/XCursorManager.hpp -+++ b/src/managers/XCursorManager.hpp -@@ -29,8 +29,9 @@ class CXCursorManager { - CXCursorManager(); - ~CXCursorManager() = default; - -- void loadTheme(const std::string& name, int size); -- SP getShape(std::string const& shape, int size); -+ void loadTheme(const std::string& name, int size, float scale); -+ SP getShape(std::string const& shape, int size, float scale); -+ void syncGsettings(); - - private: - SP createCursor(std::string const& shape, XcursorImages* xImages); -@@ -39,9 +40,10 @@ class CXCursorManager { - std::vector> loadStandardCursors(std::string const& name, int size); - std::vector> loadAllFromDir(std::string const& path, int size); - -- int lastLoadSize = 0; -- std::string themeName = ""; -+ int lastLoadSize = 0; -+ float lastLoadScale = 0; -+ std::string themeName = ""; - SP defaultCursor; - SP hyprCursor; - std::vector> cursors; --}; -\ No newline at end of file -+}; -diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp -index c2c088f8..d1b85cf2 100644 ---- a/src/managers/eventLoop/EventLoopManager.cpp -+++ b/src/managers/eventLoop/EventLoopManager.cpp -@@ -48,7 +48,6 @@ void CEventLoopManager::enterLoop() { - aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); - for (auto& fd : aqPollFDs) { - m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get())); -- fd->onSignal(); // dispatch outstanding - } - - wl_display_run(m_sWayland.display); -@@ -76,8 +75,8 @@ void CEventLoopManager::removeTimer(SP timer) { - } - - static void timespecAddNs(timespec* pTimespec, int64_t delta) { -- int delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC; -- int delta_s_high = delta / TIMESPEC_NSEC_PER_SEC; -+ auto delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC; -+ auto delta_s_high = delta / TIMESPEC_NSEC_PER_SEC; - - pTimespec->tv_sec += delta_s_high; - -diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp -index c502cb0d..e5f921a2 100644 ---- a/src/managers/input/InputManager.cpp -+++ b/src/managers/input/InputManager.cpp -@@ -82,18 +82,13 @@ CInputManager::~CInputManager() { - } - - void CInputManager::onMouseMoved(IPointer::SMotionEvent e) { -- static auto PSENS = CConfigValue("general:sensitivity"); -- static auto PNOACCEL = CConfigValue("input:force_no_accel"); -- static auto PSENSTORAW = CConfigValue("general:apply_sens_to_raw"); -+ static auto PNOACCEL = CConfigValue("input:force_no_accel"); - - const auto DELTA = *PNOACCEL == 1 ? e.unaccel : e.delta; - -- if (*PSENSTORAW == 1) -- PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA * *PSENS, e.unaccel * *PSENS); -- else -- PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel); -+ PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel); - -- g_pPointerManager->move(DELTA * *PSENS); -+ g_pPointerManager->move(DELTA); - - mouseMoveUnified(e.timeMs); - -@@ -1112,8 +1107,9 @@ void CInputManager::setPointerConfigs() { - 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 (g_pConfigManager->getDeviceInt(devname, "tap-to-click", "input:touchpad:tap-to-click") == 1) -- libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED); -+ libinput_device_config_tap_set_enabled(LIBINPUTDEV, -+ g_pConfigManager->getDeviceInt(devname, "tap-to-click", "input:touchpad:tap-to-click") == 1 ? LIBINPUT_CONFIG_TAP_ENABLED : -+ LIBINPUT_CONFIG_TAP_DISABLED); - - if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV)) { - -diff --git a/src/managers/input/InputMethodPopup.hpp b/src/managers/input/InputMethodPopup.hpp -index f6e5c8be..f8e4b962 100644 ---- a/src/managers/input/InputMethodPopup.hpp -+++ b/src/managers/input/InputMethodPopup.hpp -@@ -33,7 +33,7 @@ class CInputPopup { - WP popup; - SP surface; - CBox lastBoxLocal; -- uint64_t lastMonitor = -1; -+ MONITORID lastMonitor = MONITOR_INVALID; - - struct { - CHyprSignalListener map; -diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp -index c0e6c4f0..6ee690cd 100644 ---- a/src/managers/input/Swipe.cpp -+++ b/src/managers/input/Swipe.cpp -@@ -77,7 +77,7 @@ void CInputManager::endWorkspaceSwipe() { - // left of where we started. Instead, it's one more than the greatest - // workspace ID that currently exists. - if (workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID && *PSWIPENEW) { -- int maxWorkspace = 0; -+ WORKSPACEID maxWorkspace = 0; - for (const auto& ws : g_pCompositor->m_vWorkspaces) { - maxWorkspace = std::max(maxWorkspace, ws->m_iID); - } -diff --git a/src/meson.build b/src/meson.build -index 098d8298..475ecc24 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -28,6 +28,7 @@ executable('Hyprland', src, - xcb_xfixes_dep, - backtrace_dep, - epoll_dep, -+ gio_dep, - udis86, - - dependency('pixman-1'), -diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp -index 38b8c800..13597fa9 100644 ---- a/src/protocols/AlphaModifier.cpp -+++ b/src/protocols/AlphaModifier.cpp -@@ -4,8 +4,6 @@ - #include "../render/Renderer.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::alphaModifier->protoLog -- - CAlphaModifier::CAlphaModifier(SP resource_, SP surface_) : resource(resource_), pSurface(surface_) { - if (!resource->resource()) - return; -diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp -index 812afe53..233a5df9 100644 ---- a/src/protocols/CursorShape.cpp -+++ b/src/protocols/CursorShape.cpp -@@ -2,8 +2,6 @@ - #include - #include "../helpers/CursorShapes.hpp" - --#define LOGM PROTO::cursorShape->protoLog -- - CCursorShapeProtocol::CCursorShapeProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - ; - } -diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp -index 9f5b6312..bc0945f1 100644 ---- a/src/protocols/DRMLease.cpp -+++ b/src/protocols/DRMLease.cpp -@@ -1,10 +1,9 @@ - #include "DRMLease.hpp" - #include "../Compositor.hpp" -+#include "managers/eventLoop/EventLoopManager.hpp" - #include - #include - --#define LOGM PROTO::lease->protoLog -- - CDRMLeaseResource::CDRMLeaseResource(SP resource_, SP request) : resource(resource_) { - if (!good()) - return; -@@ -247,10 +246,8 @@ CDRMLeaseProtocol::CDRMLeaseProtocol(const wl_interface* iface, const int& ver, - break; - } - -- if (!primaryDevice || primaryDevice->success) { -- PROTO::lease.reset(); -- return; -- } -+ if (!primaryDevice || !primaryDevice->success) -+ g_pEventLoopManager->doLater([]() { PROTO::lease.reset(); }); - } - - void CDRMLeaseProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { -diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp -index 9a48b99a..4993f1a4 100644 ---- a/src/protocols/DRMSyncobj.cpp -+++ b/src/protocols/DRMSyncobj.cpp -@@ -7,8 +7,6 @@ - - #include - --#define LOGM PROTO::sync->protoLog -- - CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/DataDeviceWlr.cpp b/src/protocols/DataDeviceWlr.cpp -index c039d3b4..ad6ee89a 100644 ---- a/src/protocols/DataDeviceWlr.cpp -+++ b/src/protocols/DataDeviceWlr.cpp -@@ -3,8 +3,6 @@ - #include "../managers/SeatManager.hpp" - #include "core/Seat.hpp" - --#define LOGM PROTO::dataWlr->protoLog -- - CWLRDataOffer::CWLRDataOffer(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp -index 40f9af44..2d6b2ee2 100644 ---- a/src/protocols/FocusGrab.cpp -+++ b/src/protocols/FocusGrab.cpp -@@ -8,8 +8,6 @@ - #include - #include - --#define LOGM PROTO::focusGrab->protoLog -- - CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, SP surface) { - listeners.destroy = surface->events.destroy.registerListener([=](std::any d) { grab->eraseSurface(surface); }); - } -diff --git a/src/protocols/ForeignToplevel.cpp b/src/protocols/ForeignToplevel.cpp -index f7b3886f..59888ce2 100644 ---- a/src/protocols/ForeignToplevel.cpp -+++ b/src/protocols/ForeignToplevel.cpp -@@ -1,8 +1,6 @@ - #include "ForeignToplevel.hpp" - #include "../Compositor.hpp" - --#define LOGM PROTO::foreignToplevel->protoLog -- - CForeignToplevelHandle::CForeignToplevelHandle(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { - if (!resource_->resource()) - return; -diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp -index 295834ea..bd597a91 100644 ---- a/src/protocols/ForeignToplevelWlr.cpp -+++ b/src/protocols/ForeignToplevelWlr.cpp -@@ -4,8 +4,6 @@ - #include "protocols/core/Output.hpp" - #include "render/Renderer.hpp" - --#define LOGM PROTO::foreignToplevelWlr->protoLog -- - CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { - if (!resource_->resource()) - return; -@@ -119,7 +117,7 @@ wl_resource* CForeignToplevelHandleWlr::res() { - } - - void CForeignToplevelHandleWlr::sendMonitor(CMonitor* pMonitor) { -- if (lastMonitorID == (int64_t)pMonitor->ID) -+ if (lastMonitorID == pMonitor->ID) - return; - - const auto CLIENT = resource->client(); -diff --git a/src/protocols/ForeignToplevelWlr.hpp b/src/protocols/ForeignToplevelWlr.hpp -index e3b6f3f3..99f63b47 100644 ---- a/src/protocols/ForeignToplevelWlr.hpp -+++ b/src/protocols/ForeignToplevelWlr.hpp -@@ -20,7 +20,7 @@ class CForeignToplevelHandleWlr { - SP resource; - PHLWINDOWREF pWindow; - bool closed = false; -- int64_t lastMonitorID = -1; -+ MONITORID lastMonitorID = MONITOR_INVALID; - - void sendMonitor(CMonitor* pMonitor); - void sendState(); -diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp -index 5bf56c5a..d39fa67c 100644 ---- a/src/protocols/FractionalScale.cpp -+++ b/src/protocols/FractionalScale.cpp -@@ -2,8 +2,6 @@ - #include - #include "core/Compositor.hpp" - --#define LOGM PROTO::fractional->protoLog -- - CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - ; - } -diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp -index 494d9862..c902d00e 100644 ---- a/src/protocols/GammaControl.cpp -+++ b/src/protocols/GammaControl.cpp -@@ -5,8 +5,6 @@ - #include "../Compositor.hpp" - #include "../protocols/core/Output.hpp" - --#define LOGM PROTO::gamma->protoLog -- - CGammaControl::CGammaControl(SP resource_, wl_resource* output) : resource(resource_) { - if (!resource_->resource()) - return; -@@ -109,7 +107,7 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out - } - - CGammaControl::~CGammaControl() { -- if (!gammaTableSet || !pMonitor) -+ if (!gammaTableSet || !pMonitor || !pMonitor->output) - return; - - // reset the LUT if the client dies for whatever reason and doesn't unset the gamma -diff --git a/src/protocols/GlobalShortcuts.cpp b/src/protocols/GlobalShortcuts.cpp -index 860004c9..92bfbae4 100644 ---- a/src/protocols/GlobalShortcuts.cpp -+++ b/src/protocols/GlobalShortcuts.cpp -@@ -1,8 +1,6 @@ - #include "GlobalShortcuts.hpp" - #include "../Compositor.hpp" - --#define LOGM PROTO::globalShortcuts->protoLog -- - CShortcutClient::CShortcutClient(SP resource_) : resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/IdleNotify.cpp b/src/protocols/IdleNotify.cpp -index 2ec7d2a1..8d915ac6 100644 ---- a/src/protocols/IdleNotify.cpp -+++ b/src/protocols/IdleNotify.cpp -@@ -1,8 +1,6 @@ - #include "IdleNotify.hpp" - #include "../managers/eventLoop/EventLoopManager.hpp" - --#define LOGM PROTO::idle->protoLog -- - static int onTimer(SP self, void* data) { - - const auto NOTIF = (CExtIdleNotification*)data; -diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp -index fd306f09..a0820e0b 100644 ---- a/src/protocols/InputMethodV2.cpp -+++ b/src/protocols/InputMethodV2.cpp -@@ -6,8 +6,6 @@ - #include "core/Compositor.hpp" - #include - --#define LOGM PROTO::ime->protoLog -- - CInputMethodKeyboardGrabV2::CInputMethodKeyboardGrabV2(SP resource_, SP owner_) : resource(resource_), owner(owner_) { - if (!resource->resource()) - return; -diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp -index 17d3b22a..c02d23f3 100644 ---- a/src/protocols/LayerShell.cpp -+++ b/src/protocols/LayerShell.cpp -@@ -4,8 +4,6 @@ - #include "core/Compositor.hpp" - #include "core/Output.hpp" - --#define LOGM PROTO::layerShell->protoLog -- - void CLayerShellResource::SState::reset() { - anchor = 0; - exclusive = 0; -diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp -index 0fbf832e..32625792 100644 ---- a/src/protocols/LinuxDMABUF.cpp -+++ b/src/protocols/LinuxDMABUF.cpp -@@ -14,8 +14,6 @@ - #include "../render/OpenGL.hpp" - #include "../Compositor.hpp" - --#define LOGM PROTO::linuxDma->protoLog -- - static std::optional devIDFromFD(int fd) { - struct stat stat; - if (fstat(fd, &stat) != 0) -@@ -425,7 +423,7 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const - auto dev = devIDFromFD(rendererFD); - - if (!dev.has_value()) { -- protoLog(ERR, "failed to get drm dev, disabling linux dmabuf"); -+ LOGM(ERR, "failed to get drm dev, disabling linux dmabuf"); - removeGlobal(); - return; - } -@@ -477,7 +475,7 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const - - drmDevice* device = nullptr; - if (drmGetDeviceFromDevId(mainDevice, 0, &device) != 0) { -- protoLog(ERR, "failed to get drm dev, disabling linux dmabuf"); -+ LOGM(ERR, "failed to get drm dev, disabling linux dmabuf"); - removeGlobal(); - return; - } -@@ -487,14 +485,13 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const - mainDeviceFD = open(name, O_RDWR | O_CLOEXEC); - drmFreeDevice(&device); - if (mainDeviceFD < 0) { -- protoLog(ERR, "failed to open drm dev, disabling linux dmabuf"); -+ LOGM(ERR, "failed to open drm dev, disabling linux dmabuf"); - removeGlobal(); - return; - } - } else { -- protoLog(ERR, "DRM device {} has no render node, disabling linux dmabuf", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); -+ LOGM(ERR, "DRM device {} has no render node, disabling linux dmabuf checks", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); - drmFreeDevice(&device); -- removeGlobal(); - } - }); - } -diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp -index ed412555..9fcd5f9b 100644 ---- a/src/protocols/MesaDRM.cpp -+++ b/src/protocols/MesaDRM.cpp -@@ -4,8 +4,6 @@ - #include "../Compositor.hpp" - #include "types/WLBuffer.hpp" - --#define LOGM PROTO::mesaDRM->protoLog -- - CMesaDRMBufferResource::CMesaDRMBufferResource(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs attrs_) { - LOGM(LOG, "Creating a Mesa dmabuf, with id {}: size {}, fmt {}, planes {}", id, attrs_.size, attrs_.format, attrs_.planes); - for (int i = 0; i < attrs_.planes; ++i) { -@@ -115,7 +113,7 @@ CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, co - drmDevice* dev = nullptr; - int drmFD = g_pCompositor->m_iDRMFD; - if (drmGetDevice2(drmFD, 0, &dev) != 0) { -- protoLog(ERR, "Failed to get device, disabling MesaDRM"); -+ LOGM(ERR, "Failed to get device, disabling MesaDRM"); - removeGlobal(); - return; - } -@@ -126,13 +124,13 @@ CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, co - ASSERT(dev->available_nodes & (1 << DRM_NODE_PRIMARY)); - - if (!dev->nodes[DRM_NODE_PRIMARY]) { -- protoLog(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM"); -+ LOGM(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM"); - drmFreeDevice(&dev); - removeGlobal(); - return; - } - -- protoLog(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]); -+ LOGM(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]); - nodeName = dev->nodes[DRM_NODE_PRIMARY]; - } - drmFreeDevice(&dev); -diff --git a/src/protocols/OutputManagement.cpp b/src/protocols/OutputManagement.cpp -index 66f4c5f0..cfe388fa 100644 ---- a/src/protocols/OutputManagement.cpp -+++ b/src/protocols/OutputManagement.cpp -@@ -4,8 +4,6 @@ - - using namespace Aquamarine; - --#define LOGM PROTO::outputManagement->protoLog -- - COutputManager::COutputManager(SP resource_) : resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/OutputPower.cpp b/src/protocols/OutputPower.cpp -index 597b9871..0c324bf0 100644 ---- a/src/protocols/OutputPower.cpp -+++ b/src/protocols/OutputPower.cpp -@@ -2,8 +2,6 @@ - #include "../Compositor.hpp" - #include "core/Output.hpp" - --#define LOGM PROTO::outputPower->protoLog -- - COutputPower::COutputPower(SP resource_, CMonitor* pMonitor_) : resource(resource_), pMonitor(pMonitor_) { - if (!resource->resource()) - return; -diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp -index fd15242d..0f2dd991 100644 ---- a/src/protocols/PointerConstraints.cpp -+++ b/src/protocols/PointerConstraints.cpp -@@ -5,8 +5,6 @@ - #include "../managers/SeatManager.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::constraints->protoLog -- - CPointerConstraint::CPointerConstraint(SP resource_, SP surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) : - resourceL(resource_), locked(true), lifetime(lifetime_) { - if (!resource_->resource()) -diff --git a/src/protocols/PointerGestures.cpp b/src/protocols/PointerGestures.cpp -index 86510779..c83e3887 100644 ---- a/src/protocols/PointerGestures.cpp -+++ b/src/protocols/PointerGestures.cpp -@@ -4,8 +4,6 @@ - #include "core/Seat.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::pointerGestures->protoLog -- - CPointerGestureSwipe::CPointerGestureSwipe(SP resource_) : resource(resource_) { - if (!resource->resource()) - return; -diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp -index a2fc270c..335cf557 100644 ---- a/src/protocols/PresentationTime.cpp -+++ b/src/protocols/PresentationTime.cpp -@@ -6,8 +6,6 @@ - #include "core/Output.hpp" - #include - --#define LOGM PROTO::presentation->protoLog -- - CQueuedPresentationData::CQueuedPresentationData(SP surf) : surface(surf) { - ; - } -diff --git a/src/protocols/PrimarySelection.cpp b/src/protocols/PrimarySelection.cpp -index 78eb8d63..4fede706 100644 ---- a/src/protocols/PrimarySelection.cpp -+++ b/src/protocols/PrimarySelection.cpp -@@ -4,8 +4,6 @@ - #include "core/Seat.hpp" - #include "../config/ConfigValue.hpp" - --#define LOGM PROTO::primarySelection->protoLog -- - CPrimarySelectionOffer::CPrimarySelectionOffer(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp -index a8afba84..f246f6dd 100644 ---- a/src/protocols/Screencopy.cpp -+++ b/src/protocols/Screencopy.cpp -@@ -9,8 +9,6 @@ - - #include - --#define LOGM PROTO::screencopy->protoLog -- - CScreencopyFrame::~CScreencopyFrame() { - if (buffer && buffer->locked()) - buffer->unlock(); -diff --git a/src/protocols/ServerDecorationKDE.cpp b/src/protocols/ServerDecorationKDE.cpp -index 42da52a9..c7b98a9c 100644 ---- a/src/protocols/ServerDecorationKDE.cpp -+++ b/src/protocols/ServerDecorationKDE.cpp -@@ -1,8 +1,6 @@ - #include "ServerDecorationKDE.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::serverDecorationKDE->protoLog -- - CServerDecorationKDE::CServerDecorationKDE(SP resource_, SP surf) : resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp -index df97413c..7b0d8b3b 100644 ---- a/src/protocols/SessionLock.cpp -+++ b/src/protocols/SessionLock.cpp -@@ -5,8 +5,6 @@ - #include "core/Compositor.hpp" - #include "core/Output.hpp" - --#define LOGM PROTO::sessionLock->protoLog -- - CSessionLockSurface::CSessionLockSurface(SP resource_, SP surface_, CMonitor* pMonitor_, WP owner_) : - resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) { - if (!resource->resource()) -diff --git a/src/protocols/ShortcutsInhibit.cpp b/src/protocols/ShortcutsInhibit.cpp -index 1a0433e6..e4424ed7 100644 ---- a/src/protocols/ShortcutsInhibit.cpp -+++ b/src/protocols/ShortcutsInhibit.cpp -@@ -3,8 +3,6 @@ - #include "../Compositor.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::shortcutsInhibit->protoLog -- - CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP resource_, SP surf) : resource(resource_), pSurface(surf) { - if (!resource->resource()) - return; -diff --git a/src/protocols/Tablet.cpp b/src/protocols/Tablet.cpp -index 72c7cfde..b974152e 100644 ---- a/src/protocols/Tablet.cpp -+++ b/src/protocols/Tablet.cpp -@@ -7,8 +7,6 @@ - #include - #include - --#define LOGM PROTO::tablet->protoLog -- - CTabletPadStripV2Resource::CTabletPadStripV2Resource(SP resource_, uint32_t id_) : id(id_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp -index 78e910cb..f25f5aca 100644 ---- a/src/protocols/TextInputV1.cpp -+++ b/src/protocols/TextInputV1.cpp -@@ -3,8 +3,6 @@ - #include "../Compositor.hpp" - #include "core/Compositor.hpp" - --#define LOGM PROTO::textInputV1->protoLog -- - CTextInputV1::~CTextInputV1() { - events.destroy.emit(); - } -diff --git a/src/protocols/TextInputV3.cpp b/src/protocols/TextInputV3.cpp -index 1302a57f..99d799f3 100644 ---- a/src/protocols/TextInputV3.cpp -+++ b/src/protocols/TextInputV3.cpp -@@ -2,8 +2,6 @@ - #include - #include "core/Compositor.hpp" - --#define LOGM PROTO::textInputV3->protoLog -- - void CTextInputV3::SState::reset() { - cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; - surrounding.updated = false; -diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp -index fb3fde2b..05e991d6 100644 ---- a/src/protocols/ToplevelExport.cpp -+++ b/src/protocols/ToplevelExport.cpp -@@ -8,8 +8,6 @@ - - #include - --#define LOGM PROTO::toplevelExport->protoLog -- - CToplevelExportClient::CToplevelExportClient(SP resource_) : resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/Viewporter.cpp b/src/protocols/Viewporter.cpp -index 78f3039f..58cb851d 100644 ---- a/src/protocols/Viewporter.cpp -+++ b/src/protocols/Viewporter.cpp -@@ -2,8 +2,6 @@ - #include "core/Compositor.hpp" - #include - --#define LOGM PROTO::viewport->protoLog -- - CViewportResource::CViewportResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp -index 2642ec11..27a4f248 100644 ---- a/src/protocols/VirtualKeyboard.cpp -+++ b/src/protocols/VirtualKeyboard.cpp -@@ -2,8 +2,6 @@ - #include - #include "../devices/IKeyboard.hpp" - --#define LOGM PROTO::virtualKeyboard->protoLog -- - CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource_) : resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp -index 8626241a..eb92a640 100644 ---- a/src/protocols/VirtualPointer.cpp -+++ b/src/protocols/VirtualPointer.cpp -@@ -1,8 +1,6 @@ - #include "VirtualPointer.hpp" - #include "core/Output.hpp" - --#define LOGM PROTO::virtualPointer->protoLog -- - CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP resource_, WP boundOutput_) : boundOutput(boundOutput_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/WaylandProtocol.cpp b/src/protocols/WaylandProtocol.cpp -index 954f160d..0782d323 100644 ---- a/src/protocols/WaylandProtocol.cpp -+++ b/src/protocols/WaylandProtocol.cpp -@@ -21,7 +21,7 @@ IWaylandProtocol::IWaylandProtocol(const wl_interface* iface, const int& ver, co - m_pGlobal = wl_global_create(g_pCompositor->m_sWLDisplay, iface, ver, this, &bindManagerInternal); - - if (!m_pGlobal) { -- protoLog(ERR, "could not create a global"); -+ LOGM(ERR, "could not create a global [{}]", m_szName); - return; - } - -@@ -30,7 +30,7 @@ IWaylandProtocol::IWaylandProtocol(const wl_interface* iface, const int& ver, co - m_liDisplayDestroy.parent = this; - wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy.listener); - -- protoLog(LOG, "Registered global"); -+ LOGM(LOG, "Registered global [{}]", m_szName); - } - - IWaylandProtocol::~IWaylandProtocol() { -diff --git a/src/protocols/WaylandProtocol.hpp b/src/protocols/WaylandProtocol.hpp -index 4d4e7925..0fa8daab 100644 ---- a/src/protocols/WaylandProtocol.hpp -+++ b/src/protocols/WaylandProtocol.hpp -@@ -11,6 +11,35 @@ - - #define PROTO NProtocols - -+#define EXTRACT_CLASS_NAME() \ -+ []() constexpr -> std::string_view { \ -+ constexpr std::string_view prettyFunction = __PRETTY_FUNCTION__; \ -+ constexpr size_t colons = prettyFunction.find("::"); \ -+ if (colons != std::string_view::npos) { \ -+ constexpr size_t begin = prettyFunction.substr(0, colons).rfind(' ') + 1; \ -+ constexpr size_t end = colons - begin; \ -+ return prettyFunction.substr(begin, end); \ -+ } else { \ -+ return "Global"; \ -+ } \ -+ }() -+ -+#define LOGM(level, ...) \ -+ do { \ -+ std::ostringstream oss; \ -+ if (level == WARN || level == ERR || level == CRIT) { \ -+ oss << "[" << __FILE__ << ":" << __LINE__ << "] "; \ -+ } else if (level == LOG || level == INFO || level == TRACE) { \ -+ oss << "[" << EXTRACT_CLASS_NAME() << "] "; \ -+ } \ -+ if constexpr (std::is_same_v) { \ -+ oss << __VA_ARGS__; \ -+ Debug::log(level, oss.str()); \ -+ } else { \ -+ Debug::log(level, std::format("{}{}", oss.str(), std::format(__VA_ARGS__))); \ -+ } \ -+ } while (0) -+ - class IWaylandProtocol; - struct IWaylandProtocolDestroyWrapper { - wl_listener listener; -@@ -22,15 +51,10 @@ class IWaylandProtocol { - IWaylandProtocol(const wl_interface* iface, const int& ver, const std::string& name); - virtual ~IWaylandProtocol(); - -- virtual void onDisplayDestroy(); -- virtual void removeGlobal(); -- -- virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) = 0; -+ virtual void onDisplayDestroy(); -+ virtual void removeGlobal(); - -- template -- void protoLog(LogLevel level, std::format_string fmt, Args&&... args) { -- Debug::log(level, std::format("[{}] ", m_szName) + std::vformat(fmt.get(), std::make_format_args(args...))); -- }; -+ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) = 0; - - IWaylandProtocolDestroyWrapper m_liDisplayDestroy; - -diff --git a/src/protocols/XDGActivation.cpp b/src/protocols/XDGActivation.cpp -index 40f33f02..4a6c7bfe 100644 ---- a/src/protocols/XDGActivation.cpp -+++ b/src/protocols/XDGActivation.cpp -@@ -4,8 +4,6 @@ - #include "core/Compositor.hpp" - #include - --#define LOGM PROTO::activation->protoLog -- - CXDGActivationToken::CXDGActivationToken(SP resource_) : resource(resource_) { - if (!resource_->resource()) - return; -diff --git a/src/protocols/XDGDecoration.cpp b/src/protocols/XDGDecoration.cpp -index 021a1141..07b1694c 100644 ---- a/src/protocols/XDGDecoration.cpp -+++ b/src/protocols/XDGDecoration.cpp -@@ -1,8 +1,6 @@ - #include "XDGDecoration.hpp" - #include - --#define LOGM PROTO::xdgDecoration->protoLog -- - CXDGDecoration::CXDGDecoration(SP resource_, wl_resource* toplevel) : resource(resource_), pToplevelResource(toplevel) { - if (!resource->resource()) - return; -diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp -index 073aa502..9c2c353c 100644 ---- a/src/protocols/XDGOutput.cpp -+++ b/src/protocols/XDGOutput.cpp -@@ -12,8 +12,6 @@ - - // - --#define LOGM PROTO::xdgOutput->protoLog -- - void CXDGOutputProtocol::onManagerResourceDestroy(wl_resource* res) { - std::erase_if(m_vManagerResources, [&](const auto& other) { return other->resource() == res; }); - } -diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp -index aea23329..eaf5c333 100644 ---- a/src/protocols/XDGShell.cpp -+++ b/src/protocols/XDGShell.cpp -@@ -6,8 +6,6 @@ - #include "core/Compositor.hpp" - #include - --#define LOGM PROTO::xdgShell->protoLog -- - void SXDGPositionerState::setAnchor(xdgPositionerAnchor edges) { - anchor.setTop(edges == XDG_POSITIONER_ANCHOR_TOP || edges == XDG_POSITIONER_ANCHOR_TOP_LEFT || edges == XDG_POSITIONER_ANCHOR_TOP_RIGHT); - anchor.setLeft(edges == XDG_POSITIONER_ANCHOR_LEFT || edges == XDG_POSITIONER_ANCHOR_TOP_LEFT || edges == XDG_POSITIONER_ANCHOR_BOTTOM_LEFT); -diff --git a/src/protocols/XWaylandShell.cpp b/src/protocols/XWaylandShell.cpp -index 6cc5256f..d6c3b1a8 100644 ---- a/src/protocols/XWaylandShell.cpp -+++ b/src/protocols/XWaylandShell.cpp -@@ -2,8 +2,6 @@ - #include "core/Compositor.hpp" - #include - --#define LOGM PROTO::xwaylandShell->protoLog -- - CXWaylandSurfaceResource::CXWaylandSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp -index a767dd52..8b6f46b1 100644 ---- a/src/protocols/core/Compositor.cpp -+++ b/src/protocols/core/Compositor.cpp -@@ -13,8 +13,6 @@ - #include "../../render/Renderer.hpp" - #include - --#define LOGM PROTO::compositor->protoLog -- - class CDefaultSurfaceRole : public ISurfaceRole { - public: - virtual eSurfaceRole role() { -diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp -index fe3905d0..4ed28f24 100644 ---- a/src/protocols/core/DataDevice.cpp -+++ b/src/protocols/core/DataDevice.cpp -@@ -6,8 +6,6 @@ - #include "Seat.hpp" - #include "Compositor.hpp" - --#define LOGM PROTO::data->protoLog -- - CWLDataOfferResource::CWLDataOfferResource(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp -index bb6a9d4d..a111c12c 100644 ---- a/src/protocols/core/Seat.cpp -+++ b/src/protocols/core/Seat.cpp -@@ -9,8 +9,6 @@ - - #include - --#define LOGM PROTO::seat->protoLog -- - CWLTouchResource::CWLTouchResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) - return; -diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp -index 75c2134a..9996a607 100644 ---- a/src/protocols/core/Shm.cpp -+++ b/src/protocols/core/Shm.cpp -@@ -7,8 +7,6 @@ - #include "../../Compositor.hpp" - #include "../../helpers/Format.hpp" - --#define LOGM PROTO::shm->protoLog -- - CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) { - if (!pool_->pool->data) - return; -@@ -65,7 +63,7 @@ Aquamarine::SSHMAttrs CWLSHMBuffer::shm() { - } - - std::tuple CWLSHMBuffer::beginDataPtr(uint32_t flags) { -- return {(uint8_t*)pool->data + offset, fmt, size.x * size.y * 4}; -+ return {(uint8_t*)pool->data + offset, fmt, stride * size.y}; - } - - void CWLSHMBuffer::endDataPtr() { -diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp -index 2a7c06dc..e0679eff 100644 ---- a/src/protocols/core/Subcompositor.cpp -+++ b/src/protocols/core/Subcompositor.cpp -@@ -2,8 +2,6 @@ - #include "Compositor.hpp" - #include - --#define LOGM PROTO::subcompositor->protoLog -- - CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SP surface_, SP parent_) : - surface(surface_), parent(parent_), resource(resource_) { - if (!good()) -diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp -index 67629e23..c48ff6f3 100644 ---- a/src/render/Framebuffer.cpp -+++ b/src/render/Framebuffer.cpp -@@ -12,9 +12,10 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { - uint32_t glFormat = FormatUtils::drmFormatToGL(drmFormat); - uint32_t glType = FormatUtils::glFormatToType(glFormat); - -- if (m_iFb == (uint32_t)-1) { -+ if (!m_iFbAllocated) { - firstAlloc = true; - glGenFramebuffers(1, &m_iFb); -+ m_iFbAllocated = true; - } - - if (m_cTex->m_iTexID == 0) { -@@ -88,12 +89,12 @@ void CFramebuffer::bind() { - } - - void CFramebuffer::release() { -- if (m_iFb != (uint32_t)-1 && m_iFb) -+ if (m_iFbAllocated) - glDeleteFramebuffers(1, &m_iFb); - - m_cTex->destroyTexture(); -- m_iFb = -1; -- m_vSize = Vector2D(); -+ m_iFbAllocated = false; -+ m_vSize = Vector2D(); - } - - CFramebuffer::~CFramebuffer() { -@@ -101,5 +102,5 @@ CFramebuffer::~CFramebuffer() { - } - - bool CFramebuffer::isAllocated() { -- return m_iFb != (GLuint)-1; -+ return m_iFbAllocated; - } -\ No newline at end of file -diff --git a/src/render/Framebuffer.hpp b/src/render/Framebuffer.hpp -index a46a4859..ca7f9e8a 100644 ---- a/src/render/Framebuffer.hpp -+++ b/src/render/Framebuffer.hpp -@@ -18,7 +18,8 @@ class CFramebuffer { - Vector2D m_vSize; - - SP m_cTex; -- GLuint m_iFb = -1; -+ GLuint m_iFb; -+ bool m_iFbAllocated{false}; - - SP m_pStencilTex; - }; -\ No newline at end of file -diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp -index c355f4f9..63cc2203 100644 ---- a/src/render/OpenGL.cpp -+++ b/src/render/OpenGL.cpp -@@ -1247,14 +1247,14 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round - - glEnable(GL_STENCIL_TEST); - -- glStencilFunc(GL_ALWAYS, 1, -1); -+ glStencilFunc(GL_ALWAYS, 1, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - renderRect(box, CColor(0, 0, 0, 0), round); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - -- glStencilFunc(GL_EQUAL, 1, -1); -+ glStencilFunc(GL_EQUAL, 1, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - scissor(box); -@@ -1269,7 +1269,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT); - glDisable(GL_STENCIL_TEST); -- glStencilMask(-1); -+ glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - scissor((CBox*)nullptr); - -@@ -1802,12 +1802,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o - CRegion tempDamage{damage}; - - // and draw -- for (int i = 1; i <= *PBLURPASSES; ++i) { -+ for (auto i = 1; i <= *PBLURPASSES; ++i) { - tempDamage = damage.copy().scale(1.f / (1 << i)); - drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down - } - -- for (int i = *PBLURPASSES - 1; i >= 0; --i) { -+ for (auto i = *PBLURPASSES - 1; i >= 0; --i) { - tempDamage = damage.copy().scale(1.f / (1 << i)); // when upsampling we make the region twice as big - drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up - } -@@ -2091,7 +2091,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float - - glEnable(GL_STENCIL_TEST); - -- glStencilFunc(GL_ALWAYS, 1, -1); -+ glStencilFunc(GL_ALWAYS, 1, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); -@@ -2101,7 +2101,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float - renderTexture(tex, pBox, a, round, true, true); // discard opaque - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - -- glStencilFunc(GL_EQUAL, 1, -1); -+ glStencilFunc(GL_EQUAL, 1, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - // stencil done. Render everything. -@@ -2124,7 +2124,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float - glDisable(GL_STENCIL_TEST); - renderTextureInternalWithDamage(tex, pBox, a, &texDamage, round, false, false, true, true); - -- glStencilMask(-1); -+ glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - scissor((CBox*)nullptr); - } -@@ -2690,7 +2690,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { - // check if wallpapers exist - std::error_code err; - if (!std::filesystem::exists(texPath, err)) { -- Debug::log(ERR, "createBGTextureForMonitor: failed, file doesn't exist or access denied, ec: {}", err.message()); -+ Debug::log(ERR, "createBGTextureForMonitor: failed, file \"{}\" doesn't exist or access denied, ec: {}", texPath, err.message()); - return; // the texture will be empty, oh well. We'll clear with a solid color anyways. - } - -diff --git a/src/render/Renderbuffer.cpp b/src/render/Renderbuffer.cpp -index 58ed88d6..c4425ce9 100644 ---- a/src/render/Renderbuffer.cpp -+++ b/src/render/Renderbuffer.cpp -@@ -35,7 +35,8 @@ CRenderbuffer::CRenderbuffer(SP buffer, uint32_t format) : - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - glGenFramebuffers(1, &m_sFramebuffer.m_iFb); -- m_sFramebuffer.m_vSize = buffer->size; -+ m_sFramebuffer.m_iFbAllocated = true; -+ m_sFramebuffer.m_vSize = buffer->size; - m_sFramebuffer.bind(); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_iRBO); - -diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp -index 7b29eb77..b363c287 100644 ---- a/src/render/Renderer.cpp -+++ b/src/render/Renderer.cpp -@@ -1207,6 +1207,9 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { - } else if (!pMonitor->lastScanout.expired()) { - Debug::log(LOG, "Left a direct scanout."); - pMonitor->lastScanout.reset(); -+ -+ // reset DRM format, make sure it's the one we want. -+ pMonitor->output->state->setFormat(pMonitor->drmFormat); - } - } - -@@ -1395,15 +1398,15 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { - - pMonitor->pendingFrame = false; - -- const float µs = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - renderStart).count() / 1000.f; -- g_pDebugOverlay->renderData(pMonitor, µs); -+ const float durationUs = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - renderStart).count() / 1000.f; -+ g_pDebugOverlay->renderData(pMonitor, durationUs); - - if (*PDEBUGOVERLAY == 1) { - if (pMonitor == g_pCompositor->m_vMonitors.front().get()) { -- const float µsNoOverlay = µs - std::chrono::duration_cast(endRenderOverlay - renderStartOverlay).count() / 1000.f; -- g_pDebugOverlay->renderDataNoOverlay(pMonitor, µsNoOverlay); -+ const float noOverlayUs = durationUs - std::chrono::duration_cast(endRenderOverlay - renderStartOverlay).count() / 1000.f; -+ g_pDebugOverlay->renderDataNoOverlay(pMonitor, noOverlayUs); - } else { -- g_pDebugOverlay->renderDataNoOverlay(pMonitor, µs); -+ g_pDebugOverlay->renderDataNoOverlay(pMonitor, durationUs); - } - } - } -@@ -1658,7 +1661,7 @@ void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vectorgetMonitorFromID(monitor); - - if (!PMONITOR) -@@ -2155,6 +2158,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR - - for (auto& fmt : formats[(int)!RULE->enable10bit]) { - pMonitor->output->state->setFormat(fmt.second); -+ pMonitor->drmFormat = fmt.second; - - if (!pMonitor->state.test()) { - Debug::log(ERR, "output {} failed basic test on format {}", pMonitor->szName, fmt.first); -@@ -2299,7 +2303,7 @@ void CHyprRenderer::setCursorFromName(const std::string& name, bool force) { - } - - void CHyprRenderer::ensureCursorRenderingMode() { -- static auto PCURSORTIMEOUT = CConfigValue("cursor:inactive_timeout"); -+ static auto PCURSORTIMEOUT = CConfigValue("cursor:inactive_timeout"); - static auto PHIDEONTOUCH = CConfigValue("cursor:hide_on_touch"); - static auto PHIDEONKEY = CConfigValue("cursor:hide_on_key_press"); - -diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp -index 84501821..0b16efea 100644 ---- a/src/render/Renderer.hpp -+++ b/src/render/Renderer.hpp -@@ -49,7 +49,7 @@ class CHyprRenderer { - ~CHyprRenderer(); - - void renderMonitor(CMonitor* pMonitor); -- void arrangeLayersForMonitor(const int&); -+ void arrangeLayersForMonitor(const MONITORID&); - void damageSurface(SP, double, double, double scale = 1.0); - void damageWindow(PHLWINDOW, bool forceFull = false); - void damageBox(CBox*, bool skipFrameSchedule = false); -diff --git a/src/signal-safe.cpp b/src/signal-safe.cpp -index 05ca9c65..44d23f9b 100644 ---- a/src/signal-safe.cpp -+++ b/src/signal-safe.cpp -@@ -10,7 +10,7 @@ - extern char** environ; - - char const* sig_getenv(char const* name) { -- int len = strlen(name); -+ size_t len = strlen(name); - for (char** var = environ; *var != NULL; var++) { - if (strncmp(*var, name, len) == 0 && (*var)[len] == '=') { - return (*var) + len + 1; -diff --git a/src/signal-safe.hpp b/src/signal-safe.hpp -index 3a38f043..ef643097 100644 ---- a/src/signal-safe.hpp -+++ b/src/signal-safe.hpp -@@ -139,7 +139,7 @@ class BufFileWriter { - abort(); - } else { - close(pipefd[1]); -- int len; -+ long len; - char readbuf[256]; - while ((len = read(pipefd[0], readbuf, 256)) > 0) { - write(readbuf, len); -@@ -155,7 +155,7 @@ class BufFileWriter { - void flush() { - size_t i = 0; - while (i < m_writeBufPos) { -- int written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i); -+ auto written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i); - if (written <= 0) { - return; - } -diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp -index cec582f6..200bec70 100644 ---- a/src/xwayland/Server.cpp -+++ b/src/xwayland/Server.cpp -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - // TODO: cleanup - static bool set_cloexec(int fd, bool cloexec) { diff --git a/hosts/callisto/configuration.nix b/hosts/callisto/configuration.nix index f2136ed..bf1b379 100755 --- a/hosts/callisto/configuration.nix +++ b/hosts/callisto/configuration.nix @@ -45,7 +45,7 @@ oldAttrs.patches or [] ++ [ - ./asahi-fix.patch + ./0001-linux-dmabuf-allow-on-split-node-systems.patch ]; }); })