From bd332a79e7669f1dc05ce7ea6b5d78028f1f02bc Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 16 Mar 2024 18:12:32 +0200 Subject: [PATCH 0001/2772] Nix: match derivation to Nixpkgs --- nix/default.nix | 72 ++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/nix/default.nix b/nix/default.nix index a2a31818..91e132b2 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -14,6 +14,7 @@ jq, libGL, libdrm, + libexecinfo, libinput, libxcb, libxkbcommon, @@ -44,7 +45,9 @@ }: assert lib.assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed."; assert lib.assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed."; -assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland"; +assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland"; let + wlr = wlroots.override {inherit enableXWayland;}; +in stdenv.mkDerivation { pname = "hyprland${lib.optionalString debug "-debug"}"; inherit version; @@ -57,12 +60,36 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov src = lib.cleanSource ../.; }; + patches = [ + # make meson use the provided wlroots instead of the git submodule + ./patches/meson-build.patch + ]; + + postPatch = '' + # Fix hardcoded paths to /usr installation + sed -i "s#/usr#$out#" src/render/OpenGL.cpp + + # Generate version.h + cp src/version.h.in src/version.h + substituteInPlace src/version.h \ + --replace "@HASH@" '${commit}' \ + --replace "@BRANCH@" "" \ + --replace "@MESSAGE@" "" \ + --replace "@DATE@" "${date}" \ + --replace "@TAG@" "" \ + --replace "@DIRTY@" '${ + if commit == "" + then "dirty" + else "" + }' + ''; + nativeBuildInputs = [ jq + makeWrapper meson ninja pkg-config - makeWrapper wayland-scanner ]; @@ -90,8 +117,9 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov udis86 wayland wayland-protocols - wlroots + wlr ] + ++ lib.optionals stdenv.hostPlatform.isMusl [libexecinfo] ++ lib.optionals enableXWayland [libxcb xcbutilwm xwayland] ++ lib.optionals withSystemd [systemd]; @@ -102,38 +130,14 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov mesonAutoFeatures = "disabled"; - mesonFlags = builtins.concatLists [ - (lib.optional enableXWayland "-Dxwayland=enabled") - (lib.optional legacyRenderer "-Dlegacy_renderer=enabled") - (lib.optional withSystemd "-Dsystemd=enabled") + mesonFlags = [ + (lib.mesonEnable "xwayland" enableXWayland) + (lib.mesonEnable "legacy_renderer" legacyRenderer) + (lib.mesonEnable "systemd" withSystemd) ]; - patches = [ - # make meson use the provided wlroots instead of the git submodule - ./patches/meson-build.patch - ]; - - postPatch = '' - # Fix hardcoded paths to /usr installation - sed -i "s#/usr#$out#" src/render/OpenGL.cpp - - # Generate version.h - cp src/version.h.in src/version.h - substituteInPlace src/version.h \ - --replace "@HASH@" '${commit}' \ - --replace "@BRANCH@" "" \ - --replace "@MESSAGE@" "" \ - --replace "@DATE@" "${date}" \ - --replace "@TAG@" "" \ - --replace "@DIRTY@" '${ - if commit == "" - then "dirty" - else "" - }' - ''; - postInstall = '' - ln -s ${wlroots}/include/wlr $dev/include/hyprland/wlroots + ln -s ${wlr}/include/wlr $dev/include/hyprland/wlroots ${lib.optionalString wrapRuntimeDeps '' wrapProgram $out/bin/Hyprland \ @@ -148,10 +152,10 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov passthru.providedSessions = ["hyprland"]; meta = with lib; { - homepage = "https://github.com/vaxerski/Hyprland"; + homepage = "https://github.com/hyprwm/Hyprland"; description = "A dynamic tiling Wayland compositor that doesn't sacrifice on its looks"; license = licenses.bsd3; - platforms = platforms.linux; + platforms = wlr.meta.platforms; mainProgram = "Hyprland"; }; } From e566be7847b1d32c11291edb99b169f6b64fcebb Mon Sep 17 00:00:00 2001 From: Omar <147266582+somerand0mcat@users.noreply.github.com> Date: Sat, 16 Mar 2024 18:57:45 +0200 Subject: [PATCH 0002/2772] LICENSE: Update year (#5132) Updating the license year from 2022-2023 to 2022-2024 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 8ec509bd..a34afebb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2022-2023, vaxerski +Copyright (c) 2022-2024, vaxerski All rights reserved. Redistribution and use in source and binary forms, with or without From 3162739e1b555ba7d7b4643bf1ea4debd31007ce Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 16 Mar 2024 17:12:24 +0000 Subject: [PATCH 0003/2772] renderer: don't translate surface box on interactive resizes with non-updated sizes closes #5135 --- src/render/Renderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index cb60cd41..16d06a96 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -97,7 +97,8 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) Vector2D{windowBox.w * (PWINDOW->m_vReportedSize.x / PWINDOW->m_vRealSize.value().x), windowBox.h * (PWINDOW->m_vReportedSize.y / PWINDOW->m_vRealSize.value().y)}; Vector2D correct = Vector2D{windowBox.w, windowBox.h} - size; - windowBox.translate(correct / 2.0); + if (!INTERACTIVERESIZEINPROGRESS) + windowBox.translate(correct / 2.0); windowBox.w = size.x; windowBox.h = size.y; From 0e87a08e15c023325b64920d9e1159f38a090695 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 16 Mar 2024 17:56:09 +0000 Subject: [PATCH 0004/2772] renderer: disable surface adjustments for misaligned reported when manual resizing ref #5135 --- src/render/Renderer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 16d06a96..58f4b31a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -92,13 +92,12 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) } } - if (PSURFACE && PWINDOW && PWINDOW->m_vRealSize.goal() > PWINDOW->m_vReportedSize && PWINDOW->m_vReportedSize > Vector2D{1, 1}) { + if (!INTERACTIVERESIZEINPROGRESS && PSURFACE && PWINDOW && PWINDOW->m_vRealSize.goal() > PWINDOW->m_vReportedSize && PWINDOW->m_vReportedSize > Vector2D{1, 1}) { Vector2D size = Vector2D{windowBox.w * (PWINDOW->m_vReportedSize.x / PWINDOW->m_vRealSize.value().x), windowBox.h * (PWINDOW->m_vReportedSize.y / PWINDOW->m_vRealSize.value().y)}; Vector2D correct = Vector2D{windowBox.w, windowBox.h} - size; - if (!INTERACTIVERESIZEINPROGRESS) - windowBox.translate(correct / 2.0); + windowBox.translate(correct / 2.0); windowBox.w = size.x; windowBox.h = size.y; From 0387528c56c4d9faf93946cbc9426973de6ef61b Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:15:12 -0700 Subject: [PATCH 0005/2772] master: fix moving fullscreen workspace and remove duplicate code (#5131) --- src/layout/DwindleLayout.cpp | 49 +++++++++------------------ src/layout/DwindleLayout.hpp | 3 +- src/layout/MasterLayout.cpp | 65 ++++++++++++------------------------ 3 files changed, 39 insertions(+), 78 deletions(-) diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index cc4bc0b3..1ce6aa82 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -541,42 +541,24 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) { if (!PMONITOR) return; // ??? - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + g_pHyprRenderer->damageMonitor(PMONITOR); + + if (PMONITOR->specialWorkspaceID) + calculateWorkspace(PMONITOR->specialWorkspaceID); + + calculateWorkspace(PMONITOR->activeWorkspace); +} + +void CHyprDwindleLayout::calculateWorkspace(const int& ws) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); if (!PWORKSPACE) return; - g_pHyprRenderer->damageMonitor(PMONITOR); + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - if (PMONITOR->specialWorkspaceID) { - const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID); - - if (PSPECIALWS->m_bHasFullscreenWindow) { - const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PSPECIALWS->m_iID); - - if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_FULL) { - PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; - PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; - } else if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { - SDwindleNodeData fakeNode; - fakeNode.pWindow = PFULLWINDOW; - fakeNode.box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; - fakeNode.workspaceID = PSPECIALWS->m_iID; - PFULLWINDOW->m_vPosition = fakeNode.box.pos(); - PFULLWINDOW->m_vSize = fakeNode.box.size(); - fakeNode.ignoreFullscreenChecks = true; - - applyNodeDataToWindow(&fakeNode); - } - } - - const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->specialWorkspaceID); - - if (TOPNODE && PMONITOR) { - TOPNODE->box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; - TOPNODE->recalcSizePosRecursive(); - } - } + if (!PMONITOR) + return; if (PWORKSPACE->m_bHasFullscreenWindow) { // massive hack from the fullscreen func @@ -597,12 +579,13 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) { applyNodeDataToWindow(&fakeNode); } + // if has fullscreen, don't calculate the rest return; } - const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->activeWorkspace); + const auto TOPNODE = getMasterNodeOnWorkspace(ws); - if (TOPNODE && PMONITOR) { + if (TOPNODE) { TOPNODE->box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; TOPNODE->recalcSizePosRecursive(); } diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index fc73540a..5ca90fcd 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -78,6 +78,7 @@ class CHyprDwindleLayout : public IHyprLayout { int getNodesOnWorkspace(const int&); void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); + void calculateWorkspace(const int& ws); SDwindleNodeData* getNodeFromWindow(CWindow*); SDwindleNodeData* getFirstNodeOnWorkspace(const int&); SDwindleNodeData* getClosestNodeOnWorkspace(const int&, const Vector2D&); @@ -103,4 +104,4 @@ struct std::formatter : std::formatter { std::format_to(out, ", window: {:x}", node->pWindow); return std::format_to(out, "]"); } -}; \ No newline at end of file +}; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 9e7f8880..7919d50f 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -287,38 +287,24 @@ void CHyprMasterLayout::recalculateMonitor(const int& monid) { if (!PMONITOR) return; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + g_pHyprRenderer->damageMonitor(PMONITOR); + + if (PMONITOR->specialWorkspaceID) + calculateWorkspace(PMONITOR->specialWorkspaceID); + + calculateWorkspace(PMONITOR->activeWorkspace); +} + +void CHyprMasterLayout::calculateWorkspace(const int& ws) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); if (!PWORKSPACE) return; - g_pHyprRenderer->damageMonitor(PMONITOR); + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - if (PMONITOR->specialWorkspaceID) { - const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID); - - if (PSPECIALWS->m_bHasFullscreenWindow) { - const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PSPECIALWS->m_iID); - - if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_FULL) { - PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; - PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; - } else if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { - SMasterNodeData fakeNode; - fakeNode.pWindow = PFULLWINDOW; - fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; - fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; - fakeNode.workspaceID = PSPECIALWS->m_iID; - PFULLWINDOW->m_vPosition = fakeNode.position; - PFULLWINDOW->m_vSize = fakeNode.size; - fakeNode.ignoreFullscreenChecks = true; - - applyNodeDataToWindow(&fakeNode); - } - } - - calculateWorkspace(PMONITOR->specialWorkspaceID); - } + if (!PMONITOR) + return; if (PWORKSPACE->m_bHasFullscreenWindow) { // massive hack from the fullscreen func @@ -329,31 +315,22 @@ void CHyprMasterLayout::recalculateMonitor(const int& monid) { PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; } else if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { SMasterNodeData fakeNode; - fakeNode.pWindow = PFULLWINDOW; - fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; - fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; - fakeNode.workspaceID = PWORKSPACE->m_iID; - PFULLWINDOW->m_vPosition = fakeNode.position; - PFULLWINDOW->m_vSize = fakeNode.size; + fakeNode.pWindow = PFULLWINDOW; + fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; + fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; + fakeNode.workspaceID = PWORKSPACE->m_iID; + PFULLWINDOW->m_vPosition = fakeNode.position; + PFULLWINDOW->m_vSize = fakeNode.size; + fakeNode.ignoreFullscreenChecks = true; applyNodeDataToWindow(&fakeNode); } + // if has fullscreen, don't calculate the rest return; } - // calc the WS - calculateWorkspace(PWORKSPACE->m_iID); -} - -void CHyprMasterLayout::calculateWorkspace(const int& ws) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); - - if (!PWORKSPACE) - return; - const auto PWORKSPACEDATA = getMasterWorkspaceData(ws); - const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID); if (!PMASTERNODE) From e68c07d8096ee5f83e29508c8762279ab80a924b Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 17 Mar 2024 01:05:26 +0000 Subject: [PATCH 0006/2772] renderer: don't render window on other mons during anim in fixes #5139 --- src/Window.cpp | 1 + src/Window.hpp | 1 + src/events/Windows.cpp | 3 +++ src/helpers/AnimatedVariable.hpp | 5 +++++ src/render/Renderer.cpp | 4 ++++ 5 files changed, 14 insertions(+) diff --git a/src/Window.cpp b/src/Window.cpp index 06b71763..c6c958ba 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -524,6 +524,7 @@ void CWindow::onMap() { "CWindow"); m_vReportedSize = m_vPendingReportedSize; + m_bAnimatingIn = true; for (const auto& ctrl : g_pHyprRenderer->m_vTearingControllers) { if (ctrl->pWlrHint->surface != m_pWLSurface.wlr()) diff --git a/src/Window.hpp b/src/Window.hpp index cb4fc057..11bd86c8 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -296,6 +296,7 @@ class CWindow { Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in Vector2D m_vOriginalClosedSize; // drawing the closing animations SWindowDecorationExtents m_eOriginalClosedExtents; + bool m_bAnimatingIn = false; // For pinned (sticky) windows bool m_bPinned = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 1e547efc..f38c1fb0 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -36,6 +36,9 @@ void setAnimToMove(void* data) { CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data; animvar->setConfig(PANIMCFG); + + if (animvar->getWindow() && !animvar->getWindow()->m_vRealPosition.isBeingAnimated() && !animvar->getWindow()->m_vRealSize.isBeingAnimated()) + animvar->getWindow()->m_bAnimatingIn = false; } void Events::listener_mapWindow(void* owner, void* data) { diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 005f2832..88c775af 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -52,6 +52,7 @@ class CWorkspace; struct SLayerSurface; struct SAnimationPropertyConfig; class CHyprRenderer; +class CWindow; // Utility to define a concept as a list of possible type template @@ -135,6 +136,10 @@ class CBaseAnimatedVariable { m_bRemoveEndAfterRan = false; } + CWindow* getWindow() { + return (CWindow*)m_pWindow; + } + protected: void* m_pWindow = nullptr; void* m_pWorkspace = nullptr; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 58f4b31a..112be432 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -524,6 +524,10 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents(); } + // if window is tiled and it's flying in, don't render on other mons (for slide) + if (!ignorePosition && !pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID) + return; + // render window decorations first, if not fullscreen full if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { From 3ed3b34c4aea77484fa3325f9f95c001b8d6a0fa Mon Sep 17 00:00:00 2001 From: djvs <2954343+djvs@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:41:43 -0400 Subject: [PATCH 0007/2772] keybinds: add Dispatchers for "force float" and "force tiling" (non-toggle) (#5137) --------- Co-authored-by: djvs --- src/managers/KeybindManager.cpp | 19 ++++++++++++++++++- src/managers/KeybindManager.hpp | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2125e9ba..e45930af 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -25,6 +25,8 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["killactive"] = killActive; m_mDispatchers["closewindow"] = kill; m_mDispatchers["togglefloating"] = toggleActiveFloating; + m_mDispatchers["setfloating"] = setActiveFloating; + m_mDispatchers["settiled"] = setActiveTiled; m_mDispatchers["workspace"] = changeworkspace; m_mDispatchers["renameworkspace"] = renameWorkspace; m_mDispatchers["fullscreen"] = fullscreenActive; @@ -828,6 +830,18 @@ void CKeybindManager::clearKeybinds() { } void CKeybindManager::toggleActiveFloating(std::string args) { + return toggleActiveFloatingCore(args, std::nullopt); +} + +void CKeybindManager::setActiveFloating(std::string args) { + return toggleActiveFloatingCore(args, true); +} + +void CKeybindManager::setActiveTiled(std::string args) { + return toggleActiveFloatingCore(args, false); +} + +void toggleActiveFloatingCore(std::string args, std::optional floatState) { CWindow* PWINDOW = nullptr; if (args != "active" && args.length() > 1) @@ -838,12 +852,15 @@ void CKeybindManager::toggleActiveFloating(std::string args) { if (!PWINDOW) return; + if (floatState.has_value() && floatState == PWINDOW->m_bIsFloating) + return; + // remove drag status g_pInputManager->currentlyDraggedWindow = nullptr; if (PWINDOW->m_sGroupData.pNextWindow && PWINDOW->m_sGroupData.pNextWindow != PWINDOW) { + const auto PCURRENT = PWINDOW->getGroupCurrent(); - const auto PCURRENT = PWINDOW->getGroupCurrent(); PCURRENT->m_bIsFloating = !PCURRENT->m_bIsFloating; g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PCURRENT); diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 07b77398..5244918d 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -120,6 +120,8 @@ class CKeybindManager { static uint64_t spawnRaw(std::string); static void toggleActiveFloating(std::string); static void toggleActivePseudo(std::string); + static void setActiveFloating(std::string); + static void setActiveTiled(std::string); static void changeworkspace(std::string); static void fullscreenActive(std::string); static void fakeFullscreenActive(std::string); @@ -179,4 +181,6 @@ class CKeybindManager { friend class CConfigManager; }; +static void toggleActiveFloatingCore(std::string args, std::optional floatState); + inline std::unique_ptr g_pKeybindManager; From 3c21f5e07b853b1b37a7aa38a5084a114f0c1983 Mon Sep 17 00:00:00 2001 From: Zach DeCook Date: Sun, 17 Mar 2024 11:43:59 -0400 Subject: [PATCH 0008/2772] swipe: Touchscreen workspace swipe (#4489) * Workspace Swipe: Refactor update and end functions * Touch: Implement workspace swipe better ignoring additional fingers and new touches allow gaps-right and gaps-left to be different --- src/config/ConfigManager.cpp | 1 + src/helpers/WLClasses.hpp | 1 + src/managers/input/InputManager.hpp | 2 + src/managers/input/Swipe.cpp | 18 +++++++-- src/managers/input/Touch.cpp | 63 +++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 89195a27..ecb0937f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -498,6 +498,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("gestures:workspace_swipe_forever", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_numbered", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_use_r", Hyprlang::INT{0}); + m_pConfig->addConfigValue("gestures:workspace_swipe_touch", Hyprlang::INT{0}); m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1}); m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0}); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 5fc2692a..d48fdff7 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -283,6 +283,7 @@ struct SSwipeGesture { int initialDirection = 0; float avgSpeed = 0; int speedPoints = 0; + int touch_id = 0; CMonitor* pMonitor = nullptr; }; diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index fd3aefe5..d63de6ef 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -231,6 +231,8 @@ class CInputManager { // swipe void beginWorkspaceSwipe(); + void updateWorkspaceSwipe(double); + void endWorkspaceSwipe(); void setBorderCursorIcon(eBorderIconDirection); void setCursorIconOnBorder(CWindow* w); diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 937266af..68f7aa25 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -44,7 +44,10 @@ void CInputManager::beginWorkspaceSwipe() { void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { if (!m_sActiveSwipe.pWorkspaceBegin) return; // no valid swipe + endWorkspaceSwipe(); +} +void CInputManager::endWorkspaceSwipe() { static auto PSWIPEPERC = CConfigValue("gestures:workspace_swipe_cancel_ratio"); static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); static auto PSWIPEFORC = CConfigValue("gestures:workspace_swipe_min_speed_to_force"); @@ -192,11 +195,18 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { } void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); + const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); if (!m_sActiveSwipe.pWorkspaceBegin) return; + const double delta = m_sActiveSwipe.delta + (VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx)); + updateWorkspaceSwipe(delta); +} + +void CInputManager::updateWorkspaceSwipe(double delta) { static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); - static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); static auto PSWIPEDIRLOCK = CConfigValue("gestures:workspace_swipe_direction_lock"); static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue("gestures:workspace_swipe_direction_lock_threshold"); @@ -209,10 +219,10 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + const double d = m_sActiveSwipe.delta - delta; + m_sActiveSwipe.delta = delta; - m_sActiveSwipe.delta += VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx); - - m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1); + m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(d)) / (m_sActiveSwipe.speedPoints + 1); m_sActiveSwipe.speedPoints++; std::string wsname = ""; diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 3247a229..92f8316d 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -1,7 +1,15 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" +#include "../../config/ConfigValue.hpp" void CInputManager::onTouchDown(wlr_touch_down_event* e) { + static auto PSWIPETOUCH = CConfigValue("gestures:workspace_swipe_touch"); + static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); + auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData(); + // TODO: WORKSPACERULE.gapsOut.value_or() + auto gapsOut = *PGAPSOUT; + static auto PBORDERSIZE = CConfigValue("general:border_size"); + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); EMIT_HOOK_EVENT_CANCELLABLE("touchDown", e); auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : ""); @@ -24,6 +32,30 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { return; } + // Don't propagate new touches when a workspace swipe is in progress. + if (m_sActiveSwipe.pWorkspaceBegin) { + return; + // TODO: Don't swipe if you touched a floating window. + } else if (*PSWIPETOUCH && (!m_pFoundLSToFocus || m_pFoundLSToFocus->layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + // TODO: support no_gaps_when_only? + const double TARGETLEFT = ((VERTANIMS ? gapsOut.top : gapsOut.left) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x); + const double TARGETRIGHT = 1 - (((VERTANIMS ? gapsOut.bottom : gapsOut.right) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x)); + const double POSITION = (VERTANIMS ? e->y : e->x); + if (POSITION < TARGETLEFT || POSITION > TARGETRIGHT) { + beginWorkspaceSwipe(); + m_sActiveSwipe.touch_id = e->touch_id; + // Set the initial direction based on which edge you started from + if (POSITION > 0.5) + m_sActiveSwipe.initialDirection = *PSWIPEINVR ? -1 : 1; + else + m_sActiveSwipe.initialDirection = *PSWIPEINVR ? 1 : -1; + return; + } + } + m_bLastInputTouch = true; m_sTouchData.touchFocusWindow = m_pFoundWindowToFocus; @@ -55,6 +87,13 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { void CInputManager::onTouchUp(wlr_touch_up_event* e) { EMIT_HOOK_EVENT_CANCELLABLE("touchUp", e); + if (m_sActiveSwipe.pWorkspaceBegin) { + // If there was a swipe from this finger, end it. + if (e->touch_id == m_sActiveSwipe.touch_id) + endWorkspaceSwipe(); + return; + } + if (m_sTouchData.touchFocusSurface) { wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id); } @@ -62,6 +101,30 @@ void CInputManager::onTouchUp(wlr_touch_up_event* e) { void CInputManager::onTouchMove(wlr_touch_motion_event* e) { EMIT_HOOK_EVENT_CANCELLABLE("touchMove", e); + if (m_sActiveSwipe.pWorkspaceBegin) { + // Do nothing if this is using a different finger. + if (e->touch_id != m_sActiveSwipe.touch_id) + return; + const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); + static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); + // Handle the workspace swipe if there is one + if (m_sActiveSwipe.initialDirection == -1) { + if (*PSWIPEINVR) + // go from 0 to -PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * ((VERTANIMS ? e->y : e->x) - 1)); + else + // go from 0 to -PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (-1 * (VERTANIMS ? e->y : e->x))); + } else if (*PSWIPEINVR) + // go from 0 to PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (VERTANIMS ? e->y : e->x)); + else + // go from 0 to PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (1 - (VERTANIMS ? e->y : e->x))); + return; + } if (m_sTouchData.touchFocusWindow && g_pCompositor->windowValidMapped(m_sTouchData.touchFocusWindow)) { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID); From 30c5911718c02e0215bf0006faa6aa229558a501 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 17 Mar 2024 16:08:54 +0000 Subject: [PATCH 0009/2772] renderer: minor fixups for misaligned surface rendering offsets fixes #5136 --- src/Window.cpp | 3 +++ src/render/Renderer.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index c6c958ba..59ad5a3b 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1058,6 +1058,9 @@ bool CWindow::opaque() { if (m_fAlpha.value() != 1.f || m_fActiveInactiveAlpha.value() != 1.f) return false; + if (m_vRealSize.goal().floor() != m_vReportedSize) + return false; + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 112be432..e2bcbf1e 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -92,10 +92,12 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) } } - if (!INTERACTIVERESIZEINPROGRESS && PSURFACE && PWINDOW && PWINDOW->m_vRealSize.goal() > PWINDOW->m_vReportedSize && PWINDOW->m_vReportedSize > Vector2D{1, 1}) { - Vector2D size = - Vector2D{windowBox.w * (PWINDOW->m_vReportedSize.x / PWINDOW->m_vRealSize.value().x), windowBox.h * (PWINDOW->m_vReportedSize.y / PWINDOW->m_vRealSize.value().y)}; - Vector2D correct = Vector2D{windowBox.w, windowBox.h} - size; + if (!INTERACTIVERESIZEINPROGRESS && PSURFACE && PWINDOW && PWINDOW->m_vRealSize.goal().floor() > PWINDOW->m_vReportedSize && PWINDOW->m_vReportedSize > Vector2D{1, 1}) { + Vector2D coeff = PWINDOW->m_vReportedSize / PWINDOW->m_vRealSize.value(); + Vector2D coeff2 = PWINDOW->m_vReportedSize / PWINDOW->m_vRealSize.goal(); + + Vector2D size = Vector2D{windowBox.w, windowBox.h} * coeff; + Vector2D correct = Vector2D{windowBox.w, windowBox.h} - Vector2D{windowBox.w, windowBox.h} * coeff2; windowBox.translate(correct / 2.0); From c34ad12183506cb5f52bfb65b44e3a274e996fc3 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 17 Mar 2024 19:00:21 +0000 Subject: [PATCH 0010/2772] cursormgr: scale hotspot with buffer --- src/managers/CursorManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index c3916e4b..c4b624d4 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -128,8 +128,8 @@ void CCursorManager::setCursorFromName(const std::string& name) { Vector2D{m_sCurrentCursorShapeData.images[0].hotspotX, m_sCurrentCursorShapeData.images[0].hotspotY})); if (g_pCompositor->m_sWLRCursor) { - wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[0].hotspotX, m_sCurrentCursorShapeData.images[0].hotspotY, - m_fCursorScale); + wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[0].hotspotX / m_fCursorScale, + m_sCurrentCursorShapeData.images[0].hotspotY / m_fCursorScale, m_fCursorScale); if (m_vCursorBuffers.size() > 1) wlr_buffer_drop(&m_vCursorBuffers.front()->wlrBuffer.base); } @@ -160,8 +160,8 @@ void CCursorManager::tickAnimatedCursor() { Vector2D{m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotX, m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotY})); if (g_pCompositor->m_sWLRCursor) - wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotX, - m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotY, m_fCursorScale); + wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotX / m_fCursorScale, + m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotY / m_fCursorScale, m_fCursorScale); wl_event_source_timer_update(m_pAnimationTimer, m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].delay); } From 7587cadd0a4e94c9ba42c00307854052798cf9b2 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 04:15:04 +0000 Subject: [PATCH 0011/2772] renderer: add support for gles3.2 screen shaders --- src/render/OpenGL.cpp | 2 +- src/render/shaders/Textures.hpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 30803885..f79a10d1 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -547,7 +547,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { std::string fragmentShader((std::istreambuf_iterator(infile)), (std::istreambuf_iterator())); - m_sFinalScreenShader.program = createProgram(TEXVERTSRC, fragmentShader, true); + m_sFinalScreenShader.program = createProgram(fragmentShader.starts_with("#version 320 es") ? TEXVERTSRC320 : TEXVERTSRC, fragmentShader, true); if (!m_sFinalScreenShader.program) { g_pConfigManager->addParseError("Screen shader parser: Screen shader parse failed"); diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp index 5e346c1e..59c7304f 100644 --- a/src/render/shaders/Textures.hpp +++ b/src/render/shaders/Textures.hpp @@ -80,6 +80,17 @@ void main() { v_texcoord = texcoord; })#"; +inline const std::string TEXVERTSRC320 = R"#(#version 320 es +uniform mat3 proj; +in vec2 pos; +in vec2 texcoord; +out vec2 v_texcoord; + +void main() { + gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); + v_texcoord = texcoord; +})#"; + inline const std::string TEXFRAGSRCRGBA = R"#( precision highp float; varying vec2 v_texcoord; // is in 0-1 From 5eb33ff4d866ab64e5db33725473dc020fe355c1 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 16:35:22 +0000 Subject: [PATCH 0012/2772] screenshader: add screen_size uniform fixes #5059 --- src/render/OpenGL.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f79a10d1..c06c81dc 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -558,6 +558,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { m_sFinalScreenShader.tex = glGetUniformLocation(m_sFinalScreenShader.program, "tex"); m_sFinalScreenShader.time = glGetUniformLocation(m_sFinalScreenShader.program, "time"); m_sFinalScreenShader.wl_output = glGetUniformLocation(m_sFinalScreenShader.program, "wl_output"); + m_sFinalScreenShader.fullSize = glGetUniformLocation(m_sFinalScreenShader.program, "screen_size"); if (m_sFinalScreenShader.time != -1 && *PDT != 0 && !g_pHyprRenderer->m_bCrashingInProgress) { // The screen shader uses the "time" uniform // Since the screen shader could change every frame, damage tracking *needs* to be disabled @@ -852,6 +853,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* if (usingFinalShader && shader->wl_output != -1) glUniform1i(shader->wl_output, m_RenderData.pMonitor->ID); + if (usingFinalShader && shader->fullSize != -1) + glUniform2f(shader->fullSize, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y); if (CRASHING) { glUniform1f(shader->distort, g_pHyprRenderer->m_fCrashingDistort); From 4b74123649a42954453a7f4a452faa9ab94ecd08 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 18:11:20 +0000 Subject: [PATCH 0013/2772] socket2: add pin event fixes #4778 --- src/managers/KeybindManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e45930af..4b406cb6 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -2037,6 +2037,9 @@ void CKeybindManager::pinActive(std::string args) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS); + + g_pEventManager->postEvent(SHyprIPCEvent{"pin", std::format("{:x},{}", (uintptr_t)PWINDOW, (int)PWINDOW->m_bPinned)}); + EMIT_HOOK_EVENT("pin", PWINDOW); } void CKeybindManager::mouse(std::string args) { From 4ffcdc41ff8233a92f02c633475ac3472b0998df Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 18:29:57 +0000 Subject: [PATCH 0014/2772] animations: fix layer slide with fade fixes #5151 --- src/helpers/WLClasses.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index c71271c8..d46f7e40 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -87,7 +87,8 @@ void SLayerSurface::startAnimation(bool in, bool instant) { } realSize.setValueAndWarp(geometry.size()); - alpha.setValueAndWarp(1.f); + alpha.setValueAndWarp(in ? 0.f : 1.f); + alpha = in ? 1.f : 0.f; Vector2D prePos; From 7283dde8784ece1e5c0a47e9cbcc1696535ef098 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 23:51:32 +0000 Subject: [PATCH 0015/2772] screenShader: allow camel for screensize ref #5059 --- src/render/OpenGL.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index c06c81dc..c1375ba5 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -559,6 +559,8 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { m_sFinalScreenShader.time = glGetUniformLocation(m_sFinalScreenShader.program, "time"); m_sFinalScreenShader.wl_output = glGetUniformLocation(m_sFinalScreenShader.program, "wl_output"); m_sFinalScreenShader.fullSize = glGetUniformLocation(m_sFinalScreenShader.program, "screen_size"); + if (m_sFinalScreenShader.fullSize == -1) + m_sFinalScreenShader.fullSize = glGetUniformLocation(m_sFinalScreenShader.program, "screenSize"); if (m_sFinalScreenShader.time != -1 && *PDT != 0 && !g_pHyprRenderer->m_bCrashingInProgress) { // The screen shader uses the "time" uniform // Since the screen shader could change every frame, damage tracking *needs* to be disabled From 49f5fd59adbef25dc2c97364690fe747c8cc09e8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 02:42:30 +0000 Subject: [PATCH 0016/2772] opengl: minor adjustment to getPreferredReadFormat fixes #4791 --- src/protocols/ToplevelExport.cpp | 11 ----------- src/render/OpenGL.cpp | 6 +++--- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 88e56954..e3273f7a 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -179,17 +179,6 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou g_pHyprRenderer->makeEGLCurrent(); - if (g_pHyprOpenGL->m_mMonitorRenderResources.contains(PMONITOR)) { - const auto& RDATA = g_pHyprOpenGL->m_mMonitorRenderResources.at(PMONITOR); - // bind the fb for its format. Suppress gl errors. -#ifndef GLES2 - glBindFramebuffer(GL_READ_FRAMEBUFFER, RDATA.offloadFB.m_iFb); -#else - glBindFramebuffer(GL_FRAMEBUFFER, RDATA.offloadFB.m_iFb); -#endif - } else - Debug::log(ERR, "No RDATA in toplevelexport???"); - PFRAME->shmFormat = g_pHyprOpenGL->getPreferredReadFormat(PMONITOR); if (PFRAME->shmFormat == DRM_FORMAT_INVALID) { Debug::log(ERR, "No format supported by renderer in capture toplevel"); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index c1375ba5..d34a90b0 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2286,10 +2286,10 @@ inline const SGLPixelFormat GLES2_FORMATS[] = { }; uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) { - GLint glf = -1, glt = -1, as = -1; - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf); + GLint glf = -1, glt = -1, as = 0; + /*glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt); - glGetIntegerv(GL_ALPHA_BITS, &as); + glGetIntegerv(GL_ALPHA_BITS, &as);*/ if (glf == 0 || glt == 0) { glf = drmFormatToGL(pMonitor->drmFormat); From 7a31c954e5962db07b1b83e8a7340c38e7988ab6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 02:45:11 +0000 Subject: [PATCH 0017/2772] tablet: minor focus fixes ref #3004 --- src/managers/input/Tablets.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index f692620c..387212c7 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -39,7 +39,8 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { switch (EVENT->tool->type) { case WLR_TABLET_TOOL_TYPE_MOUSE: wlr_cursor_move(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, EVENT->dx, EVENT->dy); - g_pInputManager->refocus(); + g_pInputManager->simulateMouseMovement(); + g_pInputManager->focusTablet(PTAB, EVENT->tool, true); g_pInputManager->m_tmrLastCursorMovement.reset(); break; default: @@ -53,7 +54,8 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { else wlr_cursor_warp_absolute(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, x, y); - g_pInputManager->refocus(); + g_pInputManager->simulateMouseMovement(); + g_pInputManager->focusTablet(PTAB, EVENT->tool, true); g_pInputManager->m_tmrLastCursorMovement.reset(); break; } @@ -62,7 +64,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { // TODO: this might be wrong if (PTOOL->active) { - g_pInputManager->refocus(); + g_pInputManager->simulateMouseMovement(); g_pInputManager->focusTablet(PTAB, EVENT->tool, true); } @@ -105,7 +107,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { // TODO: this might be wrong if (EVENT->state == WLR_TABLET_TOOL_TIP_DOWN) { - g_pInputManager->refocus(); + g_pInputManager->simulateMouseMovement(); g_pInputManager->focusTablet(PTAB, EVENT->tool); wlr_send_tablet_v2_tablet_tool_down(PTOOL->wlrTabletToolV2); } else { @@ -146,7 +148,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { } else { PTOOL->active = true; - g_pInputManager->refocus(); + g_pInputManager->simulateMouseMovement(); g_pInputManager->focusTablet(PTAB, EVENT->tool); } @@ -258,12 +260,12 @@ void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool moti if (const auto PWINDOW = g_pCompositor->m_pLastWindow; PWINDOW) { const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal(); - if (PTOOL->pSurface != g_pCompositor->m_pLastFocus) + if (PTOOL->pSurface != g_pInputManager->m_pLastMouseSurface) wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2); - if (g_pCompositor->m_pLastFocus) { + if (g_pInputManager->m_pLastMouseSurface) { PTOOL->pSurface = g_pCompositor->m_pLastFocus; - wlr_tablet_v2_tablet_tool_notify_proximity_in(PTOOL->wlrTabletToolV2, pTab->wlrTabletV2, g_pCompositor->m_pLastFocus); + wlr_tablet_v2_tablet_tool_notify_proximity_in(PTOOL->wlrTabletToolV2, pTab->wlrTabletV2, g_pInputManager->m_pLastMouseSurface); } if (motion) { From e6532ba024762ba15423ae0a0935dfe4fb4196b1 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:52:52 -0700 Subject: [PATCH 0018/2772] animations: Fix incorrect animation when manually moving a window when its being created (#5141) * fix incorrect rendering when manually moving a window when its being created * add setAnimationsToMove --- src/Window.cpp | 9 +++++++++ src/Window.hpp | 1 + src/layout/DwindleLayout.cpp | 5 +++++ src/layout/IHyprLayout.cpp | 2 ++ src/layout/MasterLayout.cpp | 5 +++++ 5 files changed, 22 insertions(+) diff --git a/src/Window.cpp b/src/Window.cpp index 59ad5a3b..8130f017 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -389,6 +389,8 @@ void CWindow::moveToWorkspace(int workspaceID) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + setAnimationsToMove(); + updateSpecialRenderData(); if (PWORKSPACE) { @@ -1147,3 +1149,10 @@ bool CWindow::visibleOnMonitor(CMonitor* pMonitor) { return wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, wbox.pWlr()); } + +void CWindow::setAnimationsToMove() { + auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove"); + m_vRealPosition.setConfig(PANIMCFG); + m_vRealSize.setConfig(PANIMCFG); + m_bAnimatingIn = false; +} diff --git a/src/Window.hpp b/src/Window.hpp index 11bd86c8..8350e197 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -419,6 +419,7 @@ class CWindow { void insertWindowToGroup(CWindow* pWindow); void updateGroupOutputs(); void switchWithWindowInGroup(CWindow* pWindow); + void setAnimationsToMove(); private: // For hidden windows and stuff diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 1ce6aa82..c34f04cc 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -924,6 +924,8 @@ void CHyprDwindleLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) default: UNREACHABLE(); } + pWindow->setAnimationsToMove(); + onWindowRemovedTiling(pWindow); m_vOverrideFocalPoint = focalPoint; @@ -969,6 +971,9 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); } + pWindow->setAnimationsToMove(); + pWindow2->setAnimationsToMove(); + // recalc the workspace getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive(); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index f992899d..c8c00183 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -552,6 +552,8 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) { return; } + PWINDOW->setAnimationsToMove(); + PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta; g_pHyprRenderer->damageWindow(PWINDOW); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 7919d50f..1c6be8d6 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -970,6 +970,8 @@ void CHyprMasterLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) { const auto PWINDOW2 = g_pCompositor->getWindowInDirection(pWindow, dir[0]); + pWindow->setAnimationsToMove(); + if (pWindow->m_iWorkspaceID != PWINDOW2->m_iWorkspaceID) { // if different monitors, send to monitor onWindowRemovedTiling(pWindow); @@ -1002,6 +1004,9 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { PNODE->pWindow = pWindow2; PNODE2->pWindow = pWindow; + pWindow->setAnimationsToMove(); + pWindow2->setAnimationsToMove(); + recalculateMonitor(pWindow->m_iMonitorID); if (PNODE2->workspaceID != PNODE->workspaceID) recalculateMonitor(pWindow2->m_iMonitorID); From 7617c03dfd0073654ca8c4d9a6f5db278d14cd28 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 02:53:10 +0000 Subject: [PATCH 0019/2772] window: set config only when both props end anims --- src/events/Windows.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index f38c1fb0..7c4ae404 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -35,10 +35,10 @@ void setAnimToMove(void* data) { CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data; - animvar->setConfig(PANIMCFG); - - if (animvar->getWindow() && !animvar->getWindow()->m_vRealPosition.isBeingAnimated() && !animvar->getWindow()->m_vRealSize.isBeingAnimated()) + if (animvar->getWindow() && !animvar->getWindow()->m_vRealPosition.isBeingAnimated() && !animvar->getWindow()->m_vRealSize.isBeingAnimated()) { + animvar->setConfig(PANIMCFG); animvar->getWindow()->m_bAnimatingIn = false; + } } void Events::listener_mapWindow(void* owner, void* data) { From 05c84304ccb1169b550504830139e07e28500a3b Mon Sep 17 00:00:00 2001 From: Epilepsy Gatherings <73647246+phonetic112@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:53:51 -0400 Subject: [PATCH 0020/2772] github: remove redundant instruction (#5163) v0.34.0 is pretty old at this point. --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index b6582979..2305c650 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -13,7 +13,7 @@ body: id: ver attributes: label: Hyprland Version - description: "Paste here the output of `hyprctl version`. For hyprland after 0.34.0, paste `hyprctl systeminfo` instead." + description: "Paste the output of `hyprctl systeminfo` here." value: "
System/Version info From 5c1097cbc19131a7770b2a3f01f6f24e626991d2 Mon Sep 17 00:00:00 2001 From: joshua <54235339+sujoshua@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:54:33 +0800 Subject: [PATCH 0021/2772] IME: Improve handling of text-input and ime-relay (#5147) * input: Handling multiple surfaces for the text-input-v1 protocol implementation and imporve InputMethodRelay logic fixes #2708 * clang-format * minor style nits --------- Co-authored-by: Vaxry --- src/helpers/WLClasses.hpp | 9 +- src/managers/input/InputMethodRelay.cpp | 207 ++++++++++++++---------- src/managers/input/InputMethodRelay.hpp | 21 ++- src/protocols/TextInputV1.cpp | 8 +- 4 files changed, 145 insertions(+), 100 deletions(-) diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index d48fdff7..57f216b8 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -291,17 +291,14 @@ struct SSwipeGesture { struct STextInputV1; struct STextInput { - wlr_text_input_v3* pWlrInput = nullptr; - STextInputV1* pV1Input = nullptr; - - wlr_surface* pPendingSurface = nullptr; + wlr_text_input_v3* pWlrInput = nullptr; + STextInputV1* pV1Input = nullptr; + wlr_surface* focusedSurface = nullptr; DYNLISTENER(textInputEnable); DYNLISTENER(textInputDisable); DYNLISTENER(textInputCommit); DYNLISTENER(textInputDestroy); - - DYNLISTENER(pendingSurfaceDestroy); }; struct SIMEKbGrab { diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index fb668cc2..44ba3e42 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -87,14 +87,8 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { Debug::log(LOG, "IME Destroy"); - if (PTI) { - setPendingSurface(PTI, focusedSurface(PTI)); - - if (PTI->pWlrInput) - wlr_text_input_v3_send_leave(PTI->pWlrInput); - else - zwp_text_input_v1_send_leave(PTI->pV1Input->resourceImpl); - } + if (PTI) + onTextInputEnter(PTI->focusedSurface); }, this, "IMERelay"); @@ -144,16 +138,8 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { }, this, "IMERelay"); - const auto PTI = getFocusableTextInput(); - - if (PTI) { - if (PTI->pWlrInput) - wlr_text_input_v3_send_enter(PTI->pWlrInput, PTI->pPendingSurface); - else - zwp_text_input_v1_send_enter(PTI->pV1Input->resourceImpl, PTI->pPendingSurface->resource); - - setPendingSurface(PTI, nullptr); - } + if (const auto PTI = getFocusedTextInput(); PTI) + onTextInputEnter(PTI->focusedSurface); } wlr_surface* CInputMethodRelay::focusedSurface(STextInput* pTI) { @@ -322,22 +308,8 @@ SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) { } STextInput* CInputMethodRelay::getFocusedTextInput() { - - for (auto& ti : m_lTextInputs) { - if (focusedSurface(&ti)) { - return &ti; - } - } - - return nullptr; -} - -STextInput* CInputMethodRelay::getFocusableTextInput() { - for (auto& ti : m_lTextInputs) { - if (ti.pPendingSurface) { - return &ti; - } - } + if (m_pFocusedSurface) + return getTextInput(m_pFocusedSurface); return nullptr; } @@ -347,6 +319,13 @@ void CInputMethodRelay::onNewTextInput(wlr_text_input_v3* pInput) { } void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInputV1* pTIV1) { + + if (pInput) { + if (!setTextInputVersion(wl_resource_get_client(pInput->resource), 3)) + return; + } else if (!setTextInputVersion(pTIV1->client, 1)) + return; + const auto PTEXTINPUT = &m_lTextInputs.emplace_back(); PTEXTINPUT->pWlrInput = pInput; @@ -357,7 +336,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInput PTEXTINPUT->hyprListener_textInputEnable.initCallback( pInput ? &pInput->events.enable : &pTIV1->sEnable, - [](void* owner, void* data) { + [&](void* owner, void* data) { const auto PINPUT = (STextInput*)owner; if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { @@ -365,6 +344,15 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInput return; } + // v1 only, map surface to PTI + if (PINPUT->pV1Input) { + wlr_surface* pSurface = wlr_surface_from_resource((wl_resource*)data); + PINPUT->focusedSurface = pSurface; + setSurfaceToPTI(pSurface, PINPUT); + if (m_pFocusedSurface == pSurface) + onTextInputEnter(pSurface); + } + Debug::log(LOG, "Enable TextInput"); wlr_input_method_v2_send_activate(g_pInputManager->m_sIMERelay.m_pWLRIME); @@ -405,6 +393,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInput wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); + g_pInputManager->m_sIMERelay.removeSurfaceToPTI(PINPUT); g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); }, PTEXTINPUT, "textInput"); @@ -425,13 +414,13 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInput g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); } - g_pInputManager->m_sIMERelay.setPendingSurface(PINPUT, nullptr); - PINPUT->hyprListener_textInputCommit.removeCallback(); PINPUT->hyprListener_textInputDestroy.removeCallback(); PINPUT->hyprListener_textInputDisable.removeCallback(); PINPUT->hyprListener_textInputEnable.removeCallback(); + g_pInputManager->m_sIMERelay.removeTextInputVersion(PINPUT->pWlrInput ? wl_resource_get_client(PINPUT->pWlrInput->resource) : PINPUT->pV1Input->client); + g_pInputManager->m_sIMERelay.removeSurfaceToPTI(PINPUT); g_pInputManager->m_sIMERelay.removeTextInput(PINPUT); }, PTEXTINPUT, "textInput"); @@ -478,64 +467,110 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) { if (!m_pWLRIME) return; - auto client = [](STextInput* pTI) -> wl_client* { return pTI->pWlrInput ? wl_resource_get_client(pTI->pWlrInput->resource) : pTI->pV1Input->client; }; + if (pSurface == m_pFocusedSurface) + return; - for (auto& ti : m_lTextInputs) { - if (ti.pPendingSurface) { + // say goodbye to the last focused surface + if (STextInput* lastTI = getTextInput(m_pFocusedSurface); lastTI) { + wlr_input_method_v2_send_deactivate(m_pWLRIME); + commitIMEState(lastTI); + onTextInputLeave(m_pFocusedSurface); + } - if (pSurface != ti.pPendingSurface) - setPendingSurface(&ti, nullptr); + // do some work for the new focused surface + m_pFocusedSurface = pSurface; - } else if (focusedSurface(&ti)) { - - if (pSurface != focusedSurface(&ti)) { - wlr_input_method_v2_send_deactivate(m_pWLRIME); - commitIMEState(&ti); - - if (ti.pWlrInput) - wlr_text_input_v3_send_leave(ti.pWlrInput); - else { - zwp_text_input_v1_send_leave(ti.pV1Input->resourceImpl); - ti.pV1Input->focusedSurface = nullptr; - ti.pV1Input->active = false; - } - } else { - continue; - } - } - - if (pSurface && client(&ti) == wl_resource_get_client(pSurface->resource)) { - - if (m_pWLRIME) { - if (ti.pWlrInput) - wlr_text_input_v3_send_enter(ti.pWlrInput, pSurface); - else { - zwp_text_input_v1_send_enter(ti.pV1Input->resourceImpl, pSurface->resource); - ti.pV1Input->focusedSurface = pSurface; - ti.pV1Input->active = true; - } - } else { - setPendingSurface(&ti, pSurface); + /* + * v3 only. v1 is handled by hyprListener_textInputEnable. + * POSSIBLE BUG here: if one client has multiple STextInput and multiple surfaces, for any pSurface we can only record the last found ti. + * since original code has the same problem, it may not be a big deal. + */ + if (getTextInputVersion(wl_resource_get_client(pSurface->resource)) == 3) { + if (!getTextInput(pSurface)) { + auto client = [](STextInput* pTI) -> wl_client* { return pTI->pWlrInput ? wl_resource_get_client(pTI->pWlrInput->resource) : pTI->pV1Input->client; }; + for (auto& ti : m_lTextInputs) { + if (client(&ti) == wl_resource_get_client(pSurface->resource) && ti.pWlrInput) + setSurfaceToPTI(pSurface, &ti); } } } + + onTextInputEnter(m_pFocusedSurface); } -void CInputMethodRelay::setPendingSurface(STextInput* pInput, wlr_surface* pSurface) { - pInput->pPendingSurface = pSurface; +void CInputMethodRelay::onTextInputLeave(wlr_surface* pSurface) { + if (!pSurface) + return; + STextInput* ti = getTextInput(pSurface); + if (!ti) + return; + + if (ti->pWlrInput) + wlr_text_input_v3_send_leave(ti->pWlrInput); + else { + zwp_text_input_v1_send_leave(ti->pV1Input->resourceImpl); + ti->pV1Input->focusedSurface = nullptr; + ti->pV1Input->active = false; + } +} + +void CInputMethodRelay::onTextInputEnter(wlr_surface* pSurface) { + if (!pSurface) + return; + + STextInput* ti = getTextInput(pSurface); + if (!ti) + return; + + if (ti->pWlrInput) + wlr_text_input_v3_send_enter(ti->pWlrInput, pSurface); + else { + zwp_text_input_v1_send_enter(ti->pV1Input->resourceImpl, pSurface->resource); + ti->pV1Input->focusedSurface = pSurface; + ti->pV1Input->active = true; + } +} + +void CInputMethodRelay::setSurfaceToPTI(wlr_surface* pSurface, STextInput* pInput) { if (pSurface) { - pInput->hyprListener_pendingSurfaceDestroy.initCallback( - &pSurface->events.destroy, - [](void* owner, void* data) { - const auto PINPUT = (STextInput*)owner; - - PINPUT->pPendingSurface = nullptr; - - PINPUT->hyprListener_pendingSurfaceDestroy.removeCallback(); - }, - pInput, "TextInput"); - } else { - pInput->hyprListener_pendingSurfaceDestroy.removeCallback(); + m_mSurfaceToTextInput[pSurface] = pInput; + pInput->focusedSurface = pSurface; } } + +void CInputMethodRelay::removeSurfaceToPTI(STextInput* pInput) { + if (pInput->focusedSurface) { + m_mSurfaceToTextInput.erase(pInput->focusedSurface); + pInput->focusedSurface = nullptr; + } +} + +STextInput* CInputMethodRelay::getTextInput(wlr_surface* pSurface) { + auto result = m_mSurfaceToTextInput.find(pSurface); + if (result != m_mSurfaceToTextInput.end()) + return result->second; + + return nullptr; +} + +int CInputMethodRelay::setTextInputVersion(wl_client* pClient, int version) { + if (int v = getTextInputVersion(pClient); v != 0 && v != version) { + Debug::log(WARN, "Client attempt to register text-input-v{}, but it has already registered text-input-v{}, ignored", version, v); + return 0; + } + m_mClientTextInputVersion.insert({pClient, version}); + return 1; +} + +int CInputMethodRelay::getTextInputVersion(wl_client* pClient) { + auto result = m_mClientTextInputVersion.find(pClient); + if (result != m_mClientTextInputVersion.end()) + return result->second; + + return 0; +} + +void CInputMethodRelay::removeTextInputVersion(wl_client* pClient) { + m_mClientTextInputVersion.erase(pClient); +} diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 9f9e95f6..39465cab 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -22,9 +22,6 @@ class CInputMethodRelay { void onKeyboardFocus(wlr_surface*); STextInput* getFocusedTextInput(); - STextInput* getFocusableTextInput(); - - void setPendingSurface(STextInput*, wlr_surface*); SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*); @@ -45,8 +42,22 @@ class CInputMethodRelay { DYNLISTENER(IMEGrab); DYNLISTENER(IMENewPopup); - void createNewTextInput(wlr_text_input_v3*, STextInputV1* tiv1 = nullptr); - wlr_surface* focusedSurface(STextInput* pInput); + void createNewTextInput(wlr_text_input_v3*, STextInputV1* tiv1 = nullptr); + + wlr_surface* focusedSurface(STextInput* pInput); + wlr_surface* m_pFocusedSurface; + void onTextInputLeave(wlr_surface* pSurface); + void onTextInputEnter(wlr_surface* pSurface); + + std::unordered_map m_mSurfaceToTextInput; + void setSurfaceToPTI(wlr_surface* pSurface, STextInput* pInput); + STextInput* getTextInput(wlr_surface* pSurface); + void removeSurfaceToPTI(STextInput* pInput); + + std::unordered_map m_mClientTextInputVersion; + int setTextInputVersion(wl_client* pClient, int version); + int getTextInputVersion(wl_client* pClient); + void removeTextInputVersion(wl_client* pClient); friend class CHyprRenderer; friend class CInputManager; diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp index d69a79ca..8d1f6f97 100644 --- a/src/protocols/TextInputV1.cpp +++ b/src/protocols/TextInputV1.cpp @@ -113,8 +113,6 @@ void CTextInputV1ProtocolManager::removeTI(STextInputV1* pTI) { // if ((*TI)->resourceImpl) // wl_resource_destroy((*TI)->resourceImpl); - g_pInputManager->m_sIMERelay.removeTextInput((*TI)->pTextInput); - std::erase_if(m_pClients, [&](const auto& other) { return other.get() == pTI; }); } @@ -165,7 +163,11 @@ void CTextInputV1ProtocolManager::createTI(wl_client* client, wl_resource* resou void CTextInputV1ProtocolManager::handleActivate(wl_client* client, wl_resource* resource, wl_resource* seat, wl_resource* surface) { const auto PTI = tiFromResource(resource); - PTI->pTextInput->hyprListener_textInputEnable.emit(nullptr); + if (!surface) { + Debug::log(WARN, "Text-input-v1 PTI{:x}: No surface to activate text input on!", (uintptr_t)PTI); + return; + } + PTI->pTextInput->hyprListener_textInputEnable.emit(surface); } void CTextInputV1ProtocolManager::handleDeactivate(wl_client* client, wl_resource* resource, wl_resource* seat) { From bcba3951f45f11245d424274130eb3a0ac790d93 Mon Sep 17 00:00:00 2001 From: phonetic112 <73647246+phonetic112@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:03:31 -0400 Subject: [PATCH 0022/2772] input: Only limit drag resizes (#5164) * only limit drag resizes * change to not equals * remove extra parentheses --- src/layout/IHyprLayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index c8c00183..02f39d94 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -355,7 +355,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { canSkipUpdate = std::clamp(MSMONITOR - TIMERDELTA, 0.0, MSMONITOR) > totalMs * 1.0 / m_iMouseMoveEventCount; } - if ((abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f) || (TIMERDELTA < MSMONITOR && canSkipUpdate)) + if ((abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f) || (TIMERDELTA < MSMONITOR && canSkipUpdate && g_pInputManager->dragMode != MBIND_MOVE)) return; TIMER = std::chrono::high_resolution_clock::now(); From c32b2331d10605488d3f901189c975513c2823ad Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 18:55:17 +0000 Subject: [PATCH 0023/2772] constraint: set active flag before propagating props fixes #5170 --- src/desktop/Constraint.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/desktop/Constraint.cpp b/src/desktop/Constraint.cpp index 662f0990..2109ef1c 100644 --- a/src/desktop/Constraint.cpp +++ b/src/desktop/Constraint.cpp @@ -92,9 +92,10 @@ void CConstraint::deactivate() { if (!m_bActive) return; - wlr_pointer_constraint_v1_send_deactivated(m_pConstraint); m_bActive = false; + wlr_pointer_constraint_v1_send_deactivated(m_pConstraint); + if (isLocked()) g_pCompositor->warpCursorTo(logicPositionHint(), true); @@ -106,6 +107,8 @@ void CConstraint::activate() { if (m_bActive || m_bDead) return; + m_bActive = true; + // TODO: hack, probably not a super duper great idea if (g_pCompositor->m_sSeat.seat->pointer_state.focused_surface != m_pOwner->wlr()) { const auto SURFBOX = m_pOwner->getSurfaceBoxGlobal(); @@ -115,7 +118,6 @@ void CConstraint::activate() { g_pCompositor->warpCursorTo(logicPositionHint(), true); wlr_pointer_constraint_v1_send_activated(m_pConstraint); - m_bActive = true; } bool CConstraint::active() { From 05cd6d3df1e5faf3f7476724b0cfb156f4be43f6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 20:56:20 +0000 Subject: [PATCH 0024/2772] config/workspace: added workspace selectors --- src/Compositor.cpp | 4 +- src/Compositor.hpp | 2 +- src/Window.hpp | 14 +-- src/config/ConfigManager.cpp | 50 ++++---- src/desktop/Workspace.cpp | 202 ++++++++++++++++++++++++++++++++ src/desktop/Workspace.hpp | 2 + src/managers/KeybindManager.cpp | 4 +- 7 files changed, 239 insertions(+), 39 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 42ba9b5f..3ff67f20 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1290,10 +1290,10 @@ void CCompositor::sanityCheckWorkspaces() { } } -int CCompositor::getWindowsOnWorkspace(const int& id) { +int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTiled) { int no = 0; for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == id && w->m_bIsMapped) + if (w->m_iWorkspaceID == id && w->m_bIsMapped && !(onlyTiled.has_value() && !w->m_bIsFloating != onlyTiled.value())) no++; } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 84667656..56b83774 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -149,7 +149,7 @@ class CCompositor { CWorkspace* getWorkspaceByString(const std::string&); void sanityCheckWorkspaces(); void updateWorkspaceWindowDecos(const int&); - int getWindowsOnWorkspace(const int&); + int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}); CWindow* getUrgentWindow(); bool hasUrgentWindowOnWorkspace(const int&); CWindow* getFirstWindowOnWorkspace(const int&); diff --git a/src/Window.hpp b/src/Window.hpp index 8350e197..d98bc921 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -175,13 +175,13 @@ struct SWindowRule { std::string szClass; std::string szInitialTitle; std::string szInitialClass; - int bX11 = -1; // -1 means "ANY" - int bFloating = -1; - int bFullscreen = -1; - int bPinned = -1; - int bFocus = -1; - int iOnWorkspace = -1; - std::string szWorkspace = ""; // empty means any + int bX11 = -1; // -1 means "ANY" + int bFloating = -1; + int bFullscreen = -1; + int bPinned = -1; + int bFocus = -1; + std::string szOnWorkspace = ""; // empty means any + std::string szWorkspace = ""; // empty means any }; class CWindow { diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index ecb0937f..ee7b90bf 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -937,13 +937,7 @@ SMonitorRule CConfigManager::getMonitorRuleFor(const CMonitor& PMONITOR) { } SWorkspaceRule CConfigManager::getWorkspaceRuleFor(CWorkspace* pWorkspace) { - const auto WORKSPACEIDSTR = std::to_string(pWorkspace->m_iID); - const auto IT = std::find_if(m_dWorkspaceRules.begin(), m_dWorkspaceRules.end(), [&](const auto& other) { - return other.workspaceName == pWorkspace->m_szName /* name matches */ - || (pWorkspace->m_bIsSpecialWorkspace && other.workspaceName.starts_with("special:") && - other.workspaceName.substr(8) == pWorkspace->m_szName) /* special and special:name */ - || (pWorkspace->m_iID > 0 && WORKSPACEIDSTR == other.workspaceName); /* id matches and workspace is numerical */ - }); + const auto IT = std::find_if(m_dWorkspaceRules.begin(), m_dWorkspaceRules.end(), [&](const auto& other) { return pWorkspace->matchesStaticSelector(other.workspaceString); }); if (IT == m_dWorkspaceRules.end()) return SWorkspaceRule{}; return *IT; @@ -1039,8 +1033,9 @@ std::vector CConfigManager::getMatchingRules(CWindow* pWindow, bool continue; } - if (rule.iOnWorkspace != -1) { - if (rule.iOnWorkspace != g_pCompositor->getWindowsOnWorkspace(pWindow->m_iWorkspaceID)) + if (!rule.szOnWorkspace.empty()) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + if (!PWORKSPACE || !PWORKSPACE->matchesStaticSelector(rule.szOnWorkspace)) continue; } @@ -1327,9 +1322,8 @@ std::string CConfigManager::getBoundMonitorStringForWS(const std::string& wsname for (auto& wr : m_dWorkspaceRules) { const auto WSNAME = wr.workspaceName.starts_with("name:") ? wr.workspaceName.substr(5) : wr.workspaceName; - if (WSNAME == wsname) { + if (WSNAME == wsname) return wr.monitor; - } } return ""; @@ -2065,7 +2059,7 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& rule.bFocus = extract(FOCUSPOS + 6) == "1" ? 1 : 0; if (ONWORKSPACEPOS != std::string::npos) - rule.iOnWorkspace = configStringToInt(extract(ONWORKSPACEPOS + 12)); + rule.szOnWorkspace = extract(ONWORKSPACEPOS + 12); if (RULE == "unset") { std::erase_if(m_dWindowRules, [&](const SWindowRule& other) { @@ -2102,7 +2096,7 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& if (rule.bFocus != -1 && rule.bFocus != other.bFocus) return false; - if (rule.iOnWorkspace != -1 && rule.iOnWorkspace != other.iOnWorkspace) + if (!rule.szOnWorkspace.empty() && rule.szOnWorkspace != other.szOnWorkspace) return false; return true; @@ -2165,21 +2159,21 @@ std::optional CConfigManager::handleWorkspaceRules(const std::strin auto rules = value.substr(FIRST_DELIM + 1); SWorkspaceRule wsRule; wsRule.workspaceString = first_ident; - if (id == WORKSPACE_INVALID) { - // it could be the monitor. If so, second value MUST be - // the workspace. - const auto WORKSPACE_DELIM = value.find_first_of(',', FIRST_DELIM + 1); - auto wsIdent = removeBeginEndSpacesTabs(value.substr(FIRST_DELIM + 1, (WORKSPACE_DELIM - FIRST_DELIM - 1))); - id = getWorkspaceIDFromString(wsIdent, name); - if (id == WORKSPACE_INVALID) { - Debug::log(ERR, "Invalid workspace identifier found: {}", wsIdent); - return "Invalid workspace identifier found: " + wsIdent; - } - wsRule.monitor = first_ident; - wsRule.workspaceString = wsIdent; - wsRule.isDefault = true; // backwards compat - rules = value.substr(WORKSPACE_DELIM + 1); - } + // if (id == WORKSPACE_INVALID) { + // // it could be the monitor. If so, second value MUST be + // // the workspace. + // const auto WORKSPACE_DELIM = value.find_first_of(',', FIRST_DELIM + 1); + // auto wsIdent = removeBeginEndSpacesTabs(value.substr(FIRST_DELIM + 1, (WORKSPACE_DELIM - FIRST_DELIM - 1))); + // id = getWorkspaceIDFromString(wsIdent, name); + // if (id == WORKSPACE_INVALID) { + // Debug::log(ERR, "Invalid workspace identifier found: {}", wsIdent); + // return "Invalid workspace identifier found: " + wsIdent; + // } + // wsRule.monitor = first_ident; + // wsRule.workspaceString = wsIdent; + // wsRule.isDefault = true; // backwards compat + // rules = value.substr(WORKSPACE_DELIM + 1); + // } const static std::string ruleOnCreatedEmtpy = "on-created-empty:"; const static int ruleOnCreatedEmtpyLen = ruleOnCreatedEmtpy.length(); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 23f76309..42d59dbb 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -182,3 +182,205 @@ std::string CWorkspace::getConfigName() { return "name:" + m_szName; } + +bool CWorkspace::matchesStaticSelector(const std::string& selector_) { + auto selector = removeBeginEndSpacesTabs(selector_); + + if (selector.empty()) + return true; + + if (isNumber(selector)) { + + std::string wsname = ""; + int wsid = getWorkspaceIDFromString(selector, wsname); + + if (wsid == WORKSPACE_INVALID) + return false; + + return wsid == m_iID; + + } else if (selector.starts_with("name:")) { + return m_szName == selector.substr(5); + } else { + // parse selector + + for (size_t i = 0; i < selector.length(); ++i) { + const char& cur = selector[i]; + if (std::isspace(cur)) + continue; + + // Allowed selectors: + // r - range: r[1-5] + // s - special: s[true] + // n - named: n[true] or n[s:string] or n[e:string] + // m - monitor: m[monitor_selector] + // w - windowCount: w[0-4] or w[1], optional flag t or f for tiled or floating, e.g. w[t0-1] + + const auto NEXTSPACE = selector.find_first_of(' ', i); + std::string prop = selector.substr(i, NEXTSPACE == std::string::npos ? std::string::npos : NEXTSPACE - i); + i = NEXTSPACE; + + if (cur == 'r') { + int from = 0, to = 0; + if (!prop.starts_with("r[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + prop = prop.substr(2, prop.length() - 3); + + if (!prop.contains("-")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + const auto DASHPOS = prop.find("-"); + const auto LHS = prop.substr(0, DASHPOS), RHS = prop.substr(DASHPOS + 1); + + if (!isNumber(LHS) || !isNumber(RHS)) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + try { + from = std::stoll(LHS); + to = std::stoll(RHS); + } catch (std::exception& e) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + if (to < from || to < 1 || from < 1) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + if (std::clamp(m_iID, from, to) != m_iID) + return false; + continue; + } + + if (cur == 's') { + if (!prop.starts_with("s[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + prop = prop.substr(2, prop.length() - 3); + + const auto SHOULDBESPECIAL = configStringToInt(prop); + + if ((bool)SHOULDBESPECIAL != m_bIsSpecialWorkspace) + return false; + continue; + } + + if (cur == 'm') { + if (!prop.starts_with("m[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + prop = prop.substr(2, prop.length() - 3); + + const auto PMONITOR = g_pCompositor->getMonitorFromString(prop); + + if (!(PMONITOR ? PMONITOR->ID == m_iMonitorID : false)) + return false; + continue; + } + + if (cur == 'n') { + if (!prop.starts_with("n[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + prop = prop.substr(2, prop.length() - 3); + + if (prop.starts_with("s:")) + return m_szName.starts_with(prop.substr(2)); + if (prop.starts_with("e:")) + return m_szName.ends_with(prop.substr(2)); + + const auto WANTSNAMED = configStringToInt(prop); + + if (WANTSNAMED != (m_iID <= -1337)) + return false; + continue; + } + + if (cur == 'w') { + int from = 0, to = 0; + if (!prop.starts_with("w[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + prop = prop.substr(2, prop.length() - 3); + + int wantsOnlyTiled = -1; + + if (prop.starts_with("t")) { + wantsOnlyTiled = 1; + prop = prop.substr(1); + } else if (prop.starts_with("f")) { + wantsOnlyTiled = 0; + prop = prop.substr(1); + } + + if (!prop.contains("-")) { + // try single + + if (!isNumber(prop)) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + try { + from = std::stoll(prop); + } catch (std::exception& e) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + return g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)) == from; + } + + const auto DASHPOS = prop.find("-"); + const auto LHS = prop.substr(0, DASHPOS), RHS = prop.substr(DASHPOS + 1); + + if (!isNumber(LHS) || !isNumber(RHS)) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + try { + from = std::stoll(LHS); + to = std::stoll(RHS); + } catch (std::exception& e) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + if (to < from || to < 1 || from < 1) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + const auto WINDOWSONWORKSPACE = g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); + if (std::clamp(WINDOWSONWORKSPACE, from, to) != WINDOWSONWORKSPACE) + return false; + continue; + } + + Debug::log(LOG, "Invalid selector {}", selector); + return false; + } + + return true; + } + + UNREACHABLE(); + return false; +} \ No newline at end of file diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 15b7c0e2..f1bdb333 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -64,4 +64,6 @@ class CWorkspace { void rememberPrevWorkspace(const CWorkspace* prevWorkspace); std::string getConfigName(); + + bool matchesStaticSelector(const std::string& selector); }; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 4b406cb6..8a1d022b 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -871,10 +871,12 @@ void toggleActiveFloatingCore(std::string args, std::optional floatState) curr->updateSpecialRenderData(); curr = curr->m_sGroupData.pNextWindow; } + + g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); } else { PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; - PWINDOW->updateDynamicRules(); + g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); } From 07ab3b8cd654561ba346e40e16d44e918afa0ba0 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 19 Mar 2024 22:12:26 +0000 Subject: [PATCH 0025/2772] hyprpm: log shell in build without fails --- hyprpm/src/core/PluginManager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp index 725e6a93..c5926c3e 100644 --- a/hyprpm/src/core/PluginManager.cpp +++ b/hyprpm/src/core/PluginManager.cpp @@ -221,12 +221,12 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n"; } + if (m_bVerbose) + std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n"; + if (!std::filesystem::exists("/tmp/hyprpm/new/" + p.output)) { progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Plugin " + p.name + " failed to build.\n"); - if (m_bVerbose) - std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n"; - p.failed = true; continue; @@ -582,11 +582,12 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) { out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n"; } + if (m_bVerbose) + std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n"; + if (!std::filesystem::exists("/tmp/hyprpm/update/" + p.output)) { std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Plugin " << p.name << " failed to build.\n"; failed = true; - if (m_bVerbose) - std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n"; break; } From f6038837bc12a5f22808ceea0641dd9fe17d8094 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 20 Mar 2024 01:30:19 +0000 Subject: [PATCH 0026/2772] constraint: do not disable constraints in destroy fixes #5170 --- src/desktop/Constraint.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/desktop/Constraint.cpp b/src/desktop/Constraint.cpp index 2109ef1c..e7858321 100644 --- a/src/desktop/Constraint.cpp +++ b/src/desktop/Constraint.cpp @@ -33,8 +33,11 @@ void CConstraint::initSignals() { } void CConstraint::onDestroy() { - if (active()) - deactivate(); + hyprListener_setConstraintRegion.removeCallback(); + hyprListener_destroyConstraint.removeCallback(); + + if (active() && isLocked()) + g_pCompositor->warpCursorTo(logicPositionHint(), true); // this is us m_pOwner->m_pConstraint.reset(); From 8593c45be3cfe8055d13315051d88588f848ad39 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 20 Mar 2024 01:44:51 +0000 Subject: [PATCH 0027/2772] refactor: move window.hpp to desktop/ --- src/Compositor.hpp | 2 +- src/config/ConfigManager.hpp | 3 ++- src/{ => desktop}/Window.cpp | 10 +++++----- src/{ => desktop}/Window.hpp | 20 +++++++++---------- src/helpers/WLClasses.hpp | 2 +- src/layout/IHyprLayout.cpp | 1 + src/layout/IHyprLayout.hpp | 3 ++- src/managers/AnimationManager.cpp | 1 + src/managers/AnimationManager.hpp | 3 ++- src/managers/input/InputManager.cpp | 1 + src/managers/input/InputManager.hpp | 2 +- src/render/Renderer.cpp | 1 + src/render/Renderer.hpp | 2 +- .../decorations/IHyprWindowDecoration.cpp | 2 +- 14 files changed, 30 insertions(+), 23 deletions(-) rename src/{ => desktop}/Window.cpp (99%) rename src/{ => desktop}/Window.hpp (97%) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 56b83774..e226fdd3 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -22,7 +22,7 @@ #include "debug/HyprNotificationOverlay.hpp" #include "helpers/Monitor.hpp" #include "desktop/Workspace.hpp" -#include "Window.hpp" +#include "desktop/Window.hpp" #include "render/Renderer.hpp" #include "render/OpenGL.hpp" #include "hyprerror/HyprError.hpp" diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 2effb644..a00aaec9 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -13,7 +13,6 @@ #include #include #include -#include "../Window.hpp" #include "../helpers/WLClasses.hpp" #include "../helpers/Monitor.hpp" #include "../helpers/VarList.hpp" @@ -28,6 +27,8 @@ #define HANDLE void* +class CWindow; + struct SWorkspaceRule { std::string monitor = ""; std::string workspaceString = ""; diff --git a/src/Window.cpp b/src/desktop/Window.cpp similarity index 99% rename from src/Window.cpp rename to src/desktop/Window.cpp index 8130f017..567c3243 100644 --- a/src/Window.cpp +++ b/src/desktop/Window.cpp @@ -1,9 +1,9 @@ #include "Window.hpp" -#include "Compositor.hpp" -#include "render/decorations/CHyprDropShadowDecoration.hpp" -#include "render/decorations/CHyprGroupBarDecoration.hpp" -#include "render/decorations/CHyprBorderDecoration.hpp" -#include "config/ConfigValue.hpp" +#include "../Compositor.hpp" +#include "../render/decorations/CHyprDropShadowDecoration.hpp" +#include "../render/decorations/CHyprGroupBarDecoration.hpp" +#include "../render/decorations/CHyprBorderDecoration.hpp" +#include "../config/ConfigValue.hpp" CWindow::CWindow() { m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); diff --git a/src/Window.hpp b/src/desktop/Window.hpp similarity index 97% rename from src/Window.hpp rename to src/desktop/Window.hpp index d98bc921..3ec8a54c 100644 --- a/src/Window.hpp +++ b/src/desktop/Window.hpp @@ -1,16 +1,16 @@ #pragma once -#include "defines.hpp" -#include "desktop/Subsurface.hpp" -#include "helpers/AnimatedVariable.hpp" -#include "render/decorations/IHyprWindowDecoration.hpp" +#include "../defines.hpp" +#include "Subsurface.hpp" +#include "../helpers/AnimatedVariable.hpp" +#include "../render/decorations/IHyprWindowDecoration.hpp" #include -#include "config/ConfigDataValues.hpp" -#include "helpers/Vector2D.hpp" -#include "desktop/WLSurface.hpp" -#include "desktop/Popup.hpp" -#include "macros.hpp" -#include "managers/XWaylandManager.hpp" +#include "../config/ConfigDataValues.hpp" +#include "../helpers/Vector2D.hpp" +#include "WLSurface.hpp" +#include "Popup.hpp" +#include "../macros.hpp" +#include "../managers/XWaylandManager.hpp" enum eIdleInhibitMode { IDLEINHIBIT_NONE = 0, diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 57f216b8..806bf778 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -3,7 +3,7 @@ #include "../events/Events.hpp" #include "../defines.hpp" #include "wlr-layer-shell-unstable-v1-protocol.h" -#include "../Window.hpp" +#include "../desktop/Window.hpp" #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" #include "AnimatedVariable.hpp" diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 02f39d94..6a32144e 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -3,6 +3,7 @@ #include "../Compositor.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../config/ConfigValue.hpp" +#include "../desktop/Window.hpp" void IHyprLayout::onWindowCreated(CWindow* pWindow, eDirection direction) { if (pWindow->m_bIsFloating) { diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index d3f8dfa6..b5926a07 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -1,9 +1,10 @@ #pragma once #include "../defines.hpp" -#include "../Window.hpp" #include +class CWindow; + struct SWindowRenderLayoutHints { bool isBorderGradient = false; CGradientValueData* borderGradient; diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index f9dfa6fa..7d2a86e7 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -3,6 +3,7 @@ #include "HookSystemManager.hpp" #include "macros.hpp" #include "../config/ConfigValue.hpp" +#include "../desktop/Window.hpp" int wlTick(void* data) { if (g_pAnimationManager) diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index ae82a60b..483c9813 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -5,9 +5,10 @@ #include #include "../helpers/AnimatedVariable.hpp" #include "../helpers/BezierCurve.hpp" -#include "../Window.hpp" #include "../helpers/Timer.hpp" +class CWindow; + class CAnimationManager { public: CAnimationManager(); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 9072f27a..04981e4e 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -3,6 +3,7 @@ #include "wlr/types/wlr_switch.h" #include #include "../../config/ConfigValue.hpp" +#include "../../desktop/Window.hpp" CInputManager::~CInputManager() { m_vConstraints.clear(); diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index d63de6ef..128badfc 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -3,11 +3,11 @@ #include "../../defines.hpp" #include #include "../../helpers/WLClasses.hpp" -#include "../../Window.hpp" #include "../../helpers/Timer.hpp" #include "InputMethodRelay.hpp" class CConstraint; +class CWindow; enum eClickBehaviorMode { CLICKMODE_DEFAULT = 0, diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index e2bcbf1e..88035112 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -5,6 +5,7 @@ #include #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" +#include "../desktop/Window.hpp" extern "C" { #include diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index e480b26d..fd41a566 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -3,7 +3,6 @@ #include "../defines.hpp" #include #include "../helpers/Monitor.hpp" -#include "../Window.hpp" #include "OpenGL.hpp" #include "Renderbuffer.hpp" #include "../helpers/Timer.hpp" @@ -11,6 +10,7 @@ struct SMonitorRule; class CWorkspace; +class CWindow; // TODO: add fuller damage tracking for updating only parts of a window enum DAMAGETRACKINGMODES { diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp index 973f2700..a012848a 100644 --- a/src/render/decorations/IHyprWindowDecoration.cpp +++ b/src/render/decorations/IHyprWindowDecoration.cpp @@ -1,6 +1,6 @@ #include "IHyprWindowDecoration.hpp" -#include "../../Window.hpp" +class CWindow; IHyprWindowDecoration::IHyprWindowDecoration(CWindow* pWindow) { m_pWindow = pWindow; From 95ac8a34b1809375030b4ec2780a2b7a35ae8162 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:33:39 -0700 Subject: [PATCH 0028/2772] workspace: fix integer overflow in selector parser (#5177) --- src/desktop/Workspace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 42d59dbb..5a5e2c06 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -218,7 +218,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { const auto NEXTSPACE = selector.find_first_of(' ', i); std::string prop = selector.substr(i, NEXTSPACE == std::string::npos ? std::string::npos : NEXTSPACE - i); - i = NEXTSPACE; + i = std::min(NEXTSPACE, std::string::npos - 1); if (cur == 'r') { int from = 0, to = 0; @@ -383,4 +383,4 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { UNREACHABLE(); return false; -} \ No newline at end of file +} From 9ddf1b105e1b63a77b851af5e541a9412b0e0928 Mon Sep 17 00:00:00 2001 From: Khalid Date: Wed, 20 Mar 2024 07:00:43 +0300 Subject: [PATCH 0029/2772] tablet: Add left_handed option for tablets (#5178) * Add left_handed option for tablets * Update left_handed tablet option's fallback string --- src/config/ConfigManager.cpp | 1 + src/managers/input/InputManager.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index ee7b90bf..d671ffb0 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -476,6 +476,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("input:tablet:region_position", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:region_size", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:relative_input", Hyprlang::INT{0}); + m_pConfig->addConfigValue("input:tablet:left_handed", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:pass_mouse_when_bound", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:scroll_event_delay", Hyprlang::INT{300}); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 04981e4e..7d820c8f 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1418,6 +1418,11 @@ void CInputManager::setTabletConfigs() { Debug::log(LOG, "Setting calibration matrix for device {}", t.name); libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]); + if (g_pConfigManager->getDeviceInt(t.name, "left_handed", "input:tablet:left_handed") == 0) + libinput_device_config_left_handed_set(LIBINPUTDEV, 0); + else + libinput_device_config_left_handed_set(LIBINPUTDEV, 1); + const auto OUTPUT = g_pConfigManager->getDeviceString(t.name, "output", "input:tablet:output"); const auto PMONITOR = g_pCompositor->getMonitorFromString(OUTPUT); if (!OUTPUT.empty() && OUTPUT != STRVAL_EMPTY && PMONITOR) { From 361357095c26c70876e239a37458cb413e537af5 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 20 Mar 2024 18:05:57 +0000 Subject: [PATCH 0030/2772] workspace: fix selectors with special: fixes #5187 --- src/desktop/Workspace.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 5a5e2c06..d5f72384 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -201,6 +201,8 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { } else if (selector.starts_with("name:")) { return m_szName == selector.substr(5); + } else if (selector.starts_with("special:")) { + return m_szName == selector; } else { // parse selector From d904f51716cf939772bf2bc581bcfb30fb7ed12b Mon Sep 17 00:00:00 2001 From: Nathan Hadley <116459177+linfindel@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:11:40 +0000 Subject: [PATCH 0031/2772] README: Fix Preview B image (#5188) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70cce21d..1354fc6e 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more... [Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg [Preview A]: https://i.ibb.co/C1yTb0r/falf.png -[Preview B]: https://cdn.discordapp.com/attachments/1091569872535814185/1107675866101723277/screenshot-summer.png +[Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png [Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png From bfc95e992d460cbefe2c69de04da52e6089f6258 Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Thu, 21 Mar 2024 02:13:31 +0800 Subject: [PATCH 0032/2772] swipe: fix nullptr in `onSwipeUpdate` (#5191) --- src/managers/input/Swipe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 68f7aa25..5c3b7c28 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -195,11 +195,11 @@ void CInputManager::endWorkspaceSwipe() { } void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { + if (!m_sActiveSwipe.pWorkspaceBegin) + return; static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); - if (!m_sActiveSwipe.pWorkspaceBegin) - return; const double delta = m_sActiveSwipe.delta + (VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx)); updateWorkspaceSwipe(delta); From 214ec82ba7dcbb33b45963d13b84f9bd6c913614 Mon Sep 17 00:00:00 2001 From: Brett Alcox Date: Wed, 20 Mar 2024 20:54:10 -0500 Subject: [PATCH 0033/2772] build: fix builds without pch (#5198) --- src/layout/IHyprLayout.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index b5926a07..e168556e 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -4,6 +4,7 @@ #include class CWindow; +class CGradientValueData; struct SWindowRenderLayoutHints { bool isBorderGradient = false; From 4c796683c05a0eaccc14aae8875f06972f9f3c5e Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Wed, 20 Mar 2024 21:55:13 -0400 Subject: [PATCH 0034/2772] config: Config error limit/hyprctl (#5165) * Add error_limit to limit the number of config error messages shown in notification * Add configerrors hyprctl command * Formatting * Formatting for not my code * Use CVarList, add escapeJSONStrings * Add indication there are more undisplayed errors * Restore suppress_errors; move getErrors() to ConfigManager * Formatting, wtf * Format --- src/config/ConfigManager.cpp | 11 +++++++++++ src/config/ConfigManager.hpp | 2 ++ src/debug/HyprCtl.cpp | 25 +++++++++++++++++++++++++ src/hyprerror/HyprError.cpp | 19 ++++++++++++++++--- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index d671ffb0..7925da64 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -372,6 +372,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("debug:damage_tracking", {(Hyprlang::INT)DAMAGE_TRACKING_FULL}); m_pConfig->addConfigValue("debug:manual_crash", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:suppress_errors", Hyprlang::INT{0}); + m_pConfig->addConfigValue("debug:error_limit", Hyprlang::INT{5}); m_pConfig->addConfigValue("debug:watchdog_timeout", Hyprlang::INT{5}); m_pConfig->addConfigValue("debug:disable_scale_checks", Hyprlang::INT{0}); @@ -609,6 +610,10 @@ std::string CConfigManager::getMainConfigPath() { return getConfigDir() + "/hypr/" + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf"); } +std::string CConfigManager::getErrors() { + return m_szConfigErrors; +} + void CConfigManager::reload() { EMIT_HOOK_EVENT("preConfigReload", nullptr); setDefaultAnimationVars(); @@ -740,6 +745,12 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { g_pHyprOpenGL->m_bReloadScreenShader = true; // parseError will be displayed next frame + + if (result.error) + m_szConfigErrors = result.getError(); + else + m_szConfigErrors = ""; + if (result.error && !std::any_cast(m_pConfig->getConfigValue("debug:suppress_errors"))) g_pHyprError->queueCreate(result.getError(), CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); else if (std::any_cast(m_pConfig->getConfigValue("autogenerated")) == 1) diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index a00aaec9..9fd1e097 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -142,6 +142,7 @@ class CConfigManager { void addExecRule(const SExecRequestedRule&); void handlePluginLoads(); + std::string getErrors(); // keywords std::optional handleRawExec(const std::string&, const std::string&); @@ -193,6 +194,7 @@ class CConfigManager { std::deque firstExecRequests; std::vector> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins + std::string m_szConfigErrors = ""; // internal methods void setAnimForChildren(SAnimationPropertyConfig* const); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index f13843a3..211b532e 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -17,6 +17,7 @@ #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" +#include "../hyprerror/HyprError.hpp" static void trimTrailingComma(std::string& str) { if (!str.empty() && str.back() == ',') @@ -497,6 +498,29 @@ std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) { return result; } +std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) { + std::string result = ""; + std::string currErrors = g_pConfigManager->getErrors(); + CVarList errLines(currErrors, 0, '\n'); + if (format == eHyprCtlOutputFormat::FORMAT_JSON) { + result += "["; + for (auto line : errLines) { + result += std::format( + R"#( + "{}",)#", + + escapeJSONStrings(line)); + } + trimTrailingComma(result); + result += "\n]\n"; + } else { + for (auto line : errLines) { + result += std::format("{}\n", line); + } + } + return result; +} + std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; @@ -1531,6 +1555,7 @@ CHyprCtl::CHyprCtl() { registerCommand(SHyprCtlCommand{"animations", true, animationsRequest}); registerCommand(SHyprCtlCommand{"rollinglog", true, rollinglogRequest}); registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest}); + registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest}); registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest}); registerCommand(SHyprCtlCommand{"reload", false, reloadRequest}); diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 97a18e8c..a7636b1c 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -1,5 +1,6 @@ #include "HyprError.hpp" #include "../Compositor.hpp" +#include "../config/ConfigValue.hpp" CHyprError::CHyprError() { m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_NONE); @@ -58,6 +59,10 @@ void CHyprError::createQueued() { cairo_restore(CAIRO); const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n'); + static auto LINELIMIT = CConfigValue("debug:error_limit"); + + const auto VISLINECOUNT = std::min(LINECOUNT, *LINELIMIT); + const auto EXTRALINES = (VISLINECOUNT < LINECOUNT) ? 1 : 0; const double DEGREES = M_PI / 180.0; @@ -66,7 +71,7 @@ void CHyprError::createQueued() { const double X = PAD; const double Y = PAD; const double WIDTH = PMONITOR->vecPixelSize.x - PAD * 2; - const double HEIGHT = (FONTSIZE + 2 * (FONTSIZE / 10.0)) * LINECOUNT + 3; + const double HEIGHT = (FONTSIZE + 2 * (FONTSIZE / 10.0)) * (VISLINECOUNT + EXTRALINES) + 3; const double RADIUS = PAD > HEIGHT / 2 ? HEIGHT / 2 - 1 : PAD; m_bDamageBox = {0, 0, (int)PMONITOR->vecPixelSize.x, (int)HEIGHT + (int)PAD * 2}; @@ -91,8 +96,9 @@ void CHyprError::createQueued() { cairo_set_font_size(CAIRO, FONTSIZE); cairo_set_source_rgba(CAIRO, textColor.r, textColor.g, textColor.b, textColor.a); - float yoffset = FONTSIZE; - while (m_szQueued != "") { + float yoffset = FONTSIZE; + int renderedcnt = 0; + while (m_szQueued != "" && renderedcnt < VISLINECOUNT) { std::string current = m_szQueued.substr(0, m_szQueued.find('\n')); if (const auto NEWLPOS = m_szQueued.find('\n'); NEWLPOS != std::string::npos) m_szQueued = m_szQueued.substr(NEWLPOS + 1); @@ -101,7 +107,14 @@ void CHyprError::createQueued() { cairo_move_to(CAIRO, PAD + 1 + RADIUS, yoffset + PAD + 1); cairo_show_text(CAIRO, current.c_str()); yoffset += FONTSIZE + (FONTSIZE / 10.f); + renderedcnt++; } + if (VISLINECOUNT < LINECOUNT) { + std::string moreString = std::format("({} more...)", LINECOUNT - VISLINECOUNT); + cairo_move_to(CAIRO, PAD + 1 + RADIUS, yoffset + PAD + 1); + cairo_show_text(CAIRO, moreString.c_str()); + } + m_szQueued = ""; cairo_surface_flush(CAIROSURFACE); From ee00cb1dd87115f7c2b0fb41268e88050f28e7ed Mon Sep 17 00:00:00 2001 From: jill Date: Thu, 21 Mar 2024 17:46:23 +0300 Subject: [PATCH 0035/2772] opengl: report shader compilation errors from screen_shader (#5138) * opengl: report shader compilation errors from screen_shader * opengl: prefer .data() * opengl: move shader error logging to logError * opengl: quick glGetShaderiv -> glGetProgramiv fix * opengl: typo fix * opengl: format fixes * opengl: minor compile fixes * opengl: logError -> logShaderError --- src/render/OpenGL.cpp | 28 +++++++++++++++++++++++++--- src/render/OpenGL.hpp | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index d34a90b0..df03e8e9 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -59,6 +59,23 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_tGlobalTimer.reset(); } +void CHyprOpenGLImpl::logShaderError(const GLuint& shader, bool program) { + GLint maxLength = 0; + if (program) + glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + else + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector errorLog(maxLength); + if (program) + glGetProgramInfoLog(shader, maxLength, &maxLength, errorLog.data()); + else + glGetShaderInfoLog(shader, maxLength, &maxLength, errorLog.data()); + std::string errorStr(errorLog.begin(), errorLog.end()); + + g_pConfigManager->addParseError((program ? "Screen shader parser: Error linking program:" : "Screen shader parser: Error compiling shader: ") + errorStr); +} + GLuint CHyprOpenGLImpl::createProgram(const std::string& vert, const std::string& frag, bool dynamic) { auto vertCompiled = compileShader(GL_VERTEX_SHADER, vert, dynamic); if (dynamic) { @@ -89,8 +106,10 @@ GLuint CHyprOpenGLImpl::createProgram(const std::string& vert, const std::string GLint ok; glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (dynamic) { - if (ok == GL_FALSE) + if (ok == GL_FALSE) { + logShaderError(prog, true); return 0; + } } else { RASSERT(ok != GL_FALSE, "createProgram() failed! GL_LINK_STATUS not OK!"); } @@ -108,9 +127,12 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool GLint ok; glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); + if (dynamic) { - if (ok == GL_FALSE) + if (ok == GL_FALSE) { + logShaderError(shader, false); return 0; + } } else { RASSERT(ok != GL_FALSE, "compileShader() failed! GL_COMPILE_STATUS not OK!"); } @@ -550,7 +572,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { m_sFinalScreenShader.program = createProgram(fragmentShader.starts_with("#version 320 es") ? TEXVERTSRC320 : TEXVERTSRC, fragmentShader, true); if (!m_sFinalScreenShader.program) { - g_pConfigManager->addParseError("Screen shader parser: Screen shader parse failed"); + // Error will have been sent by now by the underlying cause return; } diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index f6dff805..b18e9108 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -219,6 +219,7 @@ class CHyprOpenGLImpl { CShader m_sFinalScreenShader; CTimer m_tGlobalTimer; + void logShaderError(const GLuint&, bool program = false); GLuint createProgram(const std::string&, const std::string&, bool dynamic = false); GLuint compileShader(const GLuint&, std::string, bool dynamic = false); void createBGTextureForMonitor(CMonitor*); From f1d06b773f2030b8ed62e3e5e8d753001ce064d2 Mon Sep 17 00:00:00 2001 From: Praneeth Jain Date: Thu, 21 Mar 2024 20:20:19 +0530 Subject: [PATCH 0036/2772] hyprpm: add missing newline (#5207) --- hyprpm/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyprpm/src/main.cpp b/hyprpm/src/main.cpp index e40d336d..38b32c83 100644 --- a/hyprpm/src/main.cpp +++ b/hyprpm/src/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char** argv, char** envp) { force = true; std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n"; } else { - std::cerr << "Unrecognized option " << ARGS[i]; + std::cerr << "Unrecognized option " << ARGS[i] << "\n"; return 1; } } else { From 997ee82bdf3c5783dffb3b5a34bff60362422780 Mon Sep 17 00:00:00 2001 From: Andrey Donets <142721811+Ligthiago@users.noreply.github.com> Date: Thu, 21 Mar 2024 18:57:06 +0400 Subject: [PATCH 0037/2772] hyprctl: add missing commands to usage (#5211) --- hyprctl/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 4d6066b5..b8072de9 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -30,6 +30,7 @@ commands: activeworkspace binds clients + configerrors cursorpos decorations devices @@ -45,8 +46,10 @@ commands: layouts monitors notify + output plugin reload + rollinglog setcursor seterror setprop From a94b902bef5eef3a4891726d51415c5d2e3391e3 Mon Sep 17 00:00:00 2001 From: Philipp Schilk Date: Thu, 21 Mar 2024 16:18:24 +0100 Subject: [PATCH 0038/2772] windowrules: Fix resizeparams parsing. (#5206) Parsing of resizeparams/relative vec2 did not correctly handle multiple spaces between x and y arguments, causing the following to fail to parse: bind = $mainMod CTRL, h, resizeactive, 10 0 This is unexpected, because most other config values are whitespace insensitive. --- src/Compositor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3ff67f20..f8138825 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2542,7 +2542,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con bool isExact = false; std::string x = args.substr(0, args.find_first_of(' ')); - std::string y = args.substr(args.find_first_of(' ') + 1); + std::string y = args.substr(args.find_last_of(' ') + 1); if (x == "exact") { x = y.substr(0, y.find_first_of(' ')); From 9bad62b85f179ad2c95c6e7f734768ef060a604b Mon Sep 17 00:00:00 2001 From: drendog <53359960+drendog@users.noreply.github.com> Date: Fri, 22 Mar 2024 02:28:50 +0100 Subject: [PATCH 0039/2772] layershell: release all mouse buttons before focus on new ls (#5219) --- src/events/Layers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index 4e61baa0..f4b52445 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -148,6 +148,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) { (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()); if (GRABSFOCUS) { + g_pInputManager->releaseAllMouseButtons(); g_pCompositor->focusSurface(layersurface->layerSurface->surface); const auto LOCAL = From c7c0e795d26b34391f0cb95fd900fc642316827f Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Fri, 22 Mar 2024 18:34:51 +0100 Subject: [PATCH 0040/2772] CGradientValueData: fix toString() method (#5220) --- src/config/ConfigDataValues.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config/ConfigDataValues.hpp b/src/config/ConfigDataValues.hpp index 39c60a5a..c162bb40 100644 --- a/src/config/ConfigDataValues.hpp +++ b/src/config/ConfigDataValues.hpp @@ -61,6 +61,7 @@ class CGradientValueData : public ICustomConfigValueData { } result += std::format("{}deg", (int)(m_fAngle * 180.0 / M_PI)); + return result; } }; From 397e08c16a7b7e414e8ef466e22fe5d4a581bafc Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Fri, 22 Mar 2024 17:41:20 +0000 Subject: [PATCH 0041/2772] input: focus window on mouse down on groupbar (#5224) modified: src/render/decorations/CHyprGroupBarDecoration.cpp --- src/render/decorations/CHyprGroupBarDecoration.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index defff9ba..a03d97f9 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -425,6 +425,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point const float BARRELATIVEX = pos.x - assignedBoxGlobal().x; const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); + static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); // close window on middle click if (e->button == 274) { @@ -453,6 +454,9 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point if (pWindow != m_pWindow) pWindow->setGroupCurrent(pWindow); + if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3) + g_pCompositor->focusWindow(pWindow); + if (pWindow->m_bIsFloating) g_pCompositor->changeWindowZOrder(pWindow, 1); From 461757e2fb39e166db83858d877fcbd730ece4aa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 22 Mar 2024 18:34:12 +0000 Subject: [PATCH 0042/2772] scripts: fix asan patch --- CMakeLists.txt | 1 + scripts/hyprlandStaticAsan.diff | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71766a8c..e039ceba 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) message(STATUS "Enabling ASan") target_link_libraries(Hyprland asan) + target_link_libraries(Hyprland ${CMAKE_SOURCE_DIR}/libwayland-server.a) target_compile_options(Hyprland PUBLIC -fsanitize=address) endif() diff --git a/scripts/hyprlandStaticAsan.diff b/scripts/hyprlandStaticAsan.diff index 5499f793..72a24914 100644 --- a/scripts/hyprlandStaticAsan.diff +++ b/scripts/hyprlandStaticAsan.diff @@ -1,13 +1,13 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 857e21de..122d6a78 100755 +index 71766a8c..bd8cdc0e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,7 +101,7 @@ message(STATUS "Checking deps...") find_package(Threads REQUIRED) find_package(PkgConfig REQUIRED) find_package(OpenGL REQUIRED) --pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2) # we do not check for wlroots, as we provide it ourselves -+pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2 libffi) # we do not check for wlroots, as we provide it ourselves +-pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2 hyprcursor) # we do not check for wlroots, as we provide it ourselves ++pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2 hyprcursor libffi) # we do not check for wlroots, as we provide it ourselves file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") @@ -18,4 +18,4 @@ index 857e21de..122d6a78 100755 + target_link_libraries(Hyprland ${CMAKE_SOURCE_DIR}/libwayland-server.a) target_compile_options(Hyprland PUBLIC -fsanitize=address) endif() - \ No newline at end of file + From d2b42e29c66fc0f6411ce64fa7e14e1b5fcc1c3f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 22 Mar 2024 18:45:24 +0000 Subject: [PATCH 0043/2772] IME: fix crashes with destroyed text-inputs ref #5189 --- src/helpers/WLClasses.cpp | 36 +++++++++++++++++++++++++ src/helpers/WLClasses.hpp | 4 +++ src/managers/input/InputMethodRelay.cpp | 21 ++++++++------- src/managers/input/InputMethodRelay.hpp | 1 + src/protocols/TextInputV1.hpp | 2 -- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index d46f7e40..1c14567d 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -244,3 +244,39 @@ void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { xkb_keymap_unref(NEWKEYMAP); xkb_context_unref(PCONTEXT); } + +void STextInput::setFocusedSurface(wlr_surface* pSurface) { + focusedSurface = pSurface; + + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + + if (!pSurface) + return; + + hyprListener_surfaceUnmapped.initCallback( + &pSurface->events.unmap, + [this](void* owner, void* data) { + if (!focusedSurface) + return; + + focusedSurface = nullptr; + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + g_pInputManager->m_sIMERelay.removeSurfaceToPTI(this); + }, + this, "STextInput"); + + hyprListener_surfaceDestroyed.initCallback( + &pSurface->events.destroy, + [this](void* owner, void* data) { + if (!focusedSurface) + return; + + focusedSurface = nullptr; + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + g_pInputManager->m_sIMERelay.removeSurfaceToPTI(this); + }, + this, "STextInput"); +} \ No newline at end of file diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 806bf778..210405f6 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -295,10 +295,14 @@ struct STextInput { STextInputV1* pV1Input = nullptr; wlr_surface* focusedSurface = nullptr; + void setFocusedSurface(wlr_surface* pSurface); + DYNLISTENER(textInputEnable); DYNLISTENER(textInputDisable); DYNLISTENER(textInputCommit); DYNLISTENER(textInputDestroy); + DYNLISTENER(surfaceUnmapped); + DYNLISTENER(surfaceDestroyed); }; struct SIMEKbGrab { diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 44ba3e42..89454d5b 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -143,7 +143,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { } wlr_surface* CInputMethodRelay::focusedSurface(STextInput* pTI) { - return pTI->pWlrInput ? pTI->pWlrInput->focused_surface : pTI->pV1Input->focusedSurface; + return pTI->pWlrInput ? pTI->pWlrInput->focused_surface : pTI->focusedSurface; } void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) { @@ -346,8 +346,8 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInput // v1 only, map surface to PTI if (PINPUT->pV1Input) { - wlr_surface* pSurface = wlr_surface_from_resource((wl_resource*)data); - PINPUT->focusedSurface = pSurface; + wlr_surface* pSurface = wlr_surface_from_resource((wl_resource*)data); + PINPUT->setFocusedSurface(pSurface); setSurfaceToPTI(pSurface, PINPUT); if (m_pFocusedSurface == pSurface) onTextInputEnter(pSurface); @@ -510,8 +510,8 @@ void CInputMethodRelay::onTextInputLeave(wlr_surface* pSurface) { wlr_text_input_v3_send_leave(ti->pWlrInput); else { zwp_text_input_v1_send_leave(ti->pV1Input->resourceImpl); - ti->pV1Input->focusedSurface = nullptr; - ti->pV1Input->active = false; + ti->setFocusedSurface(nullptr); + ti->pV1Input->active = false; } } @@ -527,23 +527,26 @@ void CInputMethodRelay::onTextInputEnter(wlr_surface* pSurface) { wlr_text_input_v3_send_enter(ti->pWlrInput, pSurface); else { zwp_text_input_v1_send_enter(ti->pV1Input->resourceImpl, pSurface->resource); - ti->pV1Input->focusedSurface = pSurface; - ti->pV1Input->active = true; + ti->setFocusedSurface(pSurface); + ti->pV1Input->active = true; } } void CInputMethodRelay::setSurfaceToPTI(wlr_surface* pSurface, STextInput* pInput) { if (pSurface) { m_mSurfaceToTextInput[pSurface] = pInput; - pInput->focusedSurface = pSurface; + pInput->setFocusedSurface(pSurface); } } void CInputMethodRelay::removeSurfaceToPTI(STextInput* pInput) { if (pInput->focusedSurface) { m_mSurfaceToTextInput.erase(pInput->focusedSurface); - pInput->focusedSurface = nullptr; + pInput->setFocusedSurface(nullptr); + return; } + + std::erase_if(m_mSurfaceToTextInput, [pInput](const auto& el) { return el.second == pInput; }); } STextInput* CInputMethodRelay::getTextInput(wlr_surface* pSurface) { diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 39465cab..6f99cae2 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -62,4 +62,5 @@ class CInputMethodRelay { friend class CHyprRenderer; friend class CInputManager; friend class CTextInputV1ProtocolManager; + friend struct STextInput; }; diff --git a/src/protocols/TextInputV1.hpp b/src/protocols/TextInputV1.hpp index b279763d..9362a52e 100644 --- a/src/protocols/TextInputV1.hpp +++ b/src/protocols/TextInputV1.hpp @@ -13,8 +13,6 @@ struct STextInputV1 { wl_resource* resourceImpl = nullptr; - wlr_surface* focusedSurface = nullptr; - STextInput* pTextInput = nullptr; wl_signal sEnable; From 568b352b235705d208df3190dfd878afd30913ca Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 22 Mar 2024 18:52:07 +0000 Subject: [PATCH 0044/2772] cmakelists: remove oopsie --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e039ceba..71766a8c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,7 +121,6 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) message(STATUS "Enabling ASan") target_link_libraries(Hyprland asan) - target_link_libraries(Hyprland ${CMAKE_SOURCE_DIR}/libwayland-server.a) target_compile_options(Hyprland PUBLIC -fsanitize=address) endif() From 8c88689faf691a4369528e6d3d52c024cd61125d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 22 Mar 2024 18:58:28 +0000 Subject: [PATCH 0045/2772] IME: guard unfocused TIs in leave --- src/managers/input/InputMethodRelay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 89454d5b..bdc46445 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -506,6 +506,9 @@ void CInputMethodRelay::onTextInputLeave(wlr_surface* pSurface) { if (!ti) return; + if (ti->pWlrInput && !ti->pWlrInput->focused_surface) + return; + if (ti->pWlrInput) wlr_text_input_v3_send_leave(ti->pWlrInput); else { From 9f2ed02f35232f0362db45d5f580025f5724500a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 22 Mar 2024 23:08:52 +0000 Subject: [PATCH 0046/2772] IME/TI: Fixes and refactoring Fixes #5189 --- src/helpers/WLClasses.cpp | 36 --- src/helpers/WLClasses.hpp | 19 +- src/managers/input/InputMethodRelay.cpp | 396 ++++-------------------- src/managers/input/InputMethodRelay.hpp | 35 +-- src/managers/input/TextInput.cpp | 273 ++++++++++++++++ src/managers/input/TextInput.hpp | 51 +++ src/protocols/TextInputV1.cpp | 10 +- src/protocols/TextInputV1.hpp | 4 +- 8 files changed, 403 insertions(+), 421 deletions(-) create mode 100644 src/managers/input/TextInput.cpp create mode 100644 src/managers/input/TextInput.hpp diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 1c14567d..d46f7e40 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -244,39 +244,3 @@ void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { xkb_keymap_unref(NEWKEYMAP); xkb_context_unref(PCONTEXT); } - -void STextInput::setFocusedSurface(wlr_surface* pSurface) { - focusedSurface = pSurface; - - hyprListener_surfaceUnmapped.removeCallback(); - hyprListener_surfaceDestroyed.removeCallback(); - - if (!pSurface) - return; - - hyprListener_surfaceUnmapped.initCallback( - &pSurface->events.unmap, - [this](void* owner, void* data) { - if (!focusedSurface) - return; - - focusedSurface = nullptr; - hyprListener_surfaceUnmapped.removeCallback(); - hyprListener_surfaceDestroyed.removeCallback(); - g_pInputManager->m_sIMERelay.removeSurfaceToPTI(this); - }, - this, "STextInput"); - - hyprListener_surfaceDestroyed.initCallback( - &pSurface->events.destroy, - [this](void* owner, void* data) { - if (!focusedSurface) - return; - - focusedSurface = nullptr; - hyprListener_surfaceUnmapped.removeCallback(); - hyprListener_surfaceDestroyed.removeCallback(); - g_pInputManager->m_sIMERelay.removeSurfaceToPTI(this); - }, - this, "STextInput"); -} \ No newline at end of file diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 210405f6..a2e72282 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -288,23 +288,6 @@ struct SSwipeGesture { CMonitor* pMonitor = nullptr; }; -struct STextInputV1; - -struct STextInput { - wlr_text_input_v3* pWlrInput = nullptr; - STextInputV1* pV1Input = nullptr; - wlr_surface* focusedSurface = nullptr; - - void setFocusedSurface(wlr_surface* pSurface); - - DYNLISTENER(textInputEnable); - DYNLISTENER(textInputDisable); - DYNLISTENER(textInputCommit); - DYNLISTENER(textInputDestroy); - DYNLISTENER(surfaceUnmapped); - DYNLISTENER(surfaceDestroyed); -}; - struct SIMEKbGrab { wlr_input_method_keyboard_grab_v2* pWlrKbGrab = nullptr; @@ -319,7 +302,7 @@ struct SIMEPopup { int x, y; int realX, realY; bool visible; - Vector2D lastSize; + CBox lastBox; DYNLISTENER(mapPopup); DYNLISTENER(unmapPopup); diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index bdc46445..13e4c9df 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -28,46 +28,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { return; } - if (PTI->pWlrInput) { - if (PIMR->m_pWLRIME->current.preedit.text) { - wlr_text_input_v3_send_preedit_string(PTI->pWlrInput, PIMR->m_pWLRIME->current.preedit.text, PIMR->m_pWLRIME->current.preedit.cursor_begin, - PIMR->m_pWLRIME->current.preedit.cursor_end); - } - - if (PIMR->m_pWLRIME->current.commit_text) { - wlr_text_input_v3_send_commit_string(PTI->pWlrInput, PIMR->m_pWLRIME->current.commit_text); - } - - if (PIMR->m_pWLRIME->current.delete_.before_length || PIMR->m_pWLRIME->current.delete_.after_length) { - wlr_text_input_v3_send_delete_surrounding_text(PTI->pWlrInput, PIMR->m_pWLRIME->current.delete_.before_length, PIMR->m_pWLRIME->current.delete_.after_length); - } - - wlr_text_input_v3_send_done(PTI->pWlrInput); - } else { - if (PIMR->m_pWLRIME->current.preedit.text) { - zwp_text_input_v1_send_preedit_cursor(PTI->pV1Input->resourceImpl, PIMR->m_pWLRIME->current.preedit.cursor_begin); - zwp_text_input_v1_send_preedit_styling(PTI->pV1Input->resourceImpl, 0, std::string(PIMR->m_pWLRIME->current.preedit.text).length(), - ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); - zwp_text_input_v1_send_preedit_string(PTI->pV1Input->resourceImpl, PTI->pV1Input->serial, PIMR->m_pWLRIME->current.preedit.text, ""); - } else { - zwp_text_input_v1_send_preedit_cursor(PTI->pV1Input->resourceImpl, PIMR->m_pWLRIME->current.preedit.cursor_begin); - zwp_text_input_v1_send_preedit_styling(PTI->pV1Input->resourceImpl, 0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); - zwp_text_input_v1_send_preedit_string(PTI->pV1Input->resourceImpl, PTI->pV1Input->serial, "", ""); - } - - if (PIMR->m_pWLRIME->current.commit_text) { - zwp_text_input_v1_send_commit_string(PTI->pV1Input->resourceImpl, PTI->pV1Input->serial, PIMR->m_pWLRIME->current.commit_text); - } - - if (PIMR->m_pWLRIME->current.delete_.before_length || PIMR->m_pWLRIME->current.delete_.after_length) { - zwp_text_input_v1_send_delete_surrounding_text(PTI->pV1Input->resourceImpl, - std::string(PIMR->m_pWLRIME->current.preedit.text).length() - PIMR->m_pWLRIME->current.delete_.before_length, - PIMR->m_pWLRIME->current.delete_.after_length + PIMR->m_pWLRIME->current.delete_.before_length); - - if (PIMR->m_pWLRIME->current.preedit.text) - zwp_text_input_v1_send_commit_string(PTI->pV1Input->resourceImpl, PTI->pV1Input->serial, PIMR->m_pWLRIME->current.preedit.text); - } - } + PTI->updateIMEState(PIMR->m_pWLRIME); }, this, "IMERelay"); @@ -88,7 +49,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { Debug::log(LOG, "IME Destroy"); if (PTI) - onTextInputEnter(PTI->focusedSurface); + PTI->enter(PTI->focusedSurface()); }, this, "IMERelay"); @@ -139,11 +100,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { this, "IMERelay"); if (const auto PTI = getFocusedTextInput(); PTI) - onTextInputEnter(PTI->focusedSurface); -} - -wlr_surface* CInputMethodRelay::focusedSurface(STextInput* pTI) { - return pTI->pWlrInput ? pTI->pWlrInput->focused_surface : pTI->focusedSurface; + PTI->enter(PTI->focusedSurface()); } void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) { @@ -151,63 +108,46 @@ void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) { return; // damage last known pos & size - g_pHyprRenderer->damageBox(pPopup->realX, pPopup->realY, pPopup->lastSize.x, pPopup->lastSize.y); + g_pHyprRenderer->damageBox(&pPopup->lastBox); const auto PFOCUSEDTI = getFocusedTextInput(); - if (!PFOCUSEDTI || !focusedSurface(PFOCUSEDTI)) + if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface()) return; - bool cursorRect = PFOCUSEDTI->pWlrInput ? PFOCUSEDTI->pWlrInput->current.features & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE : true; - const auto PFOCUSEDSURFACE = focusedSurface(PFOCUSEDTI); - CBox cursorBox = PFOCUSEDTI->pWlrInput ? PFOCUSEDTI->pWlrInput->current.cursor_rectangle : PFOCUSEDTI->pV1Input->cursorRectangle; - CMonitor* pMonitor = nullptr; + bool cursorRect = PFOCUSEDTI->hasCursorRectangle(); + const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface(); + CBox cursorBox = PFOCUSEDTI->cursorBox(); - Vector2D parentPos; - Vector2D parentSize; + CBox parentBox; - if (wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)) { - const auto PLS = g_pCompositor->getLayerSurfaceFromWlr(wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)); + const auto PSURFACE = CWLSurface::surfaceFromWlr(PFOCUSEDSURFACE); - if (PLS) { - parentPos = Vector2D(PLS->geometry.x, PLS->geometry.y) + g_pCompositor->getMonitorFromID(PLS->monitorID)->vecPosition; - parentSize = Vector2D(PLS->geometry.width, PLS->geometry.height); - pMonitor = g_pCompositor->getMonitorFromID(PLS->monitorID); - } - } else { - const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE); + if (!PSURFACE) + parentBox = {0, 0, 200, 200}; + else + parentBox = PSURFACE->getSurfaceBoxGlobal().value_or(CBox{0, 0, 200, 200}); - if (PWINDOW) { - parentPos = PWINDOW->m_vRealPosition.goal(); - parentSize = PWINDOW->m_vRealSize.goal(); - pMonitor = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); - } - } + if (!cursorRect) + cursorBox = {0, 0, (int)parentBox.w, (int)parentBox.h}; - if (!cursorRect) { - cursorBox = {0, 0, (int)parentSize.x, (int)parentSize.y}; - } + CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(cursorBox.middle()); - if (!pMonitor) - return; + if (cursorBox.y + parentBox.y + pPopup->pSurface->surface->current.height + cursorBox.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) + cursorBox.y -= pPopup->pSurface->surface->current.height + cursorBox.height; - CBox finalBox = cursorBox; + if (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) + cursorBox.x -= (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); - if (cursorBox.y + parentPos.y + pPopup->pSurface->surface->current.height + finalBox.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) - finalBox.y -= pPopup->pSurface->surface->current.height + finalBox.height; + pPopup->x = cursorBox.x; + pPopup->y = cursorBox.y + cursorBox.height; - if (cursorBox.x + parentPos.x + pPopup->pSurface->surface->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) - finalBox.x -= (cursorBox.x + parentPos.x + pPopup->pSurface->surface->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); + pPopup->realX = cursorBox.x + parentBox.x; + pPopup->realY = cursorBox.y + parentBox.y + cursorBox.height; - pPopup->x = finalBox.x; - pPopup->y = finalBox.y + finalBox.height; + pPopup->lastBox = cursorBox; - pPopup->realX = finalBox.x + parentPos.x; - pPopup->realY = finalBox.y + parentPos.y + finalBox.height; - - pPopup->lastSize = Vector2D(pPopup->pSurface->surface->current.width, pPopup->pSurface->surface->current.height); - - wlr_input_popup_surface_v2_send_text_input_rectangle(pPopup->pSurface, finalBox.pWlr()); + wlr_input_popup_surface_v2_send_text_input_rectangle(pPopup->pSurface, cursorBox.pWlr()); damagePopup(pPopup); } @@ -223,7 +163,7 @@ void Events::listener_mapInputPopup(void* owner, void* data) { g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP); - if (const auto PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PPOPUP->realX, PPOPUP->realY) + PPOPUP->lastSize / 2.f); PMONITOR) + if (const auto PMONITOR = g_pCompositor->getMonitorFromVector(PPOPUP->lastBox.middle()); PMONITOR) wlr_surface_send_enter(PPOPUP->pSurface->surface, PMONITOR->output); } @@ -232,7 +172,7 @@ void Events::listener_unmapInputPopup(void* owner, void* data) { Debug::log(LOG, "Unmapped an IME Popup"); - g_pHyprRenderer->damageBox(PPOPUP->realX, PPOPUP->realY, PPOPUP->lastSize.x, PPOPUP->lastSize.y); + g_pHyprRenderer->damageBox(&PPOPUP->lastBox); g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP); } @@ -267,12 +207,12 @@ void CInputMethodRelay::damagePopup(SIMEPopup* pPopup) { const auto PFOCUSEDTI = getFocusedTextInput(); - if (!PFOCUSEDTI || !focusedSurface(PFOCUSEDTI)) + if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface()) return; Vector2D parentPos; - const auto PFOCUSEDSURFACE = focusedSurface(PFOCUSEDTI); + const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface(); if (wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)) { const auto PLS = g_pCompositor->getLayerSurfaceFromWlr(wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)); @@ -307,276 +247,60 @@ SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) { return m_pKeyboardGrab.get(); } -STextInput* CInputMethodRelay::getFocusedTextInput() { - if (m_pFocusedSurface) - return getTextInput(m_pFocusedSurface); +CTextInput* CInputMethodRelay::getFocusedTextInput() { + if (!g_pCompositor->m_pLastFocus) + return nullptr; + + for (auto& ti : m_vTextInputs) { + if (ti->focusedSurface() == g_pCompositor->m_pLastFocus) + return ti.get(); + } return nullptr; } void CInputMethodRelay::onNewTextInput(wlr_text_input_v3* pInput) { - createNewTextInput(pInput); + m_vTextInputs.emplace_back(std::make_unique(pInput)); } -void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput, STextInputV1* pTIV1) { - - if (pInput) { - if (!setTextInputVersion(wl_resource_get_client(pInput->resource), 3)) - return; - } else if (!setTextInputVersion(pTIV1->client, 1)) - return; - - const auto PTEXTINPUT = &m_lTextInputs.emplace_back(); - - PTEXTINPUT->pWlrInput = pInput; - PTEXTINPUT->pV1Input = pTIV1; - - if (pTIV1) - pTIV1->pTextInput = PTEXTINPUT; - - PTEXTINPUT->hyprListener_textInputEnable.initCallback( - pInput ? &pInput->events.enable : &pTIV1->sEnable, - [&](void* owner, void* data) { - const auto PINPUT = (STextInput*)owner; - - if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { - // Debug::log(WARN, "Enabling TextInput on no IME!"); - return; - } - - // v1 only, map surface to PTI - if (PINPUT->pV1Input) { - wlr_surface* pSurface = wlr_surface_from_resource((wl_resource*)data); - PINPUT->setFocusedSurface(pSurface); - setSurfaceToPTI(pSurface, PINPUT); - if (m_pFocusedSurface == pSurface) - onTextInputEnter(pSurface); - } - - Debug::log(LOG, "Enable TextInput"); - - wlr_input_method_v2_send_activate(g_pInputManager->m_sIMERelay.m_pWLRIME); - g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); - }, - PTEXTINPUT, "textInput"); - - PTEXTINPUT->hyprListener_textInputCommit.initCallback( - pInput ? &pInput->events.commit : &pTIV1->sCommit, - [](void* owner, void* data) { - const auto PINPUT = (STextInput*)owner; - - if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { - // Debug::log(WARN, "Committing TextInput on no IME!"); - return; - } - - if (!(PINPUT->pWlrInput ? PINPUT->pWlrInput->current_enabled : PINPUT->pV1Input->active)) { - Debug::log(WARN, "Disabled TextInput commit?"); - return; - } - - g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); - }, - PTEXTINPUT, "textInput"); - - PTEXTINPUT->hyprListener_textInputDisable.initCallback( - pInput ? &pInput->events.disable : &pTIV1->sDisable, - [](void* owner, void* data) { - const auto PINPUT = (STextInput*)owner; - - if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { - // Debug::log(WARN, "Disabling TextInput on no IME!"); - return; - } - - Debug::log(LOG, "Disable TextInput"); - - wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); - - g_pInputManager->m_sIMERelay.removeSurfaceToPTI(PINPUT); - g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); - }, - PTEXTINPUT, "textInput"); - - PTEXTINPUT->hyprListener_textInputDestroy.initCallback( - pInput ? &pInput->events.destroy : &pTIV1->sDestroy, - [](void* owner, void* data) { - const auto PINPUT = (STextInput*)owner; - - if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { - // Debug::log(WARN, "Disabling TextInput on no IME!"); - return; - } - - if (PINPUT->pWlrInput && PINPUT->pWlrInput->current_enabled) { - wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); - - g_pInputManager->m_sIMERelay.commitIMEState(PINPUT); - } - - PINPUT->hyprListener_textInputCommit.removeCallback(); - PINPUT->hyprListener_textInputDestroy.removeCallback(); - PINPUT->hyprListener_textInputDisable.removeCallback(); - PINPUT->hyprListener_textInputEnable.removeCallback(); - - g_pInputManager->m_sIMERelay.removeTextInputVersion(PINPUT->pWlrInput ? wl_resource_get_client(PINPUT->pWlrInput->resource) : PINPUT->pV1Input->client); - g_pInputManager->m_sIMERelay.removeSurfaceToPTI(PINPUT); - g_pInputManager->m_sIMERelay.removeTextInput(PINPUT); - }, - PTEXTINPUT, "textInput"); +void CInputMethodRelay::onNewTextInput(STextInputV1* pTIV1) { + m_vTextInputs.emplace_back(std::make_unique(pTIV1)); } -void CInputMethodRelay::removeTextInput(STextInput* pInput) { - m_lTextInputs.remove_if([&](const auto& other) { return other.pWlrInput == pInput->pWlrInput && other.pV1Input == pInput->pV1Input; }); +void CInputMethodRelay::removeTextInput(CTextInput* pInput) { + m_vTextInputs.remove_if([&](const auto& other) { return other.get() == pInput; }); } -void CInputMethodRelay::commitIMEState(STextInput* pInput) { +void CInputMethodRelay::commitIMEState(CTextInput* pInput) { if (!m_pWLRIME) return; - if (pInput->pWlrInput) { - // V3 - if (pInput->pWlrInput->active_features & WLR_TEXT_INPUT_V3_FEATURE_SURROUNDING_TEXT) - wlr_input_method_v2_send_surrounding_text(m_pWLRIME, pInput->pWlrInput->current.surrounding.text, pInput->pWlrInput->current.surrounding.cursor, - pInput->pWlrInput->current.surrounding.anchor); - - wlr_input_method_v2_send_text_change_cause(m_pWLRIME, pInput->pWlrInput->current.text_change_cause); - - if (pInput->pWlrInput->active_features & WLR_TEXT_INPUT_V3_FEATURE_CONTENT_TYPE) - wlr_input_method_v2_send_content_type(m_pWLRIME, pInput->pWlrInput->current.content_type.hint, pInput->pWlrInput->current.content_type.purpose); - } else { - // V1 - if (pInput->pV1Input->pendingSurrounding.isPending) - wlr_input_method_v2_send_surrounding_text(m_pWLRIME, pInput->pV1Input->pendingSurrounding.text.c_str(), pInput->pV1Input->pendingSurrounding.cursor, - pInput->pV1Input->pendingSurrounding.anchor); - - wlr_input_method_v2_send_text_change_cause(m_pWLRIME, 0); - - if (pInput->pV1Input->pendingContentType.isPending) - wlr_input_method_v2_send_content_type(m_pWLRIME, pInput->pV1Input->pendingContentType.hint, pInput->pV1Input->pendingContentType.purpose); - } - - for (auto& p : m_lIMEPopups) { - updateInputPopup(&p); - } - - wlr_input_method_v2_send_done(m_pWLRIME); + pInput->commitStateToIME(m_pWLRIME); } void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) { if (!m_pWLRIME) return; - if (pSurface == m_pFocusedSurface) + if (pSurface == m_pLastKbFocus) return; - // say goodbye to the last focused surface - if (STextInput* lastTI = getTextInput(m_pFocusedSurface); lastTI) { - wlr_input_method_v2_send_deactivate(m_pWLRIME); - commitIMEState(lastTI); - onTextInputLeave(m_pFocusedSurface); + m_pLastKbFocus = pSurface; + + for (auto& ti : m_vTextInputs) { + if (!ti->focusedSurface()) + continue; + + ti->leave(); } - // do some work for the new focused surface - m_pFocusedSurface = pSurface; + for (auto& ti : m_vTextInputs) { + if (!ti->isV3()) + continue; - /* - * v3 only. v1 is handled by hyprListener_textInputEnable. - * POSSIBLE BUG here: if one client has multiple STextInput and multiple surfaces, for any pSurface we can only record the last found ti. - * since original code has the same problem, it may not be a big deal. - */ - if (getTextInputVersion(wl_resource_get_client(pSurface->resource)) == 3) { - if (!getTextInput(pSurface)) { - auto client = [](STextInput* pTI) -> wl_client* { return pTI->pWlrInput ? wl_resource_get_client(pTI->pWlrInput->resource) : pTI->pV1Input->client; }; - for (auto& ti : m_lTextInputs) { - if (client(&ti) == wl_resource_get_client(pSurface->resource) && ti.pWlrInput) - setSurfaceToPTI(pSurface, &ti); - } - } - } + if (ti->client() != wl_resource_get_client(pSurface->resource)) + continue; - onTextInputEnter(m_pFocusedSurface); -} - -void CInputMethodRelay::onTextInputLeave(wlr_surface* pSurface) { - if (!pSurface) - return; - - STextInput* ti = getTextInput(pSurface); - if (!ti) - return; - - if (ti->pWlrInput && !ti->pWlrInput->focused_surface) - return; - - if (ti->pWlrInput) - wlr_text_input_v3_send_leave(ti->pWlrInput); - else { - zwp_text_input_v1_send_leave(ti->pV1Input->resourceImpl); - ti->setFocusedSurface(nullptr); - ti->pV1Input->active = false; + ti->enter(pSurface); } } - -void CInputMethodRelay::onTextInputEnter(wlr_surface* pSurface) { - if (!pSurface) - return; - - STextInput* ti = getTextInput(pSurface); - if (!ti) - return; - - if (ti->pWlrInput) - wlr_text_input_v3_send_enter(ti->pWlrInput, pSurface); - else { - zwp_text_input_v1_send_enter(ti->pV1Input->resourceImpl, pSurface->resource); - ti->setFocusedSurface(pSurface); - ti->pV1Input->active = true; - } -} - -void CInputMethodRelay::setSurfaceToPTI(wlr_surface* pSurface, STextInput* pInput) { - if (pSurface) { - m_mSurfaceToTextInput[pSurface] = pInput; - pInput->setFocusedSurface(pSurface); - } -} - -void CInputMethodRelay::removeSurfaceToPTI(STextInput* pInput) { - if (pInput->focusedSurface) { - m_mSurfaceToTextInput.erase(pInput->focusedSurface); - pInput->setFocusedSurface(nullptr); - return; - } - - std::erase_if(m_mSurfaceToTextInput, [pInput](const auto& el) { return el.second == pInput; }); -} - -STextInput* CInputMethodRelay::getTextInput(wlr_surface* pSurface) { - auto result = m_mSurfaceToTextInput.find(pSurface); - if (result != m_mSurfaceToTextInput.end()) - return result->second; - - return nullptr; -} - -int CInputMethodRelay::setTextInputVersion(wl_client* pClient, int version) { - if (int v = getTextInputVersion(pClient); v != 0 && v != version) { - Debug::log(WARN, "Client attempt to register text-input-v{}, but it has already registered text-input-v{}, ignored", version, v); - return 0; - } - m_mClientTextInputVersion.insert({pClient, version}); - return 1; -} - -int CInputMethodRelay::getTextInputVersion(wl_client* pClient) { - auto result = m_mClientTextInputVersion.find(pClient); - if (result != m_mClientTextInputVersion.end()) - return result->second; - - return 0; -} - -void CInputMethodRelay::removeTextInputVersion(wl_client* pClient) { - m_mClientTextInputVersion.erase(pClient); -} diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 6f99cae2..7618400f 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -3,6 +3,7 @@ #include #include "../../defines.hpp" #include "../../helpers/WLClasses.hpp" +#include "TextInput.hpp" class CInputManager; struct STextInputV1; @@ -13,15 +14,16 @@ class CInputMethodRelay { void onNewIME(wlr_input_method_v2*); void onNewTextInput(wlr_text_input_v3*); + void onNewTextInput(STextInputV1* pTIV1); wlr_input_method_v2* m_pWLRIME = nullptr; - void commitIMEState(STextInput* pInput); - void removeTextInput(STextInput* pInput); + void commitIMEState(CTextInput* pInput); + void removeTextInput(CTextInput* pInput); void onKeyboardFocus(wlr_surface*); - STextInput* getFocusedTextInput(); + CTextInput* getFocusedTextInput(); SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*); @@ -31,10 +33,12 @@ class CInputMethodRelay { void removePopup(SIMEPopup*); private: - std::unique_ptr m_pKeyboardGrab; + std::unique_ptr m_pKeyboardGrab; - std::list m_lTextInputs; - std::list m_lIMEPopups; + std::list> m_vTextInputs; + std::list m_lIMEPopups; + + wlr_surface* m_pLastKbFocus = nullptr; DYNLISTENER(textInputNew); DYNLISTENER(IMECommit); @@ -42,25 +46,8 @@ class CInputMethodRelay { DYNLISTENER(IMEGrab); DYNLISTENER(IMENewPopup); - void createNewTextInput(wlr_text_input_v3*, STextInputV1* tiv1 = nullptr); - - wlr_surface* focusedSurface(STextInput* pInput); - wlr_surface* m_pFocusedSurface; - void onTextInputLeave(wlr_surface* pSurface); - void onTextInputEnter(wlr_surface* pSurface); - - std::unordered_map m_mSurfaceToTextInput; - void setSurfaceToPTI(wlr_surface* pSurface, STextInput* pInput); - STextInput* getTextInput(wlr_surface* pSurface); - void removeSurfaceToPTI(STextInput* pInput); - - std::unordered_map m_mClientTextInputVersion; - int setTextInputVersion(wl_client* pClient, int version); - int getTextInputVersion(wl_client* pClient); - void removeTextInputVersion(wl_client* pClient); - friend class CHyprRenderer; friend class CInputManager; friend class CTextInputV1ProtocolManager; - friend struct STextInput; + friend struct CTextInput; }; diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp new file mode 100644 index 00000000..a1916929 --- /dev/null +++ b/src/managers/input/TextInput.cpp @@ -0,0 +1,273 @@ +#include "TextInput.hpp" +#include "../../defines.hpp" +#include "InputManager.hpp" +#include "../../protocols/TextInputV1.hpp" +#include "../../Compositor.hpp" + +CTextInput::CTextInput(STextInputV1* ti) : pV1Input(ti) { + ti->pTextInput = this; + initCallbacks(); +} + +CTextInput::CTextInput(wlr_text_input_v3* ti) : pWlrInput(ti) { + initCallbacks(); +} + +CTextInput::~CTextInput() { + if (pV1Input) + pV1Input->pTextInput = nullptr; +} + +void CTextInput::tiV1Destroyed() { + pV1Input = nullptr; + + g_pInputManager->m_sIMERelay.removeTextInput(this); +} + +void CTextInput::initCallbacks() { + hyprListener_textInputEnable.initCallback( + isV3() ? &pWlrInput->events.enable : &pV1Input->sEnable, [this](void* owner, void* data) { onEnabled(); }, this, "textInput"); + + hyprListener_textInputCommit.initCallback( + isV3() ? &pWlrInput->events.commit : &pV1Input->sCommit, [this](void* owner, void* data) { onCommit(); }, this, "textInput"); + + hyprListener_textInputDisable.initCallback( + isV3() ? &pWlrInput->events.disable : &pV1Input->sDisable, [this](void* owner, void* data) { onDisabled(); }, this, "textInput"); + + hyprListener_textInputDestroy.initCallback( + isV3() ? &pWlrInput->events.destroy : &pV1Input->sDestroy, + [this](void* owner, void* data) { + if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { + // Debug::log(WARN, "Disabling TextInput on no IME!"); + return; + } + + if (pWlrInput && pWlrInput->current_enabled) { + wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); + + g_pInputManager->m_sIMERelay.commitIMEState(this); + } + + hyprListener_textInputCommit.removeCallback(); + hyprListener_textInputDestroy.removeCallback(); + hyprListener_textInputDisable.removeCallback(); + hyprListener_textInputEnable.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + hyprListener_surfaceUnmapped.removeCallback(); + + g_pInputManager->m_sIMERelay.removeTextInput(this); + }, + this, "textInput"); +} + +void CTextInput::onEnabled(wlr_surface* surfV1) { + Debug::log(LOG, "TI ENABLE"); + + if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { + // Debug::log(WARN, "Enabling TextInput on no IME!"); + return; + } + + // v1 only, map surface to PTI + if (!isV3()) { + wlr_surface* pSurface = surfV1; + setFocusedSurface(pSurface); + if (g_pCompositor->m_pLastFocus == pSurface) + enter(pSurface); + } + + wlr_input_method_v2_send_activate(g_pInputManager->m_sIMERelay.m_pWLRIME); + g_pInputManager->m_sIMERelay.commitIMEState(this); +} + +void CTextInput::onDisabled() { + if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { + // Debug::log(WARN, "Disabling TextInput on no IME!"); + return; + } + + leave(); + + hyprListener_surfaceDestroyed.removeCallback(); + hyprListener_surfaceUnmapped.removeCallback(); + + wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); + g_pInputManager->m_sIMERelay.commitIMEState(this); +} + +void CTextInput::onCommit() { + if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { + // Debug::log(WARN, "Committing TextInput on no IME!"); + return; + } + + if (!(pWlrInput ? pWlrInput->current_enabled : pV1Input->active)) { + Debug::log(WARN, "Disabled TextInput commit?"); + return; + } + + g_pInputManager->m_sIMERelay.commitIMEState(this); +} + +void CTextInput::setFocusedSurface(wlr_surface* pSurface) { + if (pSurface == pFocusedSurface) + return; + + pFocusedSurface = pSurface; + + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + + if (!pSurface) + return; + + hyprListener_surfaceUnmapped.initCallback( + &pSurface->events.unmap, + [this](void* owner, void* data) { + Debug::log(LOG, "Unmap TI owner1"); + + pFocusedSurface = nullptr; + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + }, + this, "CTextInput"); + + hyprListener_surfaceDestroyed.initCallback( + &pSurface->events.destroy, + [this](void* owner, void* data) { + Debug::log(LOG, "destroy TI owner1"); + + pFocusedSurface = nullptr; + hyprListener_surfaceUnmapped.removeCallback(); + hyprListener_surfaceDestroyed.removeCallback(); + }, + this, "CTextInput"); +} + +bool CTextInput::isV3() { + return pWlrInput; +} + +void CTextInput::enter(wlr_surface* pSurface) { + if (!pSurface || !pSurface->mapped) + return; + + if (pSurface == focusedSurface()) + return; + + if (focusedSurface()) { + leave(); + setFocusedSurface(nullptr); + } + + enterLocks++; + RASSERT(enterLocks == 1, "TextInput had != 1 lock in enter"); + + if (pWlrInput) + wlr_text_input_v3_send_enter(pWlrInput, pSurface); + else { + zwp_text_input_v1_send_enter(pV1Input->resourceImpl, pSurface->resource); + pV1Input->active = true; + } + + setFocusedSurface(pSurface); +} + +void CTextInput::leave() { + if (!focusedSurface()) + return; + + enterLocks--; + RASSERT(enterLocks == 0, "TextInput had != 0 locks in leave"); + + if (pWlrInput && pWlrInput->focused_surface) + wlr_text_input_v3_send_leave(pWlrInput); + else if (focusedSurface() && pV1Input) { + zwp_text_input_v1_send_leave(pV1Input->resourceImpl); + pV1Input->active = false; + } + + setFocusedSurface(nullptr); +} + +wlr_surface* CTextInput::focusedSurface() { + return pWlrInput ? pWlrInput->focused_surface : pFocusedSurface; +} + +wl_client* CTextInput::client() { + return pWlrInput ? wl_resource_get_client(pWlrInput->resource) : pV1Input->client; +} + +void CTextInput::commitStateToIME(wlr_input_method_v2* ime) { + if (isV3()) { + if (pWlrInput->active_features & WLR_TEXT_INPUT_V3_FEATURE_SURROUNDING_TEXT) + wlr_input_method_v2_send_surrounding_text(ime, pWlrInput->current.surrounding.text, pWlrInput->current.surrounding.cursor, pWlrInput->current.surrounding.anchor); + + wlr_input_method_v2_send_text_change_cause(ime, pWlrInput->current.text_change_cause); + + if (pWlrInput->active_features & WLR_TEXT_INPUT_V3_FEATURE_CONTENT_TYPE) + wlr_input_method_v2_send_content_type(ime, pWlrInput->current.content_type.hint, pWlrInput->current.content_type.purpose); + } else { + if (pV1Input->pendingSurrounding.isPending) + wlr_input_method_v2_send_surrounding_text(ime, pV1Input->pendingSurrounding.text.c_str(), pV1Input->pendingSurrounding.cursor, pV1Input->pendingSurrounding.anchor); + + wlr_input_method_v2_send_text_change_cause(ime, 0); + + if (pV1Input->pendingContentType.isPending) + wlr_input_method_v2_send_content_type(ime, pV1Input->pendingContentType.hint, pV1Input->pendingContentType.purpose); + } + + for (auto& p : g_pInputManager->m_sIMERelay.m_lIMEPopups) { + g_pInputManager->m_sIMERelay.updateInputPopup(&p); + } + + wlr_input_method_v2_send_done(ime); +} + +void CTextInput::updateIMEState(wlr_input_method_v2* ime) { + if (isV3()) { + if (ime->current.preedit.text) { + wlr_text_input_v3_send_preedit_string(pWlrInput, ime->current.preedit.text, ime->current.preedit.cursor_begin, ime->current.preedit.cursor_end); + } + + if (ime->current.commit_text) { + wlr_text_input_v3_send_commit_string(pWlrInput, ime->current.commit_text); + } + + if (ime->current.delete_.before_length || ime->current.delete_.after_length) { + wlr_text_input_v3_send_delete_surrounding_text(pWlrInput, ime->current.delete_.before_length, ime->current.delete_.after_length); + } + + wlr_text_input_v3_send_done(pWlrInput); + } else { + if (ime->current.preedit.text) { + zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preedit.cursor_begin); + zwp_text_input_v1_send_preedit_styling(pV1Input->resourceImpl, 0, std::string(ime->current.preedit.text).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); + zwp_text_input_v1_send_preedit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preedit.text, ""); + } else { + zwp_text_input_v1_send_preedit_cursor(pV1Input->resourceImpl, ime->current.preedit.cursor_begin); + zwp_text_input_v1_send_preedit_styling(pV1Input->resourceImpl, 0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); + zwp_text_input_v1_send_preedit_string(pV1Input->resourceImpl, pV1Input->serial, "", ""); + } + + if (ime->current.commit_text) { + zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.commit_text); + } + + if (ime->current.delete_.before_length || ime->current.delete_.after_length) { + zwp_text_input_v1_send_delete_surrounding_text(pV1Input->resourceImpl, std::string(ime->current.preedit.text).length() - ime->current.delete_.before_length, + ime->current.delete_.after_length + ime->current.delete_.before_length); + + if (ime->current.preedit.text) + zwp_text_input_v1_send_commit_string(pV1Input->resourceImpl, pV1Input->serial, ime->current.preedit.text); + } + } +} + +bool CTextInput::hasCursorRectangle() { + return !isV3() || pWlrInput->current.features & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; +} + +CBox CTextInput::cursorBox() { + return CBox{isV3() ? pWlrInput->current.cursor_rectangle : pV1Input->cursorRectangle}; +} \ No newline at end of file diff --git a/src/managers/input/TextInput.hpp b/src/managers/input/TextInput.hpp new file mode 100644 index 00000000..4acfb960 --- /dev/null +++ b/src/managers/input/TextInput.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "../../helpers/WLListener.hpp" +#include "../../macros.hpp" +#include "../../helpers/Box.hpp" + +struct wlr_text_input_v3; +struct wlr_surface; +struct wl_client; + +struct STextInputV1; + +class CTextInput { + public: + CTextInput(STextInputV1* ti); + CTextInput(wlr_text_input_v3* ti); + ~CTextInput(); + + bool isV3(); + void enter(wlr_surface* pSurface); + void leave(); + void tiV1Destroyed(); + wl_client* client(); + void commitStateToIME(wlr_input_method_v2* ime); + void updateIMEState(wlr_input_method_v2* ime); + + void onEnabled(wlr_surface* surfV1 = nullptr); + void onDisabled(); + void onCommit(); + + bool hasCursorRectangle(); + CBox cursorBox(); + + wlr_surface* focusedSurface(); + + private: + void setFocusedSurface(wlr_surface* pSurface); + void initCallbacks(); + + wlr_surface* pFocusedSurface = nullptr; + int enterLocks = 0; + wlr_text_input_v3* pWlrInput = nullptr; + STextInputV1* pV1Input = nullptr; + + DYNLISTENER(textInputEnable); + DYNLISTENER(textInputDisable); + DYNLISTENER(textInputCommit); + DYNLISTENER(textInputDestroy); + DYNLISTENER(surfaceUnmapped); + DYNLISTENER(surfaceDestroyed); +}; \ No newline at end of file diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp index 8d1f6f97..7535033a 100644 --- a/src/protocols/TextInputV1.cpp +++ b/src/protocols/TextInputV1.cpp @@ -131,7 +131,7 @@ static void destroyTI(wl_resource* resource) { wl_resource_set_user_data(resource, nullptr); } - TI->pTextInput->hyprListener_textInputDestroy.emit(nullptr); + TI->pTextInput->tiV1Destroyed(); g_pProtocolManager->m_pTextInputV1ProtocolManager->removeTI(TI); } @@ -158,7 +158,7 @@ void CTextInputV1ProtocolManager::createTI(wl_client* client, wl_resource* resou wl_signal_init(&PTI->sDestroy); wl_signal_init(&PTI->sCommit); - g_pInputManager->m_sIMERelay.createNewTextInput(nullptr, PTI); + g_pInputManager->m_sIMERelay.onNewTextInput(PTI); } void CTextInputV1ProtocolManager::handleActivate(wl_client* client, wl_resource* resource, wl_resource* seat, wl_resource* surface) { @@ -167,12 +167,12 @@ void CTextInputV1ProtocolManager::handleActivate(wl_client* client, wl_resource* Debug::log(WARN, "Text-input-v1 PTI{:x}: No surface to activate text input on!", (uintptr_t)PTI); return; } - PTI->pTextInput->hyprListener_textInputEnable.emit(surface); + PTI->pTextInput->onEnabled(wlr_surface_from_resource(surface)); } void CTextInputV1ProtocolManager::handleDeactivate(wl_client* client, wl_resource* resource, wl_resource* seat) { const auto PTI = tiFromResource(resource); - PTI->pTextInput->hyprListener_textInputDisable.emit(nullptr); + PTI->pTextInput->onDisabled(); } void CTextInputV1ProtocolManager::handleShowInputPanel(wl_client* client, wl_resource* resource) { @@ -212,7 +212,7 @@ void CTextInputV1ProtocolManager::handleSetPreferredLanguage(wl_client* client, void CTextInputV1ProtocolManager::handleCommitState(wl_client* client, wl_resource* resource, uint32_t serial) { const auto PTI = tiFromResource(resource); PTI->serial = serial; - PTI->pTextInput->hyprListener_textInputCommit.emit(nullptr); + PTI->pTextInput->onCommit(); } void CTextInputV1ProtocolManager::handleInvokeAction(wl_client* client, wl_resource* resource, uint32_t button, uint32_t index) { diff --git a/src/protocols/TextInputV1.hpp b/src/protocols/TextInputV1.hpp index 9362a52e..0a1203f0 100644 --- a/src/protocols/TextInputV1.hpp +++ b/src/protocols/TextInputV1.hpp @@ -5,7 +5,7 @@ #include -struct STextInput; +class CTextInput; struct STextInputV1 { wl_client* client = nullptr; @@ -13,7 +13,7 @@ struct STextInputV1 { wl_resource* resourceImpl = nullptr; - STextInput* pTextInput = nullptr; + CTextInput* pTextInput = nullptr; wl_signal sEnable; wl_signal sDisable; From 0dfdb6678f5362fda449694639e8fee806ca1ae4 Mon Sep 17 00:00:00 2001 From: fufexan Date: Sat, 23 Mar 2024 00:03:18 +0000 Subject: [PATCH 0047/2772] [gha] Nix: update inputs --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 9e6464f0..a883fa8e 100644 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ ] }, "locked": { - "lastModified": 1710257359, - "narHash": "sha256-43re5pzE/cswFAgw92/ugsB3+d5ufDaCcLtl9ztKfBo=", + "lastModified": 1711035742, + "narHash": "sha256-5vvhCSUGG9TA2G1eIRgokuYizhRnZu0ZbcU1MXfHsUE=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "1761f6cefd77f4fcd2039d930c88d6716ddc4974", + "rev": "6a92473237f430399a417e1c2da9d7fcd4970086", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1709914708, - "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=", + "lastModified": 1710960526, + "narHash": "sha256-tt0UgVKWeLQ+tFzvqrm4uAZbzONwdGshpfiLHAQ1P2c=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2", + "rev": "a2f39421144d42541c057be235154ce21b76c0f6", "type": "github" }, "original": { @@ -94,11 +94,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710272261, - "narHash": "sha256-g0bDwXFmTE7uGDOs9HcJsfLFhH7fOsASbAuOzDC+fhQ=", + "lastModified": 1711001935, + "narHash": "sha256-URtGpHue7HHZK0mrHnSf8wJ6OmMKYSsoLmJybrOLFSQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0ad13a6833440b8e238947e47bea7f11071dc2b2", + "rev": "20f77aa09916374aa3141cbc605c955626762c9a", "type": "github" }, "original": { From 059e85ae69e5d50bb6734532da4abdcf66167ab3 Mon Sep 17 00:00:00 2001 From: Khalid Date: Sat, 23 Mar 2024 23:31:03 +0300 Subject: [PATCH 0048/2772] input: Add options to set tablet's active area (#5199) * Add options to set tablet's active area * Set tablet's active area in `setTabletConfigs` * Fix formatting for new variables in ConfigManager * Report tablet's physical size with hyprctl --- src/config/ConfigManager.cpp | 12 ++++++++---- src/debug/HyprCtl.cpp | 2 +- src/helpers/WLClasses.hpp | 2 ++ src/managers/input/InputManager.cpp | 7 +++++++ src/managers/input/Tablets.cpp | 8 +++++++- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 7925da64..f0af317a 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -478,6 +478,8 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("input:tablet:region_size", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:relative_input", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:tablet:left_handed", Hyprlang::INT{0}); + m_pConfig->addConfigValue("input:tablet:active_area_position", Hyprlang::VEC2{0, 0}); + m_pConfig->addConfigValue("input:tablet:active_area_size", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("binds:pass_mouse_when_bound", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:scroll_event_delay", Hyprlang::INT{300}); @@ -554,10 +556,12 @@ CConfigManager::CConfigManager() { m_pConfig->addSpecialConfigValue("device", "scroll_points", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "transform", Hyprlang::INT{0}); m_pConfig->addSpecialConfigValue("device", "output", {STRVAL_EMPTY}); - m_pConfig->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices - m_pConfig->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets - m_pConfig->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets - m_pConfig->addSpecialConfigValue("device", "relative_input", Hyprlang::INT{0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices + m_pConfig->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "relative_input", Hyprlang::INT{0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "active_area_position", Hyprlang::VEC2{0, 0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "active_area_size", Hyprlang::VEC2{0, 0}); // only for tablets // keywords m_pConfig->registerHandler(&::handleRawExec, "exec", {false}); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 211b532e..903b7d7f 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -657,7 +657,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { } for (auto& d : g_pInputManager->m_lTablets) { - result += std::format("\tTablet at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.name); + result += std::format("\tTablet at {:x}:\n\t\t{}\n\t\t\tsize: {}x{}mm\n", (uintptr_t)&d, d.name, d.wlrTablet->width_mm, d.wlrTablet->height_mm); } for (auto& d : g_pInputManager->m_lTabletTools) { diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index a2e72282..dbe8d389 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -217,6 +217,8 @@ struct STablet { std::string boundOutput = ""; + CBox activeArea; + // bool operator==(const STablet& b) const { return wlrDevice == b.wlrDevice; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 7d820c8f..94e6abec 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1438,6 +1438,13 @@ void CInputManager::setTabletConfigs() { auto regionBox = CBox{REGION_POS.x, REGION_POS.y, REGION_SIZE.x, REGION_SIZE.y}; if (!regionBox.empty()) wlr_cursor_map_input_to_region(g_pCompositor->m_sWLRCursor, t.wlrDevice, regionBox.pWlr()); + + const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(t.name, "active_area_size", "input:tablet:active_area_size"); + const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(t.name, "active_area_position", "input:tablet:active_area_position"); + if (ACTIVE_AREA_SIZE.x != 0 || ACTIVE_AREA_SIZE.y != 0) { + t.activeArea = CBox{ACTIVE_AREA_POS.x / t.wlrTablet->width_mm, ACTIVE_AREA_POS.y / t.wlrTablet->height_mm, + (ACTIVE_AREA_POS.x + ACTIVE_AREA_SIZE.x) / t.wlrTablet->width_mm, (ACTIVE_AREA_POS.y + ACTIVE_AREA_SIZE.y) / t.wlrTablet->height_mm}; + } } } } diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index 387212c7..9252fca4 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -51,8 +51,14 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) { if (PTAB->relativeInput) wlr_cursor_move(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, dx, dy); - else + else { + // Calculate transformations if active area is set + if (!PTAB->activeArea.empty()) { + x = (x - PTAB->activeArea.x) / (PTAB->activeArea.w - PTAB->activeArea.x); + y = (y - PTAB->activeArea.y) / (PTAB->activeArea.h - PTAB->activeArea.y); + } wlr_cursor_warp_absolute(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, x, y); + } g_pInputManager->simulateMouseMovement(); g_pInputManager->focusTablet(PTAB, EVENT->tool, true); From 0d91f82d835b65f339726e3fbbd9c5347baabf7e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 23 Mar 2024 21:10:54 +0000 Subject: [PATCH 0049/2772] config: be a bit louder in the disabled log warning --- src/config/ConfigManager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f0af317a..11159131 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -586,11 +586,13 @@ CConfigManager::CConfigManager() { m_pConfig->commence(); - Debug::log(LOG, "NOTE: further logs to stdout / logfile are disabled by default. Use debug:disable_logs and debug:enable_stdout_logs to override this."); - setDefaultAnimationVars(); resetHLConfig(); + Debug::log(LOG, + "!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: " + "https://wiki.hyprland.org/Configuring/Variables/#debug"); + Debug::disableLogs = reinterpret_cast(m_pConfig->getConfigValuePtr("debug:disable_logs")->getDataStaticPtr()); Debug::disableTime = reinterpret_cast(m_pConfig->getConfigValuePtr("debug:disable_time")->getDataStaticPtr()); From 2d5fda4810f706a1b6e2c0a1021ce57c8ad2e7a9 Mon Sep 17 00:00:00 2001 From: Sungyoon Cho Date: Sun, 24 Mar 2024 06:12:27 +0900 Subject: [PATCH 0050/2772] input: fix crash with text-input-v1 (#5234) --- src/managers/input/TextInput.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index a1916929..827d4dbe 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -71,9 +71,10 @@ void CTextInput::onEnabled(wlr_surface* surfV1) { // v1 only, map surface to PTI if (!isV3()) { wlr_surface* pSurface = surfV1; - setFocusedSurface(pSurface); if (g_pCompositor->m_pLastFocus == pSurface) enter(pSurface); + else + setFocusedSurface(pSurface); } wlr_input_method_v2_send_activate(g_pInputManager->m_sIMERelay.m_pWLRIME); From 295128ab2a3c4ad1715bb7cd926880316f00e667 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 23 Mar 2024 22:10:37 +0000 Subject: [PATCH 0051/2772] window: assign surface on create ref #5076 --- src/desktop/Window.cpp | 5 ----- src/events/Windows.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 567c3243..3145000c 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -468,8 +468,6 @@ void CWindow::onUnmap() { std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other == this; }); - m_pWLSurface.unassign(); - hyprListener_unmapWindow.removeCallback(); if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(m_iWorkspaceID) == 0 && g_pCompositor->isWorkspaceSpecial(m_iWorkspaceID)) { @@ -493,9 +491,6 @@ void CWindow::onUnmap() { } void CWindow::onMap() { - - m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(this), this); - // JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped) m_vRealPosition.resetAllCallbacks(); m_vRealSize.resetAllCallbacks(); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 7c4ae404..056d9108 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -877,6 +877,8 @@ void Events::listener_destroyWindow(void* owner, void* data) { g_pCompositor->m_pLastFocus = nullptr; } + PWINDOW->m_pWLSurface.unassign(); + PWINDOW->hyprListener_commitWindow.removeCallback(); PWINDOW->hyprListener_mapWindow.removeCallback(); PWINDOW->hyprListener_unmapWindow.removeCallback(); @@ -1217,6 +1219,8 @@ void Events::listener_surfaceXWayland(wl_listener* listener, void* data) { PNEWWINDOW->hyprListener_destroyWindow.initCallback(&XWSURFACE->events.destroy, &Events::listener_destroyWindow, PNEWWINDOW, "XWayland Window"); PNEWWINDOW->hyprListener_setOverrideRedirect.initCallback(&XWSURFACE->events.set_override_redirect, &Events::listener_setOverrideRedirect, PNEWWINDOW, "XWayland Window"); PNEWWINDOW->hyprListener_configureX11.initCallback(&XWSURFACE->events.request_configure, &Events::listener_configureX11, PNEWWINDOW, "XWayland Window"); + + PNEWWINDOW->m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(PNEWWINDOW), PNEWWINDOW); } void Events::listener_newXDGToplevel(wl_listener* listener, void* data) { @@ -1232,6 +1236,8 @@ void Events::listener_newXDGToplevel(wl_listener* listener, void* data) { PNEWWINDOW->hyprListener_mapWindow.initCallback(&XDGSURFACE->surface->events.map, &Events::listener_mapWindow, PNEWWINDOW, "XDG Window"); PNEWWINDOW->hyprListener_destroyWindow.initCallback(&XDGSURFACE->events.destroy, &Events::listener_destroyWindow, PNEWWINDOW, "XDG Window"); PNEWWINDOW->hyprListener_commitWindow.initCallback(&XDGSURFACE->surface->events.commit, &Events::listener_commitWindow, PNEWWINDOW, "XDG Window"); + + PNEWWINDOW->m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(PNEWWINDOW), PNEWWINDOW); } void Events::listener_NewXDGDeco(wl_listener* listener, void* data) { From c7fbea3368452c34c47a4a634e642de6cd4090cb Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 23 Mar 2024 15:14:50 -0700 Subject: [PATCH 0052/2772] animations: Fix animation issue in focusworkspaceoncurrentmonitor (#5202) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * dont render when workspace offset * add guard * can remove useless code now if workspace offset is not taken into account * clang-format * when special workspace is moved, set anim to move * add offset back * make it a configurable option because some folks apparently can't align their monitors correctly and may not want this feature😔 * remove config option --- src/helpers/Monitor.cpp | 1 + src/managers/AnimationManager.cpp | 12 ++++++------ src/render/Renderer.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 9126f936..3edb7ca4 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -667,6 +667,7 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) { if (w->m_iWorkspaceID == pWorkspace->m_iID) { w->m_iMonitorID = ID; w->updateSurfaceScaleTransformDetails(); + w->setAnimationsToMove(); const auto MIDDLE = w->middle(); if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && w->m_iX11Type != 2) { diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 7d2a86e7..a14bc195 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -109,14 +109,13 @@ void CAnimationManager::tick() { g_pHyprRenderer->damageWindow(w.get()); } - // if a workspace window is on any monitor, damage it + // if a special workspace window is on any monitor, damage it for (auto& w : g_pCompositor->m_vWindows) { for (auto& m : g_pCompositor->m_vMonitors) { - if (w->m_iWorkspaceID == PWORKSPACE->m_iID && g_pCompositor->windowValidMapped(w.get()) && g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) { + if (w->m_iWorkspaceID == PWORKSPACE->m_iID && PWORKSPACE->m_bIsSpecialWorkspace && g_pCompositor->windowValidMapped(w.get()) && + g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) { CBox bb = w->getFullWindowBoundingBox(); bb.translate(PWORKSPACE->m_vRenderOffset.value()); - if (PWORKSPACE->m_bIsSpecialWorkspace) - bb.scaleFromCenter(1.1); // for some reason special ws windows getting border artifacts if you close it too quickly... bb.intersection({m->vecPosition, m->vecSize}); g_pHyprRenderer->damageBox(&bb); } @@ -197,7 +196,8 @@ void CAnimationManager::tick() { PWINDOW->updateWindowDecos(); auto bb = PWINDOW->getFullWindowBoundingBox(); const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); - bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + if (PWINDOWWORKSPACE) + bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); g_pHyprRenderer->damageBox(&bb); } else if (PWORKSPACE) { for (auto& w : g_pCompositor->m_vWindows) { @@ -245,7 +245,7 @@ void CAnimationManager::tick() { BORDERSIZE + ROUNDINGSIZE); // bottom // damage for new box - CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value(), PWINDOW->m_vRealSize.value()}; + CBox WLRBOXNEW = PWINDOW->getFullWindowBoundingBox(); const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); if (PWINDOWWORKSPACE) WLRBOXNEW.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 88035112..7f83c429 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -217,7 +217,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo } } - if (pWindow->m_iWorkspaceID == pWorkspace->m_iID) + if (pWindow->m_iWorkspaceID == pWorkspace->m_iID && pWorkspace->m_iMonitorID == pMonitor->ID) return true; // if not, check if it maybe is active on a different monitor. @@ -228,9 +228,11 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo return true; if (pWindow->m_vRealPosition.isBeingAnimated()) { + if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) + return false; // render window if window and monitor intersect // (when moving out of or through a monitor) - CBox windowBox = {pWindow->m_vRealPosition.value(), pWindow->m_vRealSize.value()}; + CBox windowBox = pWindow->getFullWindowBoundingBox(); const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize}; if (!windowBox.intersection(monitorBox).empty()) return true; From 432924b372b8e416ca627fa1adef2504dac1d2be Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 02:02:27 +0000 Subject: [PATCH 0053/2772] xwayland: assign wlr_surface on associate --- src/events/Windows.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 056d9108..d1cf9552 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -1190,11 +1190,15 @@ void Events::listener_associateX11(void* owner, void* data) { PWINDOW->hyprListener_mapWindow.initCallback(&PWINDOW->m_uSurface.xwayland->surface->events.map, &Events::listener_mapWindow, PWINDOW, "XWayland Window"); PWINDOW->hyprListener_commitWindow.initCallback(&PWINDOW->m_uSurface.xwayland->surface->events.commit, &Events::listener_commitWindow, PWINDOW, "XWayland Window"); + + PWINDOW->m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW); } void Events::listener_dissociateX11(void* owner, void* data) { const auto PWINDOW = (CWindow*)owner; + PWINDOW->m_pWLSurface.unassign(); + PWINDOW->hyprListener_mapWindow.removeCallback(); PWINDOW->hyprListener_commitWindow.removeCallback(); } @@ -1219,8 +1223,6 @@ void Events::listener_surfaceXWayland(wl_listener* listener, void* data) { PNEWWINDOW->hyprListener_destroyWindow.initCallback(&XWSURFACE->events.destroy, &Events::listener_destroyWindow, PNEWWINDOW, "XWayland Window"); PNEWWINDOW->hyprListener_setOverrideRedirect.initCallback(&XWSURFACE->events.set_override_redirect, &Events::listener_setOverrideRedirect, PNEWWINDOW, "XWayland Window"); PNEWWINDOW->hyprListener_configureX11.initCallback(&XWSURFACE->events.request_configure, &Events::listener_configureX11, PNEWWINDOW, "XWayland Window"); - - PNEWWINDOW->m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(PNEWWINDOW), PNEWWINDOW); } void Events::listener_newXDGToplevel(wl_listener* listener, void* data) { From 09e1128da29741ecdf193b3091afa54b061a915f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 02:21:28 +0000 Subject: [PATCH 0054/2772] cursormgr: initialize size to 0 Because the ctor expects that. Ref #5237 --- src/managers/CursorManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index 0e8d99bc..ff633592 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -55,7 +55,7 @@ class CCursorManager { std::unique_ptr m_pHyprcursor; std::string m_szTheme = ""; - int m_iSize = 24; + int m_iSize = 0; float m_fCursorScale = 1.0; Hyprcursor::SCursorStyleInfo m_sCurrentStyleInfo; From 86dc46ffea2fa72abe1228c1fad1b42d1507e45d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 03:09:39 +0000 Subject: [PATCH 0055/2772] animationmgr: use realpos and size for border damage fixes #5239 --- src/managers/AnimationManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index a14bc195..93608383 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -245,7 +245,7 @@ void CAnimationManager::tick() { BORDERSIZE + ROUNDINGSIZE); // bottom // damage for new box - CBox WLRBOXNEW = PWINDOW->getFullWindowBoundingBox(); + CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value(), PWINDOW->m_vRealSize.value()}; const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); if (PWINDOWWORKSPACE) WLRBOXNEW.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); From acf15e5579a5d2bbbe4a13e87306445e31ea5e4f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 15:00:00 +0000 Subject: [PATCH 0056/2772] text-input: reset lock counter on surface destroy fixes #5231 --- src/managers/input/TextInput.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index 827d4dbe..c42d4f1f 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -127,6 +127,8 @@ void CTextInput::setFocusedSurface(wlr_surface* pSurface) { [this](void* owner, void* data) { Debug::log(LOG, "Unmap TI owner1"); + if (enterLocks) + enterLocks--; pFocusedSurface = nullptr; hyprListener_surfaceUnmapped.removeCallback(); hyprListener_surfaceDestroyed.removeCallback(); @@ -138,6 +140,8 @@ void CTextInput::setFocusedSurface(wlr_surface* pSurface) { [this](void* owner, void* data) { Debug::log(LOG, "destroy TI owner1"); + if (enterLocks) + enterLocks--; pFocusedSurface = nullptr; hyprListener_surfaceUnmapped.removeCallback(); hyprListener_surfaceDestroyed.removeCallback(); From 5cc4bf699cfe4d5915b8ea9f2a7c8449cdc7bd2f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 16:08:25 +0000 Subject: [PATCH 0057/2772] IME: Refactor and fixup popups --- src/Compositor.cpp | 15 --- src/Compositor.hpp | 1 - src/events/Events.hpp | 6 - src/helpers/WLClasses.hpp | 20 --- src/managers/input/InputManager.cpp | 6 +- src/managers/input/InputMethodPopup.cpp | 168 ++++++++++++++++++++++++ src/managers/input/InputMethodPopup.hpp | 41 ++++++ src/managers/input/InputMethodRelay.cpp | 154 +++------------------- src/managers/input/InputMethodRelay.hpp | 21 +-- src/managers/input/TextInput.cpp | 4 +- src/render/Renderer.cpp | 20 +-- src/render/Renderer.hpp | 2 +- 12 files changed, 260 insertions(+), 198 deletions(-) create mode 100644 src/managers/input/InputMethodPopup.cpp create mode 100644 src/managers/input/InputMethodPopup.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f8138825..9ae1adfb 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1163,21 +1163,6 @@ wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector< return nullptr; } -SIMEPopup* CCompositor::vectorToIMEPopup(const Vector2D& pos, std::list& popups) { - for (auto& popup : popups) { - auto surface = popup.pSurface->surface; - CBox box{ - popup.realX, - popup.realY, - surface->current.width, - surface->current.height, - }; - if (box.containsPoint(pos)) - return &popup; - } - return nullptr; -} - CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) { for (auto& w : m_vWindows) { if (!w->m_bIsMapped || w->m_bFadingOut) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index e226fdd3..df8de0c0 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -135,7 +135,6 @@ class CCompositor { bool monitorExists(CMonitor*); CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* pIgnoreWindow = nullptr); wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector>*, Vector2D*, SLayerSurface**); - SIMEPopup* vectorToIMEPopup(const Vector2D& pos, std::list& popups); wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl); Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*); CMonitor* getMonitorFromOutput(wlr_output*); diff --git a/src/events/Events.hpp b/src/events/Events.hpp index a105846e..9dbd75df 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -126,12 +126,6 @@ namespace Events { LISTENER(newTextInput); LISTENER(newVirtualKeyboard); - // IME Popups - DYNLISTENFUNC(mapInputPopup); - DYNLISTENFUNC(unmapInputPopup); - DYNLISTENFUNC(commitInputPopup); - DYNLISTENFUNC(destroyInputPopup); - // Touch LISTENER(touchBegin); LISTENER(touchEnd); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index dbe8d389..7db656d8 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -298,26 +298,6 @@ struct SIMEKbGrab { DYNLISTENER(grabDestroy); }; -struct SIMEPopup { - wlr_input_popup_surface_v2* pSurface = nullptr; - - int x, y; - int realX, realY; - bool visible; - CBox lastBox; - - DYNLISTENER(mapPopup); - DYNLISTENER(unmapPopup); - DYNLISTENER(destroyPopup); - DYNLISTENER(commitPopup); - - DYNLISTENER(focusedSurfaceUnmap); - - bool operator==(const SIMEPopup& other) const { - return pSurface == other.pSurface; - } -}; - struct STouchDevice { wlr_input_device* pWlrDevice = nullptr; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 94e6abec..9f38ab22 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -215,10 +215,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // also IME popups if (!foundSurface) { - auto popup = g_pCompositor->vectorToIMEPopup(mouseCoords, m_sIMERelay.m_lIMEPopups); + auto popup = g_pInputManager->m_sIMERelay.popupFromCoords(mouseCoords); if (popup) { - foundSurface = popup->pSurface->surface; - surfacePos = Vector2D(popup->realX, popup->realY); + foundSurface = popup->getWlrSurface(); + surfacePos = popup->globalBox().pos(); } } diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp new file mode 100644 index 00000000..56fb2024 --- /dev/null +++ b/src/managers/input/InputMethodPopup.cpp @@ -0,0 +1,168 @@ +#include "InputMethodPopup.hpp" + +CInputPopup::CInputPopup(wlr_input_popup_surface_v2* surf) : pWlr(surf) { + surface.assign(surf->surface); + initCallbacks(); +} + +static void onCommit(void* owner, void* data) { + const auto PPOPUP = (CInputPopup*)owner; + PPOPUP->onCommit(); +} + +static void onMap(void* owner, void* data) { + const auto PPOPUP = (CInputPopup*)owner; + PPOPUP->onMap(); +} + +static void onUnmap(void* owner, void* data) { + const auto PPOPUP = (CInputPopup*)owner; + PPOPUP->onUnmap(); +} + +static void onDestroy(void* owner, void* data) { + const auto PPOPUP = (CInputPopup*)owner; + PPOPUP->onDestroy(); +} + +void CInputPopup::initCallbacks() { + hyprListener_commitPopup.initCallback(&pWlr->surface->events.commit, &::onCommit, this, "IME Popup"); + hyprListener_mapPopup.initCallback(&pWlr->surface->events.map, &::onMap, this, "IME Popup"); + hyprListener_unmapPopup.initCallback(&pWlr->surface->events.unmap, &::onUnmap, this, "IME Popup"); + hyprListener_destroyPopup.initCallback(&pWlr->events.destroy, &::onDestroy, this, "IME Popup"); +} + +CWLSurface* CInputPopup::queryOwner() { + const auto FOCUSED = g_pInputManager->m_sIMERelay.getFocusedTextInput(); + + if (!FOCUSED) + return nullptr; + + return CWLSurface::surfaceFromWlr(FOCUSED->focusedSurface()); +} + +void CInputPopup::onDestroy() { + hyprListener_commitPopup.removeCallback(); + hyprListener_destroyPopup.removeCallback(); + hyprListener_mapPopup.removeCallback(); + hyprListener_unmapPopup.removeCallback(); + + g_pInputManager->m_sIMERelay.removePopup(this); +} + +void CInputPopup::onMap() { + Debug::log(LOG, "Mapped an IME Popup"); + + updateBox(); + damageEntire(); +} + +void CInputPopup::onUnmap() { + Debug::log(LOG, "Unmapped an IME Popup"); + + damageEntire(); +} + +void CInputPopup::onCommit() { + updateBox(); +} + +void CInputPopup::damageEntire() { + const auto OWNER = queryOwner(); + + if (!OWNER) { + Debug::log(ERR, "BUG THIS: No owner in imepopup::damageentire"); + return; + } + + Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos(); + CBox global = lastBoxLocal.copy().translate(pos); + + g_pHyprRenderer->damageBox(&global); +} + +void CInputPopup::damageSurface() { + const auto OWNER = queryOwner(); + + if (!OWNER) { + Debug::log(ERR, "BUG THIS: No owner in imepopup::damagesurface"); + return; + } + + Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos() + lastBoxLocal.pos(); + g_pHyprRenderer->damageSurface(surface.wlr(), pos.x, pos.y); +} + +void CInputPopup::updateBox() { + if (!surface.wlr()->mapped) + return; + + const auto OWNER = queryOwner(); + const auto PFOCUSEDTI = g_pInputManager->m_sIMERelay.getFocusedTextInput(); + + if (!PFOCUSEDTI) + return; + + bool cursorRect = PFOCUSEDTI->hasCursorRectangle(); + CBox cursorBoxLocal = PFOCUSEDTI->cursorBox(); + + CBox parentBox; + + if (!OWNER) + parentBox = {0, 0, 500, 500}; + else + parentBox = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 500, 500}); + + if (!cursorRect) { + Vector2D coords = OWNER ? OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 500, 500}).pos() : Vector2D{0, 0}; + parentBox = {coords, {500, 500}}; + cursorBoxLocal = {0, 0, (int)parentBox.w, (int)parentBox.h}; + } + + if (cursorBoxLocal != lastBoxLocal) + damageEntire(); + + CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle()); + + if (cursorBoxLocal.y + parentBox.y + surface.wlr()->current.height + cursorBoxLocal.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) + cursorBoxLocal.y -= surface.wlr()->current.height + cursorBoxLocal.height; + + if (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) + cursorBoxLocal.x -= (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); + + lastBoxLocal = cursorBoxLocal; + + wlr_input_popup_surface_v2_send_text_input_rectangle(pWlr, cursorBoxLocal.pWlr()); + + damageSurface(); + + if (const auto PM = g_pCompositor->getMonitorFromCursor(); PM && PM->ID != lastMonitor) { + const auto PML = g_pCompositor->getMonitorFromID(lastMonitor); + + if (PML) + wlr_surface_send_leave(surface.wlr(), PML->output); + + wlr_surface_send_enter(surface.wlr(), PM->output); + + lastMonitor = PM->ID; + } +} + +CBox CInputPopup::globalBox() { + const auto OWNER = queryOwner(); + + if (!OWNER) { + Debug::log(ERR, "BUG THIS: No owner in imepopup::globalbox"); + return {}; + } + + return lastBoxLocal.copy().translate(OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos()); +} + +bool CInputPopup::isVecInPopup(const Vector2D& point) { + return globalBox().containsPoint(point); +} + +wlr_surface* CInputPopup::getWlrSurface() { + return surface.wlr(); +} diff --git a/src/managers/input/InputMethodPopup.hpp b/src/managers/input/InputMethodPopup.hpp new file mode 100644 index 00000000..8bcf1101 --- /dev/null +++ b/src/managers/input/InputMethodPopup.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../../helpers/WLListener.hpp" +#include "../../desktop/WLSurface.hpp" +#include "../../macros.hpp" +#include "../../helpers/Box.hpp" + +struct wlr_input_popup_surface_v2; + +class CInputPopup { + public: + CInputPopup(wlr_input_popup_surface_v2* surf); + + void onDestroy(); + void onMap(); + void onUnmap(); + void onCommit(); + + void damageEntire(); + void damageSurface(); + + bool isVecInPopup(const Vector2D& point); + + CBox globalBox(); + wlr_surface* getWlrSurface(); + + private: + void initCallbacks(); + CWLSurface* queryOwner(); + void updateBox(); + + wlr_input_popup_surface_v2* pWlr = nullptr; + CWLSurface surface; + CBox lastBoxLocal; + uint64_t lastMonitor = -1; + + DYNLISTENER(mapPopup); + DYNLISTENER(unmapPopup); + DYNLISTENER(destroyPopup); + DYNLISTENER(commitPopup); +}; \ No newline at end of file diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 13e4c9df..2bd98a79 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -86,14 +86,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { hyprListener_IMENewPopup.initCallback( &m_pWLRIME->events.new_popup_surface, [&](void* owner, void* data) { - const auto PNEWPOPUP = &m_lIMEPopups.emplace_back(); - - PNEWPOPUP->pSurface = (wlr_input_popup_surface_v2*)data; - - PNEWPOPUP->hyprListener_commitPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.commit, &Events::listener_commitInputPopup, PNEWPOPUP, "IME Popup"); - PNEWPOPUP->hyprListener_mapPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.map, &Events::listener_mapInputPopup, PNEWPOPUP, "IME Popup"); - PNEWPOPUP->hyprListener_unmapPopup.initCallback(&PNEWPOPUP->pSurface->surface->events.unmap, &Events::listener_unmapInputPopup, PNEWPOPUP, "IME Popup"); - PNEWPOPUP->hyprListener_destroyPopup.initCallback(&PNEWPOPUP->pSurface->events.destroy, &Events::listener_destroyInputPopup, PNEWPOPUP, "IME Popup"); + m_vIMEPopups.emplace_back(std::make_unique((wlr_input_popup_surface_v2*)data)); Debug::log(LOG, "New input popup"); }, @@ -103,132 +96,12 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { PTI->enter(PTI->focusedSurface()); } -void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) { - if (!pPopup->pSurface->surface->mapped) - return; - - // damage last known pos & size - g_pHyprRenderer->damageBox(&pPopup->lastBox); - - const auto PFOCUSEDTI = getFocusedTextInput(); - - if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface()) - return; - - bool cursorRect = PFOCUSEDTI->hasCursorRectangle(); - const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface(); - CBox cursorBox = PFOCUSEDTI->cursorBox(); - - CBox parentBox; - - const auto PSURFACE = CWLSurface::surfaceFromWlr(PFOCUSEDSURFACE); - - if (!PSURFACE) - parentBox = {0, 0, 200, 200}; - else - parentBox = PSURFACE->getSurfaceBoxGlobal().value_or(CBox{0, 0, 200, 200}); - - if (!cursorRect) - cursorBox = {0, 0, (int)parentBox.w, (int)parentBox.h}; - - CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(cursorBox.middle()); - - if (cursorBox.y + parentBox.y + pPopup->pSurface->surface->current.height + cursorBox.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) - cursorBox.y -= pPopup->pSurface->surface->current.height + cursorBox.height; - - if (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) - cursorBox.x -= (cursorBox.x + parentBox.x + pPopup->pSurface->surface->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); - - pPopup->x = cursorBox.x; - pPopup->y = cursorBox.y + cursorBox.height; - - pPopup->realX = cursorBox.x + parentBox.x; - pPopup->realY = cursorBox.y + parentBox.y + cursorBox.height; - - pPopup->lastBox = cursorBox; - - wlr_input_popup_surface_v2_send_text_input_rectangle(pPopup->pSurface, cursorBox.pWlr()); - - damagePopup(pPopup); +void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, wlr_surface* pSurface) { + pPopup->onCommit(); } -void CInputMethodRelay::setIMEPopupFocus(SIMEPopup* pPopup, wlr_surface* pSurface) { - updateInputPopup(pPopup); -} - -void Events::listener_mapInputPopup(void* owner, void* data) { - const auto PPOPUP = (SIMEPopup*)owner; - - Debug::log(LOG, "Mapped an IME Popup"); - - g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP); - - if (const auto PMONITOR = g_pCompositor->getMonitorFromVector(PPOPUP->lastBox.middle()); PMONITOR) - wlr_surface_send_enter(PPOPUP->pSurface->surface, PMONITOR->output); -} - -void Events::listener_unmapInputPopup(void* owner, void* data) { - const auto PPOPUP = (SIMEPopup*)owner; - - Debug::log(LOG, "Unmapped an IME Popup"); - - g_pHyprRenderer->damageBox(&PPOPUP->lastBox); - - g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP); -} - -void Events::listener_destroyInputPopup(void* owner, void* data) { - const auto PPOPUP = (SIMEPopup*)owner; - - Debug::log(LOG, "Removed an IME Popup"); - - PPOPUP->hyprListener_commitPopup.removeCallback(); - PPOPUP->hyprListener_destroyPopup.removeCallback(); - PPOPUP->hyprListener_focusedSurfaceUnmap.removeCallback(); - PPOPUP->hyprListener_mapPopup.removeCallback(); - PPOPUP->hyprListener_unmapPopup.removeCallback(); - - g_pInputManager->m_sIMERelay.removePopup(PPOPUP); -} - -void Events::listener_commitInputPopup(void* owner, void* data) { - const auto PPOPUP = (SIMEPopup*)owner; - - g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP); -} - -void CInputMethodRelay::removePopup(SIMEPopup* pPopup) { - m_lIMEPopups.remove(*pPopup); -} - -void CInputMethodRelay::damagePopup(SIMEPopup* pPopup) { - if (!pPopup->pSurface->surface->mapped) - return; - - const auto PFOCUSEDTI = getFocusedTextInput(); - - if (!PFOCUSEDTI || !PFOCUSEDTI->focusedSurface()) - return; - - Vector2D parentPos; - - const auto PFOCUSEDSURFACE = PFOCUSEDTI->focusedSurface(); - - if (wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)) { - const auto PLS = g_pCompositor->getLayerSurfaceFromWlr(wlr_layer_surface_v1_try_from_wlr_surface(PFOCUSEDSURFACE)); - - if (PLS) { - parentPos = Vector2D(PLS->geometry.x, PLS->geometry.y) + g_pCompositor->getMonitorFromID(PLS->monitorID)->vecPosition; - } - } else { - const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE); - - if (PWINDOW) { - parentPos = PWINDOW->m_vRealPosition.goal(); - } - } - - g_pHyprRenderer->damageSurface(pPopup->pSurface->surface, parentPos.x + pPopup->x, parentPos.y + pPopup->y); +void CInputMethodRelay::removePopup(CInputPopup* pPopup) { + std::erase_if(m_vIMEPopups, [pPopup](const auto& other) { return other.get() == pPopup; }); } SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) { @@ -268,7 +141,13 @@ void CInputMethodRelay::onNewTextInput(STextInputV1* pTIV1) { } void CInputMethodRelay::removeTextInput(CTextInput* pInput) { - m_vTextInputs.remove_if([&](const auto& other) { return other.get() == pInput; }); + std::erase_if(m_vTextInputs, [pInput](const auto& other) { return other.get() == pInput; }); +} + +void CInputMethodRelay::updateAllPopups() { + for (auto& p : m_vIMEPopups) { + p->onCommit(); + } } void CInputMethodRelay::commitIMEState(CTextInput* pInput) { @@ -304,3 +183,12 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) { ti->enter(pSurface); } } + +CInputPopup* CInputMethodRelay::popupFromCoords(const Vector2D& point) { + for (auto& p : m_vIMEPopups) { + if (p->isVecInPopup(point)) + return p.get(); + } + + return nullptr; +} diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 7618400f..f19b4bb5 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -4,8 +4,10 @@ #include "../../defines.hpp" #include "../../helpers/WLClasses.hpp" #include "TextInput.hpp" +#include "InputMethodPopup.hpp" class CInputManager; +class CHyprRenderer; struct STextInputV1; class CInputMethodRelay { @@ -27,18 +29,20 @@ class CInputMethodRelay { SIMEKbGrab* getIMEKeyboardGrab(SKeyboard*); - void setIMEPopupFocus(SIMEPopup*, wlr_surface*); - void updateInputPopup(SIMEPopup*); - void damagePopup(SIMEPopup*); - void removePopup(SIMEPopup*); + void setIMEPopupFocus(CInputPopup*, wlr_surface*); + void removePopup(CInputPopup*); + + CInputPopup* popupFromCoords(const Vector2D& point); + + void updateAllPopups(); private: - std::unique_ptr m_pKeyboardGrab; + std::unique_ptr m_pKeyboardGrab; - std::list> m_vTextInputs; - std::list m_lIMEPopups; + std::vector> m_vTextInputs; + std::vector> m_vIMEPopups; - wlr_surface* m_pLastKbFocus = nullptr; + wlr_surface* m_pLastKbFocus = nullptr; DYNLISTENER(textInputNew); DYNLISTENER(IMECommit); @@ -50,4 +54,5 @@ class CInputMethodRelay { friend class CInputManager; friend class CTextInputV1ProtocolManager; friend struct CTextInput; + friend class CHyprRenderer; }; diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index c42d4f1f..0e642f82 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -222,9 +222,7 @@ void CTextInput::commitStateToIME(wlr_input_method_v2* ime) { wlr_input_method_v2_send_content_type(ime, pV1Input->pendingContentType.hint, pV1Input->pendingContentType.purpose); } - for (auto& p : g_pInputManager->m_sIMERelay.m_lIMEPopups) { - g_pInputManager->m_sIMERelay.updateInputPopup(&p); - } + g_pInputManager->m_sIMERelay.updateAllPopups(); wlr_input_method_v2_send_done(ime); } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 7f83c429..a3112c1e 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -679,16 +679,20 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times g_pHyprOpenGL->m_RenderData.clipBox = {}; } -void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) { - SRenderData renderdata = {pMonitor, time, pPopup->realX, pPopup->realY}; +void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, CMonitor* pMonitor, timespec* time) { + const auto POS = pPopup->globalBox().pos(); + + SRenderData renderdata = {pMonitor, time, POS.x, POS.y}; + + const auto SURF = pPopup->getWlrSurface(); renderdata.blur = false; - renderdata.surface = pPopup->pSurface->surface; + renderdata.surface = SURF; renderdata.decorate = false; - renderdata.w = pPopup->pSurface->surface->current.width; - renderdata.h = pPopup->pSurface->surface->current.height; + renderdata.w = SURF->current.width; + renderdata.h = SURF->current.height; - wlr_surface_for_each_surface(pPopup->pSurface->surface, renderSurface, &renderdata); + wlr_surface_for_each_surface(SURF, renderSurface, &renderdata); } void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, CMonitor* pMonitor, timespec* time) { @@ -830,8 +834,8 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* } // Render IME popups - for (auto& imep : g_pInputManager->m_sIMERelay.m_lIMEPopups) { - renderIMEPopup(&imep, pMonitor, time); + for (auto& imep : g_pInputManager->m_sIMERelay.m_vIMEPopups) { + renderIMEPopup(imep.get(), pMonitor, time); } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index fd41a566..1c6628f1 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -115,7 +115,7 @@ class CHyprRenderer { void renderLayer(SLayerSurface*, CMonitor*, timespec*); void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); void renderDragIcon(CMonitor*, timespec*); - void renderIMEPopup(SIMEPopup*, CMonitor*, timespec*); + void renderIMEPopup(CInputPopup*, CMonitor*, timespec*); void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry); void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); From 1e82d5a04d0ab75ea1d9aa763d28c1767d58e898 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 17:19:35 +0000 Subject: [PATCH 0058/2772] ime: fix build without pch --- src/managers/input/InputMethodPopup.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index 56fb2024..326b982e 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -1,4 +1,6 @@ #include "InputMethodPopup.hpp" +#include "InputManager.hpp" +#include "../../Compositor.hpp" CInputPopup::CInputPopup(wlr_input_popup_surface_v2* surf) : pWlr(surf) { surface.assign(surf->surface); From 294ff8609f80b8e9d16233de94e49f992d5de33a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 19:39:56 +0000 Subject: [PATCH 0059/2772] cursormgr: log theme loading failures --- src/managers/CursorManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index c4b624d4..ae258916 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -15,6 +15,9 @@ static int cursorAnimTimer(void* data) { CCursorManager::CCursorManager() { m_pHyprcursor = std::make_unique(m_szTheme.empty() ? nullptr : m_szTheme.c_str()); + if (!m_pHyprcursor->valid()) + Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", m_szTheme); + // find default size. First, HYPRCURSOR_SIZE, then XCURSOR_SIZE, then 24 auto SIZE = getenv("HYPRCURSOR_SIZE"); if (SIZE) { @@ -224,6 +227,9 @@ void CCursorManager::changeTheme(const std::string& name, const int size) { m_szTheme = name; m_iSize = size; + if (!m_pHyprcursor->valid()) + Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", m_szTheme); + setenv("XCURSOR_SIZE", std::to_string(m_iSize).c_str(), true); setenv("XCURSOR_THEME", name.c_str(), true); From 03e99f93ae3c98284bd9d489de490bca2b11824c Mon Sep 17 00:00:00 2001 From: Brett Alcox Date: Sun, 24 Mar 2024 15:38:10 -0500 Subject: [PATCH 0060/2772] renderer: forward decl for b_pch=false (#5250) --- src/render/Renderer.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 1c6628f1..011b17b9 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -11,6 +11,7 @@ struct SMonitorRule; class CWorkspace; class CWindow; +class CInputPopup; // TODO: add fuller damage tracking for updating only parts of a window enum DAMAGETRACKINGMODES { From 89543e8e3cb7d3d3e1755649779c3835bd5c5fd9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 24 Mar 2024 20:47:09 +0000 Subject: [PATCH 0061/2772] cursormgr: don't set x theme in changeTheme --- src/managers/CursorManager.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index ae258916..6c481cea 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -230,8 +230,5 @@ void CCursorManager::changeTheme(const std::string& name, const int size) { if (!m_pHyprcursor->valid()) Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", m_szTheme); - setenv("XCURSOR_SIZE", std::to_string(m_iSize).c_str(), true); - setenv("XCURSOR_THEME", name.c_str(), true); - updateTheme(); } From 8001b96bb5f801ea665fd482ba421e8703d986e7 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sun, 24 Mar 2024 18:41:56 -0700 Subject: [PATCH 0062/2772] renderer: dont render fullscreen special on wrong monitor (#5249) --- src/render/Renderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index a3112c1e..2059be0a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -328,7 +328,8 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); + if (shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); if (w->m_iWorkspaceID != pWorkspace->m_iID) continue; From 6b28bf563e3b4e5f6631985f24c88e8a8ebaa0d4 Mon Sep 17 00:00:00 2001 From: dmayle Date: Sun, 24 Mar 2024 18:46:59 -0700 Subject: [PATCH 0063/2772] keybinds: Fix exit trigger by moving it to monitor.frame (#5240) --- src/Compositor.hpp | 1 + src/events/Monitors.cpp | 7 +++++++ src/managers/KeybindManager.cpp | 2 +- src/managers/input/InputManager.cpp | 3 --- src/managers/input/InputManager.hpp | 2 -- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index df8de0c0..64cd6e43 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -118,6 +118,7 @@ class CCompositor { bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bNextIsUnsafe = false; // because wlroots CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state + bool m_bExitTriggered = false; // For exit dispatcher bool m_bIsShuttingDown = false; // ------------------------------------------------- // diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index e235096b..a6fd5a4a 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -117,6 +117,13 @@ void Events::listener_newOutput(wl_listener* listener, void* data) { } void Events::listener_monitorFrame(void* owner, void* data) { + if (g_pCompositor->m_bExitTriggered) { + // Only signal cleanup once + g_pCompositor->m_bExitTriggered = false; + g_pCompositor->cleanup(); + return; + } + CMonitor* const PMONITOR = (CMonitor*)owner; if ((g_pCompositor->m_sWLRSession && !g_pCompositor->m_sWLRSession->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) { diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 8a1d022b..a8d390fa 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1512,7 +1512,7 @@ void CKeybindManager::renameWorkspace(std::string args) { } void CKeybindManager::exitHyprland(std::string argz) { - g_pInputManager->m_bExitTriggered = true; + g_pCompositor->m_bExitTriggered = true; } void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) { diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 9f38ab22..94245587 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1189,9 +1189,6 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar updateKeyboardsLeds(pKeyboard->keyboard); } - - if (m_bExitTriggered) - g_pCompositor->cleanup(); } void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) { diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 128badfc..a89981f3 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -251,8 +251,6 @@ class CInputManager { void restoreCursorIconToApp(); // no-op if restored - bool m_bExitTriggered = false; // for exit dispatcher - friend class CKeybindManager; friend class CWLSurface; }; From 356414639fc06ace7045236ec41d673342981057 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sun, 24 Mar 2024 18:50:41 -0700 Subject: [PATCH 0064/2772] core: fix missing workspace events during swapping (#5251) --- src/Compositor.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 9ae1adfb..bf6c4200 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2053,6 +2053,11 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) const auto LASTWIN = pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow(); g_pCompositor->focusWindow(LASTWIN ? LASTWIN : (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING))); + + const auto PNEWWORKSPACE = pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID ? PWORKSPACEB : PWORKSPACEA; + g_pEventManager->postEvent(SHyprIPCEvent{"workspace", PNEWWORKSPACE->m_szName}); + g_pEventManager->postEvent(SHyprIPCEvent{"workspacev2", std::format("{},{}", PNEWWORKSPACE->m_iID, PNEWWORKSPACE->m_szName)}); + EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE); } // event From ca17a89d86b73f37019c4cc0c7087303adbcc1f9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 25 Mar 2024 16:08:55 +0000 Subject: [PATCH 0065/2772] renderer: allow blurring ls popups --- src/config/ConfigManager.cpp | 3 ++- src/desktop/Popup.cpp | 9 +++++++ src/desktop/Window.cpp | 10 +++++++ src/desktop/Window.hpp | 1 + src/helpers/WLClasses.cpp | 9 +++++++ src/helpers/WLClasses.hpp | 2 ++ src/render/OpenGL.cpp | 21 ++++++++++++++- src/render/Renderer.cpp | 52 ++++++++++++++++++++++-------------- 8 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 11159131..d13b871d 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1906,7 +1906,8 @@ bool windowRuleValid(const std::string& RULE) { } bool layerRuleValid(const std::string& RULE) { - return RULE == "noanim" || RULE == "blur" || RULE.starts_with("ignorealpha") || RULE.starts_with("ignorezero") || RULE.starts_with("xray") || RULE.starts_with("animation"); + return RULE == "noanim" || RULE == "blur" || RULE == "blurpopups" || RULE.starts_with("ignorealpha") || RULE.starts_with("ignorezero") || RULE.starts_with("xray") || + RULE.starts_with("animation"); } std::optional CConfigManager::handleWindowRule(const std::string& command, const std::string& value) { diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 98d5881a..77e486fd 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -117,6 +117,9 @@ void CPopup::onMap() { unconstrain(); sendScale(); + + if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); } void CPopup::onUnmap() { @@ -131,6 +134,9 @@ void CPopup::onUnmap() { m_pSubsurfaceHead.reset(); g_pInputManager->simulateMouseMovement(); + + if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); } void CPopup::onCommit(bool ignoreSiblings) { @@ -158,6 +164,9 @@ void CPopup::onCommit(bool ignoreSiblings) { g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y); m_bRequestedReposition = false; + + if (m_pLayerOwner && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP) + g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); } void CPopup::onReposition() { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 3145000c..9151d57e 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1151,3 +1151,13 @@ void CWindow::setAnimationsToMove() { m_vRealSize.setConfig(PANIMCFG); m_bAnimatingIn = false; } + +int CWindow::popupsCount() { + if (m_bIsX11) + return 1; + + int no = 0; + wlr_xdg_surface_for_each_popup_surface( + m_uSurface.xdg, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); + return no; +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 3ec8a54c..d8b4012d 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -404,6 +404,7 @@ class CWindow { void onBorderAngleAnimEnd(void* ptr); bool isInCurvedCorner(double x, double y); bool hasPopupAt(const Vector2D& pos); + int popupsCount(); void applyGroupRules(); void createGroup(); diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index d46f7e40..e7ae69c0 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -37,6 +37,8 @@ void SLayerSurface::applyRules() { noAnimations = true; else if (rule.rule == "blur") forceBlur = true; + else if (rule.rule == "blurpopups") + forceBlurPopups = true; else if (rule.rule.starts_with("ignorealpha") || rule.rule.starts_with("ignorezero")) { const auto FIRST_SPACE_POS = rule.rule.find_first_of(' '); std::string alphaValue = ""; @@ -168,6 +170,13 @@ bool SLayerSurface::isFadedOut() { return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated(); } +int SLayerSurface::popupsCount() { + int no = 0; + wlr_layer_surface_v1_for_each_popup_surface( + layerSurface, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); + return no; +} + void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { xkb_state_unref(xkbTranslationState); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 7db656d8..f1311e42 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -22,6 +22,7 @@ struct SLayerSurface { void applyRules(); void startAnimation(bool in, bool instant = false); bool isFadedOut(); + int popupsCount(); CAnimatedVariable realPosition; CAnimatedVariable realSize; @@ -58,6 +59,7 @@ struct SLayerSurface { bool noAnimations = false; bool forceBlur = false; + bool forceBlurPopups = false; int xray = -1; bool ignoreAlpha = false; float ignoreAlphaValue = 0.f; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index df03e8e9..f5cf2624 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -147,6 +147,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { static auto PXRAY = CConfigValue("decoration:blur:xray"); static auto POPTIM = CConfigValue("decoration:blur:new_optimizations"); static auto PBLURSPECIAL = CConfigValue("decoration:blur:special"); + static auto PBLURPOPUPS = CConfigValue("decoration:blur:popups"); if (m_RenderData.mouseZoomFactor != 1.0 || g_pHyprRenderer->m_bCrashingInProgress) return true; @@ -167,23 +168,35 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray; if (ls->forceBlur && !XRAYMODE) return true; + + if (ls->popupsCount() > 0 && ls->forceBlurPopups) + return true; } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray; if (ls->forceBlur && !XRAYMODE) return true; + + if (ls->popupsCount() > 0 && ls->forceBlurPopups) + return true; } // these two block optimization for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { if (ls->forceBlur) return true; + + if (ls->popupsCount() > 0 && ls->forceBlurPopups) + return true; } for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { if (ls->forceBlur) return true; + + if (ls->popupsCount() > 0 && ls->forceBlurPopups) + return true; } if (*PBLURSPECIAL) { @@ -202,12 +215,18 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { return false; for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || (!w->m_bIsFloating && *POPTIM && !g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))) + if (!w->m_bIsMapped || w->isHidden()) continue; if (!g_pHyprRenderer->shouldRenderWindow(w.get())) continue; + if (w->popupsCount() > 0 && *PBLURPOPUPS) + return true; + + if (!w->m_bIsFloating && *POPTIM && !g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + continue; + if (w->m_sAdditionalConfigData.forceNoBlur.toUnderlying() == true || w->m_sAdditionalConfigData.xray.toUnderlying() == true) continue; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 2059be0a..3e8b277f 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -55,12 +55,9 @@ CHyprRenderer::CHyprRenderer() { } static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { - static auto PBLURPOPUPS = CConfigValue("decoration:blur:popups"); - static auto PBLURPOPUPSIGNOREALPHA = CConfigValue("decoration:blur:popups_ignorealpha"); - - const auto TEXTURE = wlr_surface_get_texture(surface); - const auto RDATA = (SRenderData*)data; - const auto INTERACTIVERESIZEINPROGRESS = RDATA->pWindow && g_pInputManager->currentlyDraggedWindow == RDATA->pWindow && g_pInputManager->dragMode == MBIND_RESIZE; + const auto TEXTURE = wlr_surface_get_texture(surface); + const auto RDATA = (SRenderData*)data; + const auto INTERACTIVERESIZEINPROGRESS = RDATA->pWindow && g_pInputManager->currentlyDraggedWindow == RDATA->pWindow && g_pInputManager->dragMode == MBIND_RESIZE; if (!TEXTURE) return; @@ -168,16 +165,9 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true); } } else { - if (RDATA->blur && RDATA->popup && *PBLURPOPUPS) { - - if (*PBLURPOPUPSIGNOREALPHA != 1.f) { - g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; - g_pHyprOpenGL->m_RenderData.discardOpacity = *PBLURPOPUPSIGNOREALPHA; - } - - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, true); - g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHA; - } else + if (RDATA->blur && RDATA->popup) + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, true, RDATA->fadeAlpha); + else g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true); } @@ -616,12 +606,28 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* renderdata.squishOversized = false; // don't squish popups renderdata.popup = true; + static CConfigValue PBLURPOPUPS = CConfigValue("decoration:blur:popups"); + static CConfigValue PBLURIGNOREA = CConfigValue("decoration:blur:popups_ignorealpha"); + + renderdata.blur = *PBLURPOPUPS; + + const auto DM = g_pHyprOpenGL->m_RenderData.discardMode; + const auto DA = g_pHyprOpenGL->m_RenderData.discardOpacity; + + if (renderdata.blur) { + g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; + g_pHyprOpenGL->m_RenderData.discardOpacity = *PBLURIGNOREA; + } + if (pWindow->m_sAdditionalConfigData.nearestNeighbor.toUnderlying()) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata); g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; + + g_pHyprOpenGL->m_RenderData.discardMode = DM; + g_pHyprOpenGL->m_RenderData.discardOpacity = DA; } if (decorate) { @@ -664,20 +670,26 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times g_pHyprOpenGL->m_pCurrentLayer = pLayer; - if (pLayer->ignoreAlpha) { + const auto DM = g_pHyprOpenGL->m_RenderData.discardMode; + const auto DA = g_pHyprOpenGL->m_RenderData.discardOpacity; + + if (renderdata.blur && pLayer->ignoreAlpha) { g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; g_pHyprOpenGL->m_RenderData.discardOpacity = pLayer->ignoreAlphaValue; } + wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); - g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHA; renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; renderdata.popup = true; + renderdata.blur = pLayer->forceBlurPopups; wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata); - g_pHyprOpenGL->m_pCurrentLayer = nullptr; - g_pHyprOpenGL->m_RenderData.clipBox = {}; + g_pHyprOpenGL->m_pCurrentLayer = nullptr; + g_pHyprOpenGL->m_RenderData.clipBox = {}; + g_pHyprOpenGL->m_RenderData.discardMode = DM; + g_pHyprOpenGL->m_RenderData.discardOpacity = DA; } void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, CMonitor* pMonitor, timespec* time) { From ae17e900e720430c7848faf1b6e21b5f352c26ca Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 25 Mar 2024 16:20:30 +0000 Subject: [PATCH 0066/2772] layer-shell: render popups above everything --- src/Compositor.cpp | 23 ++++++++++++++++++++++- src/Compositor.hpp | 3 ++- src/helpers/WLClasses.cpp | 3 +++ src/managers/input/InputManager.cpp | 3 +++ src/render/Renderer.cpp | 14 +++++++++++--- src/render/Renderer.hpp | 2 +- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index bf6c4200..2d6e7856 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1143,13 +1143,34 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) { return true; } +wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) { + for (auto& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) { + for (auto& ls : lsl | std::views::reverse) { + if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) + continue; + + auto SURFACEAT = wlr_layer_surface_v1_popup_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); + + if (SURFACEAT) { + if (!pixman_region32_not_empty(&SURFACEAT->input_region)) + continue; + + *ppLayerSurfaceFound = ls.get(); + return SURFACEAT; + } + } + } + + return nullptr; +} + wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector>* layerSurfaces, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) { for (auto& ls : *layerSurfaces | std::views::reverse) { if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) continue; - auto SURFACEAT = wlr_layer_surface_v1_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); + auto SURFACEAT = wlr_surface_surface_at(ls->layerSurface->surface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); if (SURFACEAT) { if (!pixman_region32_not_empty(&SURFACEAT->input_region)) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 64cd6e43..ace2a388 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -118,7 +118,7 @@ class CCompositor { bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bNextIsUnsafe = false; // because wlroots CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state - bool m_bExitTriggered = false; // For exit dispatcher + bool m_bExitTriggered = false; // For exit dispatcher bool m_bIsShuttingDown = false; // ------------------------------------------------- // @@ -136,6 +136,7 @@ class CCompositor { bool monitorExists(CMonitor*); CWindow* vectorToWindowUnified(const Vector2D&, uint8_t properties, CWindow* pIgnoreWindow = nullptr); wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector>*, Vector2D*, SLayerSurface**); + wlr_surface* vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, SLayerSurface**); wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl); Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*); CMonitor* getMonitorFromOutput(wlr_output*); diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index e7ae69c0..5e18c274 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -171,6 +171,9 @@ bool SLayerSurface::isFadedOut() { } int SLayerSurface::popupsCount() { + if (!layerSurface || !mapped || fadingOut) + return 0; + int no = 0; wlr_layer_surface_v1_for_each_popup_surface( layerSurface, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 94245587..690463fa 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -209,6 +209,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { surfacePos = PMONITOR->vecPosition; } + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerPopupSurface(mouseCoords, PMONITOR, &surfaceCoords, &pFoundLayerSurface); + // overlays are above fullscreen if (!foundSurface) foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 3e8b277f..4680568c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -646,7 +646,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->m_RenderData.clipBox = CBox(); } -void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time) { +void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time, bool popups) { if (pLayer->fadingOut) { g_pHyprOpenGL->renderSnapshot(&pLayer); return; @@ -678,13 +678,15 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times g_pHyprOpenGL->m_RenderData.discardOpacity = pLayer->ignoreAlphaValue; } - wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); + if (!popups) + wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; renderdata.popup = true; renderdata.blur = pLayer->forceBlurPopups; - wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata); + if (popups) + wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata); g_pHyprOpenGL->m_pCurrentLayer = nullptr; g_pHyprOpenGL->m_RenderData.clipBox = {}; @@ -855,6 +857,12 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* renderLayer(ls.get(), pMonitor, time); } + for (auto& lsl : pMonitor->m_aLayerSurfaceLayers) { + for (auto& ls : lsl) { + renderLayer(ls.get(), pMonitor, time, true); + } + } + renderDragIcon(pMonitor, time); //g_pHyprOpenGL->restoreMatrix(); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 011b17b9..d73b4c5f 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -113,7 +113,7 @@ class CHyprRenderer { void renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) void renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); - void renderLayer(SLayerSurface*, CMonitor*, timespec*); + void renderLayer(SLayerSurface*, CMonitor*, timespec*, bool popups = false); void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); void renderDragIcon(CMonitor*, timespec*); void renderIMEPopup(CInputPopup*, CMonitor*, timespec*); From 414e37996d0c33a5792b8698146792a2a0359b93 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:21:31 -0700 Subject: [PATCH 0067/2772] github: fix github issue template crash dir (#5269) --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 2305c650..0bdaff4d 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -63,5 +63,5 @@ body: description: | Anything that can help. Please always ATTACH and not paste them. Logs can be found in /tmp/hypr - Crash reports are stored in ~/.hyprland or $XDG_CACHE_HOME/hyprland + Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland From a9d7526aae38dcdceb391fe9f00919c6c400abe3 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 26 Mar 2024 02:26:09 +0000 Subject: [PATCH 0068/2772] core: ensure m_pLastMonitor validity over unsafe state ref #5241 --- src/Compositor.cpp | 2 ++ src/events/Windows.cpp | 4 ++++ src/helpers/Monitor.cpp | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 2d6e7856..68db0091 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2808,6 +2808,8 @@ void CCompositor::enterUnsafeState() { m_pUnsafeOutput->onConnect(false); m_bUnsafeState = true; + + setActiveMonitor(m_pUnsafeOutput); } void CCompositor::leaveUnsafeState() { diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index d1cf9552..0d1665b7 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -53,6 +53,10 @@ void Events::listener_mapWindow(void* owner, void* data) { static auto PNEWTAKESOVERFS = CConfigValue("misc:new_window_takes_over_fullscreen"); auto PMONITOR = g_pCompositor->m_pLastMonitor; + if (!g_pCompositor->m_pLastMonitor) { + g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({})); + PMONITOR = g_pCompositor->m_pLastMonitor; + } auto PWORKSPACE = PMONITOR->specialWorkspaceID ? g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); PWINDOW->m_iMonitorID = PMONITOR->ID; PWINDOW->m_iWorkspaceID = PMONITOR->specialWorkspaceID ? PMONITOR->specialWorkspaceID : PMONITOR->activeWorkspace; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 3edb7ca4..219257b9 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -310,7 +310,7 @@ void CMonitor::onDisconnect(bool destroy) { Debug::log(WARN, "wlr_output_commit_state failed in CMonitor::onDisconnect"); if (g_pCompositor->m_pLastMonitor == this) - g_pCompositor->setActiveMonitor(BACKUPMON); + g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_pUnsafeOutput); if (g_pHyprRenderer->m_pMostHzMonitor == this) { int mostHz = 0; From 1a0b8d1263a318146ce63062115332c725e79edf Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 26 Mar 2024 13:35:03 +0000 Subject: [PATCH 0069/2772] renderer: minor fixes to misaligned reported surface rendering fixes #5257 --- src/render/Renderer.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 4680568c..f94a3688 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -91,11 +91,9 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) } if (!INTERACTIVERESIZEINPROGRESS && PSURFACE && PWINDOW && PWINDOW->m_vRealSize.goal().floor() > PWINDOW->m_vReportedSize && PWINDOW->m_vReportedSize > Vector2D{1, 1}) { - Vector2D coeff = PWINDOW->m_vReportedSize / PWINDOW->m_vRealSize.value(); - Vector2D coeff2 = PWINDOW->m_vReportedSize / PWINDOW->m_vRealSize.goal(); - - Vector2D size = Vector2D{windowBox.w, windowBox.h} * coeff; - Vector2D correct = Vector2D{windowBox.w, windowBox.h} - Vector2D{windowBox.w, windowBox.h} * coeff2; + Vector2D size = + Vector2D{windowBox.w * (PWINDOW->m_vReportedSize.x / PWINDOW->m_vRealSize.value().x), windowBox.h * (PWINDOW->m_vReportedSize.y / PWINDOW->m_vRealSize.value().y)}; + Vector2D correct = Vector2D{windowBox.w, windowBox.h} - size; windowBox.translate(correct / 2.0); From 9b7ae25ae83b5b0d6f61fe542391301a57d31270 Mon Sep 17 00:00:00 2001 From: Khalid Date: Tue, 26 Mar 2024 16:38:54 +0300 Subject: [PATCH 0070/2772] hyprctl: output json with `--batch` if requested (#5277) --- hyprctl/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index b8072de9..0bf6f414 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -22,6 +22,7 @@ #include #include #include +#include const std::string USAGE = R"#(usage: hyprctl [(opt)flags] [command] [(opt)args] @@ -234,9 +235,14 @@ void requestHyprpaper(std::string arg) { std::cout << std::string(buffer); } -void batchRequest(std::string arg) { - std::string rq = "[[BATCH]]" + arg.substr(arg.find_first_of(" ") + 1); +void batchRequest(std::string arg, bool json) { + std::string commands = arg.substr(arg.find_first_of(" ") + 1); + if (json) { + commands = "j/" + std::regex_replace(commands, std::regex(";\\s*"), ";j/"); + } + + std::string rq = "[[BATCH]]" + commands; request(rq); } @@ -383,7 +389,7 @@ int main(int argc, char** argv) { int exitStatus = 0; if (fullRequest.contains("/--batch")) - batchRequest(fullRequest); + batchRequest(fullRequest, json); else if (fullRequest.contains("/hyprpaper")) requestHyprpaper(fullRequest); else if (fullRequest.contains("/switchxkblayout")) From ae52b7f4680716976d05b638aaa90e169d199117 Mon Sep 17 00:00:00 2001 From: Sungyoon Cho Date: Wed, 27 Mar 2024 00:16:09 +0900 Subject: [PATCH 0071/2772] textinput: fix ime when opening multiple windows (#5281) --- src/managers/input/TextInput.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index 0e642f82..7bb6c81a 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -87,7 +87,11 @@ void CTextInput::onDisabled() { return; } - leave(); + if (!focusedSurface()) + return; + + if (!isV3()) + leave(); hyprListener_surfaceDestroyed.removeCallback(); hyprListener_surfaceUnmapped.removeCallback(); From 93d05114716e847c37f49d3cc2d0c5cb01d06a24 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 27 Mar 2024 16:30:08 +0000 Subject: [PATCH 0072/2772] layershell: update render pos and size in arrange fixes #5258 --- src/render/Renderer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f94a3688..c48bbdd4 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1618,6 +1618,9 @@ void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vectorlayerSurface, box.width, box.height); + + ls->realPosition = box.pos(); + ls->realSize = box.size(); } } From 132ab8d035f2eb0ec75661526c6f342c5ec52159 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 28 Mar 2024 01:39:17 +0000 Subject: [PATCH 0073/2772] layers: add animation direction overrides fixes #5285 --- src/helpers/WLClasses.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 5e18c274..96ba0fa5 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -65,11 +65,26 @@ void SLayerSurface::applyRules() { void SLayerSurface::startAnimation(bool in, bool instant) { const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle); - if (ANIMSTYLE == "slide") { + if (ANIMSTYLE.starts_with("slide")) { // get closest edge - const auto MIDDLE = geometry.middle(); + const auto MIDDLE = geometry.middle(); - const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE); + const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE); + + int force = -1; + + CVarList args(ANIMSTYLE, 0, 's'); + if (args.size() > 1) { + const auto ARG2 = args[1]; + if (ARG2 == "top") + force = 0; + else if (ARG2 == "bottom") + force = 1; + else if (ARG2 == "left") + force = 2; + else if (ARG2 == "right") + force = 3; + } const std::array edgePoints = { PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0}, @@ -78,13 +93,15 @@ void SLayerSurface::startAnimation(bool in, bool instant) { PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, }; - float closest = std::numeric_limits::max(); - size_t leader = 0; - for (size_t i = 0; i < 4; ++i) { - float dist = MIDDLE.distance(edgePoints[i]); - if (dist < closest) { - leader = i; - closest = dist; + float closest = std::numeric_limits::max(); + int leader = force; + if (leader == -1) { + for (size_t i = 0; i < 4; ++i) { + float dist = MIDDLE.distance(edgePoints[i]); + if (dist < closest) { + leader = i; + closest = dist; + } } } From 0869f65b0b7e13b0d7f522decfc21244beb21c3a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 28 Mar 2024 02:04:30 +0000 Subject: [PATCH 0074/2772] input: add misc:hide_cursor_on_key_press fixes #3045 --- src/config/ConfigManager.cpp | 1 + src/render/Renderer.cpp | 77 ++++++++++++++++++++++++++++-------- src/render/Renderer.hpp | 9 ++++- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index d13b871d..17dea1a7 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -349,6 +349,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("misc:background_color", Hyprlang::INT{0xff111111}); m_pConfig->addConfigValue("misc:new_window_takes_over_fullscreen", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:enable_hyprcursor", Hyprlang::INT{1}); + m_pConfig->addConfigValue("misc:hide_cursor_on_key_press", Hyprlang::INT{0}); m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1}); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index c48bbdd4..960add70 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -11,8 +11,13 @@ extern "C" { #include } -CHyprRenderer::CHyprRenderer() { +static int cursorTicker(void* data) { + g_pHyprRenderer->ensureCursorRenderingMode(); + wl_event_source_timer_update(g_pHyprRenderer->m_pCursorTicker, 500); + return 0; +} +CHyprRenderer::CHyprRenderer() { if (g_pCompositor->m_sWLRSession) { wlr_device* dev; wl_list_for_each(dev, &g_pCompositor->m_sWLRSession->devices, link) { @@ -52,6 +57,30 @@ CHyprRenderer::CHyprRenderer() { if (m_bNvidia) Debug::log(WARN, "NVIDIA detected, please remember to follow nvidia instructions on the wiki"); + + // cursor hiding stuff + + g_pHookSystem->hookDynamic("keyPress", [&](void* self, SCallbackInfo& info, std::any param) { + if (m_sCursorHiddenConditions.hiddenOnKeyboard) + return; + + m_sCursorHiddenConditions.hiddenOnKeyboard = true; + ensureCursorRenderingMode(); + }); + + g_pHookSystem->hookDynamic("mouseMove", [&](void* self, SCallbackInfo& info, std::any param) { + if (!m_sCursorHiddenConditions.hiddenOnKeyboard && m_sCursorHiddenConditions.hiddenOnTouch == g_pInputManager->m_bLastInputTouch && + !m_sCursorHiddenConditions.hiddenOnTimeout) + return; + + m_sCursorHiddenConditions.hiddenOnKeyboard = false; + m_sCursorHiddenConditions.hiddenOnTimeout = false; + m_sCursorHiddenConditions.hiddenOnTouch = g_pInputManager->m_bLastInputTouch; + ensureCursorRenderingMode(); + }); + + m_pCursorTicker = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, cursorTicker, nullptr); + wl_event_source_timer_update(m_pCursorTicker, 500); } static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { @@ -1090,8 +1119,6 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (g_pConfigManager->m_bWantsMonitorReload) g_pConfigManager->performMonitorReload(); - - ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts } // // @@ -2269,29 +2296,45 @@ void CHyprRenderer::setCursorFromName(const std::string& name, bool force) { void CHyprRenderer::ensureCursorRenderingMode() { static auto PCURSORTIMEOUT = CConfigValue("general:cursor_inactive_timeout"); static auto PHIDEONTOUCH = CConfigValue("misc:hide_cursor_on_touch"); + static auto PHIDEONKEY = CConfigValue("misc:hide_cursor_on_key_press"); - const auto PASSEDCURSORSECONDS = g_pInputManager->m_tmrLastCursorMovement.getSeconds(); + if (*PCURSORTIMEOUT <= 0) + m_sCursorHiddenConditions.hiddenOnTimeout = false; + if (*PHIDEONTOUCH == 0) + m_sCursorHiddenConditions.hiddenOnTouch = false; + if (*PHIDEONKEY == 0) + m_sCursorHiddenConditions.hiddenOnKeyboard = false; - if (*PCURSORTIMEOUT > 0 || *PHIDEONTOUCH) { - const bool HIDE = (*PCURSORTIMEOUT > 0 && *PCURSORTIMEOUT < PASSEDCURSORSECONDS) || (g_pInputManager->m_bLastInputTouch && *PHIDEONTOUCH); + if (*PCURSORTIMEOUT > 0) + m_sCursorHiddenConditions.hiddenOnTimeout = *PCURSORTIMEOUT < g_pInputManager->m_tmrLastCursorMovement.getSeconds(); - if (HIDE && !m_bCursorHidden) { - Debug::log(LOG, "Hiding the cursor (timeout)"); + const bool HIDE = m_sCursorHiddenConditions.hiddenOnTimeout || m_sCursorHiddenConditions.hiddenOnTouch || m_sCursorHiddenConditions.hiddenOnKeyboard; - for (auto& m : g_pCompositor->m_vMonitors) - g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? + if (HIDE == m_bCursorHidden) + return; - setCursorHidden(true); + if (HIDE) { + Debug::log(LOG, "Hiding the cursor (hl-mandated)"); - } else if (!HIDE && m_bCursorHidden) { - Debug::log(LOG, "Showing the cursor (timeout)"); + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->output->software_cursor_locks == 0) + continue; - for (auto& m : g_pCompositor->m_vMonitors) - g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? - - setCursorHidden(false); + g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? } + + setCursorHidden(true); + } else { + Debug::log(LOG, "Showing the cursor (hl-mandated)"); + + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->output->software_cursor_locks == 0) + continue; + + g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area? + } + setCursorHidden(false); } } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index d73b4c5f..0a684af3 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -96,6 +96,7 @@ class CHyprRenderer { bool m_bCrashingInProgress = false; float m_fCrashingDistort = 0.5f; wl_event_source* m_pCrashingLoop = nullptr; + wl_event_source* m_pCursorTicker = nullptr; std::vector> m_vTearingControllers; @@ -128,7 +129,13 @@ class CHyprRenderer { bool m_bNvidia = false; - CRenderbuffer* getOrCreateRenderbuffer(wlr_buffer* buffer, uint32_t fmt); + struct { + bool hiddenOnTouch = false; + bool hiddenOnTimeout = false; + bool hiddenOnKeyboard = false; + } m_sCursorHiddenConditions; + + CRenderbuffer* getOrCreateRenderbuffer(wlr_buffer* buffer, uint32_t fmt); std::vector> m_vRenderbuffers; friend class CHyprOpenGLImpl; From c24034eb9d33f104f9e1f9016d93a2600dba2a92 Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Thu, 28 Mar 2024 02:08:21 +0000 Subject: [PATCH 0075/2772] core: fix fullscreen + floating focus change (#5291) modified: src/Compositor.cpp --- src/Compositor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 68db0091..2e49237c 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1568,7 +1568,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { // for tiled windows, we calc edges for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || w->m_bIsFloating || !isWorkspaceVisible(w->m_iWorkspaceID)) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->m_iWorkspaceID)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_iWorkspaceID != w->m_iWorkspaceID) @@ -1657,7 +1657,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { constexpr float THRESHOLD = 0.3 * M_PI; for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || !w->m_bIsFloating || !isWorkspaceVisible(w->m_iWorkspaceID)) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->m_iWorkspaceID)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_iWorkspaceID != w->m_iWorkspaceID) From 25718754534d0ccd87b198b63459497e63887f35 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 28 Mar 2024 02:28:16 +0000 Subject: [PATCH 0076/2772] format: fix format --- src/managers/input/TextInput.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index 7bb6c81a..39a03c91 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -88,10 +88,10 @@ void CTextInput::onDisabled() { } if (!focusedSurface()) - return; + return; if (!isV3()) - leave(); + leave(); hyprListener_surfaceDestroyed.removeCallback(); hyprListener_surfaceUnmapped.removeCallback(); From 647d5a4ffc08ee654eb3ce951977789b1385a7f8 Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:14:27 +0000 Subject: [PATCH 0077/2772] layers: fix bottom slide animation (#5307) modified: src/helpers/WLClasses.cpp --- src/helpers/WLClasses.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 96ba0fa5..edcdfb14 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -118,7 +118,7 @@ void SLayerSurface::startAnimation(bool in, bool instant) { break; case 1: // BOTTOM - prePos = {geometry.x, PMONITOR->vecPosition.y + PMONITOR->vecPosition.y}; + prePos = {geometry.x, PMONITOR->vecPosition.y + PMONITOR->vecSize.y}; break; case 2: // LEFT From 187caf4187ffc16ec159b1a5b15657a18dfc05e1 Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:15:34 +0000 Subject: [PATCH 0078/2772] layers: don't change workspace on layer restore focus (#5308) modified: src/events/Layers.cpp --- src/events/Layers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index f4b52445..a1fef175 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -237,7 +237,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface); - if (!foundSurface && g_pCompositor->m_pLastWindow) { + if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_iWorkspaceID)) { // if there isn't any, focus the last window const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->focusWindow(nullptr); From d8429eebc66e7091381502edc0fc7335790f62e4 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Thu, 28 Mar 2024 18:43:58 +0200 Subject: [PATCH 0079/2772] flake.lock: update Fixes #5301 --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index a883fa8e..288a335b 100644 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ ] }, "locked": { - "lastModified": 1711035742, - "narHash": "sha256-5vvhCSUGG9TA2G1eIRgokuYizhRnZu0ZbcU1MXfHsUE=", + "lastModified": 1711466786, + "narHash": "sha256-sArxGyUBiCA1in+q6t0QqT+ZJiZ1PyBp7cNPKLmREM0=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "6a92473237f430399a417e1c2da9d7fcd4970086", + "rev": "d3876f34779cc03ee51e4aafc0d00a4f187c7544", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1710960526, - "narHash": "sha256-tt0UgVKWeLQ+tFzvqrm4uAZbzONwdGshpfiLHAQ1P2c=", + "lastModified": 1711250455, + "narHash": "sha256-LSq1ZsTpeD7xsqvlsepDEelWRDtAhqwetp6PusHXJRo=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "a2f39421144d42541c057be235154ce21b76c0f6", + "rev": "b3e430f81f3364c5dd1a3cc9995706a4799eb3fa", "type": "github" }, "original": { @@ -94,11 +94,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1711001935, - "narHash": "sha256-URtGpHue7HHZK0mrHnSf8wJ6OmMKYSsoLmJybrOLFSQ=", + "lastModified": 1711523803, + "narHash": "sha256-UKcYiHWHQynzj6CN/vTcix4yd1eCu1uFdsuarupdCQQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "20f77aa09916374aa3141cbc605c955626762c9a", + "rev": "2726f127c15a4cc9810843b96cad73c7eb39e443", "type": "github" }, "original": { From 2930c5cb6f5d71dbdfd4d396287f90e19cd41228 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 29 Mar 2024 00:23:16 +0000 Subject: [PATCH 0080/2772] animvar: fixup update callbacks and cleanup --- src/desktop/Window.cpp | 16 ++++++++-------- src/desktop/Workspace.cpp | 8 +++----- src/helpers/AnimatedVariable.cpp | 25 ++++++++++++++++++++++++- src/helpers/AnimatedVariable.hpp | 28 ++++++++++++++++++++++++++-- src/helpers/WLClasses.cpp | 9 +++------ src/hyprerror/HyprError.cpp | 2 +- 6 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 9151d57e..81c77455 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -6,14 +6,14 @@ #include "../config/ConfigValue.hpp" CWindow::CWindow() { - m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); - m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); - m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER); - m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), (void*)this, AVARDAMAGE_BORDER); - m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE); - m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), (void*)this, AVARDAMAGE_ENTIRE); - m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW); - m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE); + m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE); + m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE); + m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), this, AVARDAMAGE_BORDER); + m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), this, AVARDAMAGE_BORDER); + m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), this, AVARDAMAGE_ENTIRE); + m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), this, AVARDAMAGE_ENTIRE); + m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), this, AVARDAMAGE_SHADOW); + m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), this, AVARDAMAGE_ENTIRE); addWindowDeco(std::make_unique(this)); addWindowDeco(std::make_unique(this)); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index d5f72384..440afc56 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -15,12 +15,10 @@ CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { m_szName = name; m_bIsSpecialWorkspace = special; - m_vRenderOffset.m_pWorkspace = this; - m_vRenderOffset.create(special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, + m_vRenderOffset.create(special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), this, AVARDAMAGE_ENTIRE); - m_fAlpha.m_pWorkspace = this; - m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), - nullptr, AVARDAMAGE_ENTIRE); + m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), this, + AVARDAMAGE_ENTIRE); m_fAlpha.setValueAndWarp(1.f); m_vRenderOffset.registerVar(); diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 3a891e37..74575c83 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -6,7 +6,7 @@ CBaseAnimatedVariable::CBaseAnimatedVariable(ANIMATEDVARTYPE type) : m_Type(type ; // dummy var } -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) { +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, CWindow* pWindow, AVARDAMAGEPOLICY policy) { m_eDamagePolicy = policy; m_pConfig = pAnimConfig; m_pWindow = pWindow; @@ -14,6 +14,29 @@ void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, void* m_bDummy = false; } +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy) { + m_eDamagePolicy = policy; + m_pConfig = pAnimConfig; + m_pLayer = pLayer; + + m_bDummy = false; +} + +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy) { + m_eDamagePolicy = policy; + m_pConfig = pAnimConfig; + m_pWorkspace = pWorkspace; + + m_bDummy = false; +} + +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, AVARDAMAGEPOLICY policy) { + m_eDamagePolicy = policy; + m_pConfig = pAnimConfig; + + m_bDummy = false; +} + CBaseAnimatedVariable::~CBaseAnimatedVariable() { unregister(); } diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 88c775af..82e30892 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -67,7 +67,10 @@ concept Animable = OneOf; class CBaseAnimatedVariable { public: CBaseAnimatedVariable(ANIMATEDVARTYPE type); - void create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, CWindow* pWindow, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, AVARDAMAGEPOLICY policy); CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete; @@ -204,11 +207,26 @@ class CAnimatedVariable : public CBaseAnimatedVariable { public: CAnimatedVariable() : CBaseAnimatedVariable(typeToANIMATEDVARTYPE) {} // dummy var - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) { + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, CWindow* pWindow, AVARDAMAGEPOLICY policy) { create(pAnimConfig, pWindow, policy); m_Value = value; m_Goal = value; } + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy) { + create(pAnimConfig, pLayer, policy); + m_Value = value; + m_Goal = value; + } + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy) { + create(pAnimConfig, pWorkspace, policy); + m_Value = value; + m_Goal = value; + } + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, AVARDAMAGEPOLICY policy) { + create(pAnimConfig, policy); + m_Value = value; + m_Goal = value; + } using CBaseAnimatedVariable::create; @@ -261,10 +279,16 @@ class CAnimatedVariable : public CBaseAnimatedVariable { } void warp(bool endCallback = true) override { + if (m_Value == m_Goal) + return; + m_Value = m_Goal; m_bIsBeingAnimated = false; + if (m_fUpdateCallback) + m_fUpdateCallback(this); + if (endCallback) onAnimationEnd(); } diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index edcdfb14..084a719d 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -3,12 +3,9 @@ #include "../Compositor.hpp" SLayerSurface::SLayerSurface() { - alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayers"), nullptr, AVARDAMAGE_ENTIRE); - realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layers"), nullptr, AVARDAMAGE_ENTIRE); - realSize.create(g_pConfigManager->getAnimationPropertyConfig("layers"), nullptr, AVARDAMAGE_ENTIRE); - alpha.m_pLayer = this; - realPosition.m_pLayer = this; - realSize.m_pLayer = this; + alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayers"), this, AVARDAMAGE_ENTIRE); + realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layers"), this, AVARDAMAGE_ENTIRE); + realSize.create(g_pConfigManager->getAnimationPropertyConfig("layers"), this, AVARDAMAGE_ENTIRE); alpha.registerVar(); realPosition.registerVar(); realSize.registerVar(); diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index a7636b1c..73f9c5d5 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -3,7 +3,7 @@ #include "../config/ConfigValue.hpp" CHyprError::CHyprError() { - m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_NONE); + m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE); m_fFadeOpacity.registerVar(); g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) { From fcd9d77b642c0cd45cae61cf10ed1924f2e7945b Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 29 Mar 2024 00:43:50 +0000 Subject: [PATCH 0081/2772] layout: improve initial size prediction for floating --- src/events/Windows.cpp | 17 +---------- src/layout/DwindleLayout.cpp | 2 +- src/layout/DwindleLayout.hpp | 2 +- src/layout/IHyprLayout.cpp | 57 ++++++++++++++++++++++++++++++++++-- src/layout/IHyprLayout.hpp | 8 ++++- src/layout/MasterLayout.cpp | 2 +- src/layout/MasterLayout.hpp | 2 +- 7 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 0d1665b7..00546550 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -782,22 +782,7 @@ void Events::listener_commitWindow(void* owner, void* data) { CWindow* PWINDOW = (CWindow*)owner; if (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->initial_commit) { - Vector2D predSize = g_pLayoutManager->getCurrentLayout()->predictSizeForNewWindow(); - - if (g_pXWaylandManager->shouldBeFloated(PWINDOW, true)) - predSize = {}; - - Vector2D maxSize = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->pending.max_width, PWINDOW->m_uSurface.xdg->toplevel->pending.max_height}; - - if ((maxSize.x > 0 && maxSize.x < predSize.x) || (maxSize.y > 0 && maxSize.y < predSize.y)) - predSize = {}; - - for (auto& r : g_pConfigManager->getMatchingRules(PWINDOW, true, true)) { - if (r.szRule.starts_with("float")) { - predSize = {}; - break; - } - } + Vector2D predSize = g_pLayoutManager->getCurrentLayout()->predictSizeForNewWindow(PWINDOW); Debug::log(LOG, "Layout predicts size {} for {}", predSize, PWINDOW); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index c34f04cc..fe8847ed 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -1116,7 +1116,7 @@ void CHyprDwindleLayout::onDisable() { m_lDwindleNodesData.clear(); } -Vector2D CHyprDwindleLayout::predictSizeForNewWindow() { +Vector2D CHyprDwindleLayout::predictSizeForNewWindowTiled() { if (!g_pCompositor->m_pLastMonitor) return {}; diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index 5ca90fcd..b8c752f4 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -59,7 +59,7 @@ class CHyprDwindleLayout : public IHyprLayout { virtual void alterSplitRatio(CWindow*, float, bool); virtual std::string getLayoutName(); virtual void replaceWindowDataWith(CWindow* from, CWindow* to); - virtual Vector2D predictSizeForNewWindow(); + virtual Vector2D predictSizeForNewWindowTiled(); virtual void onEnable(); virtual void onDisable(); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 6a32144e..1570fd73 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -644,8 +644,61 @@ void IHyprLayout::requestFocusForWindow(CWindow* pWindow) { g_pCompositor->warpCursorTo(pWindow->middle()); } -Vector2D IHyprLayout::predictSizeForNewWindow() { - return Vector2D{}; +Vector2D IHyprLayout::predictSizeForNewWindowFloating(CWindow* pWindow) { // get all rules, see if we have any size overrides. + Vector2D sizeOverride = {}; + if (g_pCompositor->m_pLastMonitor) { + for (auto& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) { + if (r.szRule.starts_with("size")) { + try { + const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1); + const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); + const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); + + const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); + + const auto SIZEX = SIZEXSTR == "max" ? + std::clamp(MAXSIZE.x, 20.0, g_pCompositor->m_pLastMonitor->vecSize.x) : + (!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.x); + const auto SIZEY = SIZEYSTR == "max" ? + std::clamp(MAXSIZE.y, 20.0, g_pCompositor->m_pLastMonitor->vecSize.y) : + (!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.y); + + sizeOverride = {SIZEX, SIZEY}; + + } catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); } + break; + } + } + } + + return sizeOverride; +} + +Vector2D IHyprLayout::predictSizeForNewWindow(CWindow* pWindow) { + bool shouldBeFloated = g_pXWaylandManager->shouldBeFloated(pWindow, true); + + if (!shouldBeFloated) { + for (auto& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) { + if (r.szRule.starts_with("float")) { + shouldBeFloated = true; + break; + } + } + } + + Vector2D sizePredicted = {}; + + if (!shouldBeFloated) + sizePredicted = predictSizeForNewWindowTiled(); + else + sizePredicted = predictSizeForNewWindowFloating(pWindow); + + Vector2D maxSize = Vector2D{pWindow->m_uSurface.xdg->toplevel->pending.max_width, pWindow->m_uSurface.xdg->toplevel->pending.max_height}; + + if ((maxSize.x > 0 && maxSize.x < sizePredicted.x) || (maxSize.y > 0 && maxSize.y < sizePredicted.y)) + sizePredicted = {}; + + return sizePredicted; } IHyprLayout::~IHyprLayout() {} diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index e168556e..d6c41d3b 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -187,7 +187,13 @@ class IHyprLayout { Called to predict the size of a newly opened window to send it a configure. Return 0,0 if unpredictable */ - virtual Vector2D predictSizeForNewWindow(); + virtual Vector2D predictSizeForNewWindowTiled() = 0; + + /* + Prefer not overriding, use predictSizeForNewWindowTiled. + */ + virtual Vector2D predictSizeForNewWindow(CWindow* pWindow); + virtual Vector2D predictSizeForNewWindowFloating(CWindow* pWindow); private: int m_iMouseMoveEventCount; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 1c6be8d6..ea54b0e2 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -1435,7 +1435,7 @@ void CHyprMasterLayout::replaceWindowDataWith(CWindow* from, CWindow* to) { applyNodeDataToWindow(PNODE); } -Vector2D CHyprMasterLayout::predictSizeForNewWindow() { +Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() { static auto PNEWISMASTER = CConfigValue("master:new_is_master"); if (!g_pCompositor->m_pLastMonitor) diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 6f8ea120..1e48b5dd 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -65,7 +65,7 @@ class CHyprMasterLayout : public IHyprLayout { virtual void alterSplitRatio(CWindow*, float, bool); virtual std::string getLayoutName(); virtual void replaceWindowDataWith(CWindow* from, CWindow* to); - virtual Vector2D predictSizeForNewWindow(); + virtual Vector2D predictSizeForNewWindowTiled(); virtual void onEnable(); virtual void onDisable(); From 53aa184d2099b1f5c1b712df1484211bad3d6093 Mon Sep 17 00:00:00 2001 From: Muhamed Hobi Date: Fri, 29 Mar 2024 10:07:33 -0400 Subject: [PATCH 0082/2772] makefile: Remove old headers first (#5316) Windows.cpp was moved and I found myself having both versions in my include. Clear out the headers before dumping new ones. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c29f20a0..71097960 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,7 @@ pluginenv: installheaders: @if [ ! -f ./src/version.h ]; then echo -en "You need to run $(MAKE) all first.\n" && exit 1; fi + rm -fr ${PREFIX}/include/hyprland mkdir -p ${PREFIX}/include/hyprland mkdir -p ${PREFIX}/include/hyprland/protocols mkdir -p ${PREFIX}/include/hyprland/wlroots From 3d1bf1405ee2b368b461164210ad1485d5f32178 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 29 Mar 2024 18:57:10 +0000 Subject: [PATCH 0083/2772] keybinds: add binds:disable_keybind_grabbing fixes #5273 --- src/config/ConfigManager.cpp | 1 + src/managers/KeybindManager.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 17dea1a7..1229e80b 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -490,6 +490,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("binds:focus_preferred_method", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:ignore_group_lock", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:movefocus_cycles_fullscreen", Hyprlang::INT{1}); + m_pConfig->addConfigValue("binds:disable_keybind_grabbing", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_fingers", Hyprlang::INT{3}); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a8d390fa..57b1b4e0 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -501,7 +501,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi if (g_pCompositor->m_sSeat.exclusiveClient) Debug::log(LOG, "Keybind handling only locked (inhibitor)"); - if (!m_lShortcutInhibitors.empty()) { + static auto PDISABLEINHIBIT = CConfigValue("binds:disable_keybind_grabbing"); + + if (!*PDISABLEINHIBIT && !m_lShortcutInhibitors.empty()) { for (auto& i : m_lShortcutInhibitors) { if (i.pWlrInhibitor->surface == g_pCompositor->m_pLastFocus) { Debug::log(LOG, "Keybind handling is disabled due to an inhibitor for surface {:x}", (uintptr_t)i.pWlrInhibitor->surface); From 54376d7b5f88bffd96ce9ded26637d83d7aa95b1 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 29 Mar 2024 19:06:08 +0000 Subject: [PATCH 0084/2772] compositor: remove windows from fading out on destroy ref #5321 --- src/Compositor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 2e49237c..7e81797f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -693,6 +693,8 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) { void CCompositor::removeWindowFromVectorSafe(CWindow* pWindow) { if (windowExists(pWindow) && !pWindow->m_bFadingOut) std::erase_if(m_vWindows, [&](std::unique_ptr& el) { return el.get() == pWindow; }); + + std::erase_if(m_vWindowsFadingOut, [&](CWindow* el) { return el == pWindow; }); } bool CCompositor::windowExists(CWindow* pWindow) { From 6fb8f502050c269597636c3b0bfcf046f7f6a947 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 30 Mar 2024 03:09:22 +0000 Subject: [PATCH 0085/2772] hyprpm: avoid crashes on corrupted headers ref #5329 --- hyprpm/src/core/PluginManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp index c5926c3e..965f2e9d 100644 --- a/hyprpm/src/core/PluginManager.cpp +++ b/hyprpm/src/core/PluginManager.cpp @@ -333,7 +333,12 @@ eHeadersErrors CPluginManager::headersValid() { std::string verHeaderContent((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); ifs.close(); - std::string hash = verHeaderContent.substr(verHeaderContent.find("#define GIT_COMMIT_HASH") + 23); + const auto HASHPOS = verHeaderContent.find("#define GIT_COMMIT_HASH"); + + if (HASHPOS == std::string::npos || HASHPOS + 23 >= verHeaderContent.length()) + return HEADERS_CORRUPTED; + + std::string hash = verHeaderContent.substr(HASHPOS + 23); hash = hash.substr(0, hash.find_first_of('\n')); hash = hash.substr(hash.find_first_of('"') + 1); hash = hash.substr(0, hash.find_first_of('"')); From a17d7ba87b661e0f152fa59bc9efdf1da2a84c86 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 30 Mar 2024 09:57:43 -0700 Subject: [PATCH 0086/2772] dispatchers: fix swap workspaces wrong positioning of floating windows (#5328) --- src/Compositor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 7e81797f..6276b735 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2024,7 +2024,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) // additionally, move floating and fs windows manually if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.value() - pMonitorA->vecPosition + pMonitorB->vecPosition; + w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorA->vecPosition + pMonitorB->vecPosition; if (w->m_bIsFullscreen) { w->m_vRealPosition = pMonitorB->vecPosition; @@ -2049,7 +2049,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) // additionally, move floating and fs windows manually if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.value() - pMonitorB->vecPosition + pMonitorA->vecPosition; + w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorB->vecPosition + pMonitorA->vecPosition; if (w->m_bIsFullscreen) { w->m_vRealPosition = pMonitorA->vecPosition; @@ -2226,7 +2226,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni if (w->m_bIsMapped && !w->isHidden()) { if (POLDMON) { if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.value() - POLDMON->vecPosition + pMonitor->vecPosition; + w->m_vRealPosition = w->m_vRealPosition.goal() - POLDMON->vecPosition + pMonitor->vecPosition; if (w->m_bIsFullscreen) { w->m_vRealPosition = pMonitor->vecPosition; From 906e49814412921fd6d0e0188416665dd8ef3e0c Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 30 Mar 2024 09:58:18 -0700 Subject: [PATCH 0087/2772] dispatchers: open special ws on active monitor instead of mouse monitor (#5330) --- src/managers/KeybindManager.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 57b1b4e0..03887514 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1624,9 +1624,6 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { } void CKeybindManager::toggleSpecialWorkspace(std::string args) { - - static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); - std::string workspaceName = ""; int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName); @@ -1636,7 +1633,7 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) { } bool requestedWorkspaceIsAlreadyOpen = false; - const auto PMONITOR = *PFOLLOWMOUSE == 1 ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->m_pLastMonitor; + const auto PMONITOR = g_pCompositor->m_pLastMonitor; int specialOpenOnMonitor = PMONITOR->specialWorkspaceID; for (auto& m : g_pCompositor->m_vMonitors) { From 77f26997fd00aaec958463414269fa3d8f62bb63 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 30 Mar 2024 17:00:56 +0000 Subject: [PATCH 0088/2772] IME: don't assert on lock mismatch, just fix it --- src/managers/input/TextInput.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index 39a03c91..eeea899d 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -170,7 +170,11 @@ void CTextInput::enter(wlr_surface* pSurface) { } enterLocks++; - RASSERT(enterLocks == 1, "TextInput had != 1 lock in enter"); + if (enterLocks != 1) { + Debug::log(ERR, "BUG THIS: TextInput has != 1 locks in enter"); + leave(); + enterLocks = 1; + } if (pWlrInput) wlr_text_input_v3_send_enter(pWlrInput, pSurface); @@ -187,7 +191,10 @@ void CTextInput::leave() { return; enterLocks--; - RASSERT(enterLocks == 0, "TextInput had != 0 locks in leave"); + if (enterLocks != 1) { + Debug::log(ERR, "BUG THIS: TextInput has != 0 locks in leave"); + enterLocks = 0; + } if (pWlrInput && pWlrInput->focused_surface) wlr_text_input_v3_send_leave(pWlrInput); From 1aed45f61d2dd48943a63cabf7bd77c19a59cf62 Mon Sep 17 00:00:00 2001 From: Aqa-Ib Date: Sun, 31 Mar 2024 01:48:39 +0100 Subject: [PATCH 0089/2772] core: Fix resizeparams (#5262) * Revert a94b902 * Fix resizeparams using CVarList * clang-format * fix * Use 's' as delimiter * remove size checks * fix tabs * fix mixing tabs and spaces --- src/Compositor.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 6276b735..30e769e3 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -10,6 +10,7 @@ #include // for sd_notify #endif #include +#include "helpers/VarList.hpp" int handleCritSignal(int signo, void* data) { Debug::log(LOG, "Hyprland received signal {}", signo); @@ -2545,7 +2546,7 @@ SLayerSurface* CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { // returns a delta Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, const Vector2D& relativeTo) { - if (!args.contains(' ')) + if (!args.contains(' ') && !args.contains('\t')) return relativeTo; const auto PMONITOR = m_pLastMonitor; @@ -2554,12 +2555,13 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con bool yIsPercent = false; bool isExact = false; - std::string x = args.substr(0, args.find_first_of(' ')); - std::string y = args.substr(args.find_last_of(' ') + 1); + CVarList varList(args, 0, 's', true); + std::string x = varList[0]; + std::string y = varList[1]; if (x == "exact") { - x = y.substr(0, y.find_first_of(' ')); - y = y.substr(y.find_first_of(' ') + 1); + x = varList[1]; + y = varList[2]; isExact = true; } From 5e8c25d498ed5cb7852ae74a876b0c138a62d59d Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:49:53 -0700 Subject: [PATCH 0090/2772] core: match all workspace rules instead of the first one only (#5340) --- src/Compositor.cpp | 15 ++++++++++---- src/config/ConfigManager.cpp | 12 +++++++----- src/config/ConfigManager.hpp | 2 +- src/desktop/Window.cpp | 29 +++++++++++++++++++-------- src/desktop/Workspace.cpp | 8 +++++--- src/layout/DwindleLayout.cpp | 25 ++++++++++++++++++------ src/layout/MasterLayout.cpp | 38 +++++++++++++++++++++++++----------- 7 files changed, 91 insertions(+), 38 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 30e769e3..3ac9a73f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1260,8 +1260,13 @@ void CCompositor::sanityCheckWorkspaces() { auto it = m_vWorkspaces.begin(); while (it != m_vWorkspaces.end()) { - const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(it->get()); - if (WORKSPACERULE.isPersistent) { + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(it->get()); + bool isPersistent = false; + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.isPersistent) + isPersistent = true; + } + if (isPersistent) { ++it; continue; } @@ -1288,8 +1293,10 @@ void CCompositor::sanityCheckWorkspaces() { continue; } if (!WORKSPACE->m_bOnCreatedEmptyExecuted) { - if (auto cmd = WORKSPACERULE.onCreatedEmptyRunCmd) - g_pKeybindManager->spawn(*cmd); + for (auto& wsRule : WORKSPACERULES) { + if (auto cmd = wsRule.onCreatedEmptyRunCmd) + g_pKeybindManager->spawn(*cmd); + } WORKSPACE->m_bOnCreatedEmptyExecuted = true; } diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 1229e80b..df2006ae 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -956,11 +956,13 @@ SMonitorRule CConfigManager::getMonitorRuleFor(const CMonitor& PMONITOR) { return SMonitorRule{.name = "", .resolution = Vector2D(0, 0), .offset = Vector2D(-INT32_MAX, -INT32_MAX), .scale = -1}; // 0, 0 is preferred and -1, -1 is auto } -SWorkspaceRule CConfigManager::getWorkspaceRuleFor(CWorkspace* pWorkspace) { - const auto IT = std::find_if(m_dWorkspaceRules.begin(), m_dWorkspaceRules.end(), [&](const auto& other) { return pWorkspace->matchesStaticSelector(other.workspaceString); }); - if (IT == m_dWorkspaceRules.end()) - return SWorkspaceRule{}; - return *IT; +std::vector CConfigManager::getWorkspaceRulesFor(CWorkspace* pWorkspace) { + std::vector results; + for (auto& rule : m_dWorkspaceRules) { + if (pWorkspace->matchesStaticSelector(rule.workspaceString)) + results.push_back(rule); + } + return results; } std::vector CConfigManager::getMatchingRules(CWindow* pWindow, bool dynamic, bool shadowExec) { diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 9fd1e097..5406d853 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -105,7 +105,7 @@ class CConfigManager { static std::string getMainConfigPath(); SMonitorRule getMonitorRuleFor(const CMonitor&); - SWorkspaceRule getWorkspaceRuleFor(CWorkspace*); + std::vector getWorkspaceRulesFor(CWorkspace*); std::string getDefaultWorkspaceFor(const std::string&); CMonitor* getBoundMonitorForWS(const std::string&); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 81c77455..1336456a 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1088,20 +1088,33 @@ float CWindow::rounding() { } void CWindow::updateSpecialRenderData() { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); - const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{}; - bool border = true; + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + const auto WORKSPACERULES = PWORKSPACE ? g_pConfigManager->getWorkspaceRulesFor(PWORKSPACE) : std::vector{}; + bool border = true; static auto PNOBORDERONFLOATING = CConfigValue("general:no_border_on_floating"); if (m_bIsFloating && *PNOBORDERONFLOATING == 1) border = false; - m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(border); - m_sSpecialRenderData.borderSize = WORKSPACERULE.borderSize.value_or(-1); - m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true); - m_sSpecialRenderData.rounding = WORKSPACERULE.rounding.value_or(true); - m_sSpecialRenderData.shadow = WORKSPACERULE.shadow.value_or(true); + m_sSpecialRenderData.border = border; + m_sSpecialRenderData.borderSize = -1; + m_sSpecialRenderData.decorate = true; + m_sSpecialRenderData.rounding = true; + m_sSpecialRenderData.shadow = true; + + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.border.has_value()) + m_sSpecialRenderData.border = wsRule.border.value(); + if (wsRule.borderSize.has_value()) + m_sSpecialRenderData.borderSize = wsRule.borderSize.value(); + if (wsRule.decorate.has_value()) + m_sSpecialRenderData.decorate = wsRule.decorate.value(); + if (wsRule.rounding.has_value()) + m_sSpecialRenderData.rounding = wsRule.rounding.value(); + if (wsRule.shadow.has_value()) + m_sSpecialRenderData.shadow = wsRule.shadow.value(); + } } int CWindow::getRealBorderSize() { diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 440afc56..05843b59 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -24,9 +24,11 @@ CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { m_vRenderOffset.registerVar(); m_fAlpha.registerVar(); - const auto RULEFORTHIS = g_pConfigManager->getWorkspaceRuleFor(this); - if (RULEFORTHIS.defaultName.has_value()) - m_szName = RULEFORTHIS.defaultName.value(); + const auto RULESFORTHIS = g_pConfigManager->getWorkspaceRulesFor(this); + for (auto& rule : RULESFORTHIS) { + if (rule.defaultName.has_value()) + m_szName = rule.defaultName.value(); + } g_pEventManager->postEvent({"createworkspace", m_szName}); g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)}); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index fe8847ed..93f60e3f 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -128,7 +128,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for const auto PWINDOW = pNode->pWindow; // get specific gaps and rules for this workspace, // if user specified them in config - const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(pNode->workspaceID)); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(pNode->workspaceID)); if (!g_pCompositor->windowExists(PWINDOW)) { Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW); @@ -147,10 +147,16 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for auto* const PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData(); auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData(); - auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN); - auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); + auto gapsIn = *PGAPSIN; + auto gapsOut = *PGAPSOUT; + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.gapsIn.has_value()) + gapsIn = wsRule.gapsIn.value(); + if (wsRule.gapsOut.has_value()) + gapsOut = wsRule.gapsOut.value(); + } - CBox nodeBox = pNode->box; + CBox nodeBox = pNode->box; nodeBox.round(); PWINDOW->m_vSize = nodeBox.size(); @@ -161,10 +167,17 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && (NODESONWORKSPACE == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { - PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(*PNOGAPSWHENONLY == 2); - PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true); PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.shadow = false; + PWINDOW->m_sSpecialRenderData.border = (*PNOGAPSWHENONLY == 2); + PWINDOW->m_sSpecialRenderData.decorate = true; + + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.border.has_value()) + PWINDOW->m_sSpecialRenderData.border = wsRule.border.value(); + if (wsRule.decorate.has_value()) + PWINDOW->m_sSpecialRenderData.decorate = wsRule.decorate.value(); + } PWINDOW->updateWindowDecos(); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index ea54b0e2..9c49197e 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -41,14 +41,17 @@ SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) { } //create on the fly if it doesn't exist yet - const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back(); - PWORKSPACEDATA->workspaceID = ws; - static auto PORIENTATION = CConfigValue("master:orientation"); - const auto layoutoptsForWs = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(ws)).layoutopts; + const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back(); + PWORKSPACEDATA->workspaceID = ws; + static auto PORIENTATION = CConfigValue("master:orientation"); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(ws)); + std::string orientationForWs = *PORIENTATION; - if (layoutoptsForWs.contains("orientation")) - orientationForWs = layoutoptsForWs.at("orientation"); + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.layoutopts.contains("orientation")) + orientationForWs = wsRule.layoutopts.at("orientation"); + } if (orientationForWs == "top") { PWORKSPACEDATA->orientation = ORIENTATION_TOP; @@ -626,7 +629,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { const auto PWINDOW = pNode->pWindow; // get specific gaps and rules for this workspace, // if user specified them in config - const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)); if (PWINDOW->m_bIsFullscreen && !pNode->ignoreFullscreenChecks) return; @@ -640,8 +643,14 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { auto* PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData(); auto* PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData(); - auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN); - auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); + auto gapsIn = *PGAPSIN; + auto gapsOut = *PGAPSOUT; + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.gapsIn.has_value()) + gapsIn = wsRule.gapsIn.value(); + if (wsRule.gapsOut.has_value()) + gapsOut = wsRule.gapsOut.value(); + } if (!g_pCompositor->windowValidMapped(PWINDOW)) { Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW); @@ -655,10 +664,17 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { - PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(*PNOGAPSWHENONLY == 2); - PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true); PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.shadow = false; + PWINDOW->m_sSpecialRenderData.border = (*PNOGAPSWHENONLY == 2); + PWINDOW->m_sSpecialRenderData.decorate = true; + + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.border.has_value()) + PWINDOW->m_sSpecialRenderData.border = wsRule.border.value(); + if (wsRule.decorate.has_value()) + PWINDOW->m_sSpecialRenderData.decorate = wsRule.decorate.value(); + } PWINDOW->updateWindowDecos(); From 1cc9a44318e53a34f41cc36483502de985b88cf8 Mon Sep 17 00:00:00 2001 From: Zach DeCook Date: Sat, 30 Mar 2024 20:50:25 -0400 Subject: [PATCH 0091/2772] input: Fix incorrect keyboard focus taken when no window was present (#5337) A non-keyboard layer never needs keyboard focus --- src/managers/input/InputManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 690463fa..4e2bf709 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -422,10 +422,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { unsetCursorImage(); } - if (pFoundLayerSurface && - (pFoundLayerSurface->layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE || - (pFoundLayerSurface->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP && !g_pCompositor->m_pLastWindow)) && - FOLLOWMOUSE != 3 && allowKeyboardRefocus) { + if (pFoundLayerSurface && (pFoundLayerSurface->layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 && + allowKeyboardRefocus) { g_pCompositor->focusSurface(foundSurface); } From 16a9c16d9f99bd8be9f1bb15442b001fdf2ea759 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:14:26 -0700 Subject: [PATCH 0092/2772] renderer/animations: Fix various inaccurate damage tracking issues and offsets (#5297) --- src/desktop/Window.cpp | 38 ++++++++ src/desktop/Window.hpp | 4 + src/desktop/Workspace.cpp | 10 ++ src/helpers/Box.cpp | 25 ++--- src/helpers/Box.hpp | 2 +- src/managers/AnimationManager.cpp | 94 +++++++----------- src/render/Renderer.cpp | 97 ++++++++----------- src/render/Renderer.hpp | 4 +- .../decorations/CHyprBorderDecoration.cpp | 34 ++++++- .../decorations/CHyprBorderDecoration.hpp | 2 +- .../decorations/CHyprDropShadowDecoration.cpp | 42 +++++++- .../decorations/CHyprDropShadowDecoration.hpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 18 ++-- .../decorations/CHyprGroupBarDecoration.hpp | 2 +- .../decorations/IHyprWindowDecoration.hpp | 2 +- 15 files changed, 229 insertions(+), 147 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 1336456a..891fd652 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1165,6 +1165,44 @@ void CWindow::setAnimationsToMove() { m_bAnimatingIn = false; } +void CWindow::onWorkspaceAnimUpdate() { + // clip box for animated offsets + if (!m_bIsFloating || m_bPinned || m_bIsFullscreen) { + m_vFloatingOffset = Vector2D(0, 0); + return; + } + + Vector2D offset; + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + if (!PWORKSPACE) + return; + + const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); + if (!PWSMON) + return; + + const auto WINBB = getFullWindowBoundingBox(); + if (PWORKSPACE->m_vRenderOffset.value().x != 0) { + const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x; + + if (WINBB.x < PWSMON->vecPosition.x) + offset.x += (PWSMON->vecPosition.x - WINBB.x) * PROGRESS; + + if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) + offset.x += (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS; + } else if (PWORKSPACE->m_vRenderOffset.value().y != 0) { + const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y; + + if (WINBB.y < PWSMON->vecPosition.y) + offset.y += (PWSMON->vecPosition.y - WINBB.y) * PROGRESS; + + if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y) + offset.y += (WINBB.y + WINBB.height - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS; + } + + m_vFloatingOffset = offset; +} + int CWindow::popupsCount() { if (m_bIsX11) return 1; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index d8b4012d..bc1820a0 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -237,6 +237,9 @@ class CWindow { Vector2D m_vLastFloatingSize; Vector2D m_vLastFloatingPosition; + // for floating window offset in workspace animations + Vector2D m_vFloatingOffset = Vector2D(0, 0); + // this is used for pseudotiling bool m_bIsPseudotiled = false; Vector2D m_vPseudoSize = Vector2D(0, 0); @@ -421,6 +424,7 @@ class CWindow { void updateGroupOutputs(); void switchWithWindowInGroup(CWindow* pWindow); void setAnimationsToMove(); + void onWorkspaceAnimUpdate(); private: // For hidden windows and stuff diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 05843b59..a0c14bba 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -49,6 +49,16 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle; static auto PWORKSPACEGAP = CConfigValue("general:gaps_workspaces"); + // set floating windows offset callbacks + m_vRenderOffset.setUpdateCallback([&](void*) { + for (auto& w : g_pCompositor->m_vWindows) { + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != m_iID) + continue; + + w->onWorkspaceAnimUpdate(); + }; + }); + if (ANIMSTYLE.starts_with("slidefade")) { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); float movePerc = 100.f; diff --git a/src/helpers/Box.cpp b/src/helpers/Box.cpp index e9e0eeeb..8470b509 100644 --- a/src/helpers/Box.cpp +++ b/src/helpers/Box.cpp @@ -106,6 +106,11 @@ CBox& CBox::expand(const double& value) { w += value * 2.0; h += value * 2.0; + if (w <= 0 || h <= 0) { + w = 0; + h = 0; + } + return *this; } @@ -116,22 +121,20 @@ CBox& CBox::noNegativeSize() { return *this; } -CBox& CBox::intersection(const CBox other) { - const float newTop = std::max(y, other.y); +CBox CBox::intersection(const CBox other) const { + const float newX = std::max(x, other.x); + const float newY = std::max(y, other.y); const float newBottom = std::min(y + h, other.y + other.h); - const float newLeft = std::max(x, other.x); const float newRight = std::min(x + w, other.x + other.w); - y = newTop; - x = newLeft; - w = newRight - newLeft; - h = newBottom - newTop; + float newW = newRight - newX; + float newH = newBottom - newY; - if (w <= 0 || h <= 0) { - w = 0; - h = 0; + if (newW <= 0 || newH <= 0) { + newW = 0; + newH = 0; } - return *this; + return {newX, newY, newW, newH}; } CBox CBox::roundInternal() { diff --git a/src/helpers/Box.hpp b/src/helpers/Box.hpp index e38d6108..98ba8d47 100644 --- a/src/helpers/Box.hpp +++ b/src/helpers/Box.hpp @@ -52,9 +52,9 @@ class CBox { CBox& addExtents(const SWindowDecorationExtents& e); CBox& expand(const double& value); CBox& noNegativeSize(); - CBox& intersection(const CBox other); CBox copy() const; + CBox intersection(const CBox other) const; SWindowDecorationExtents extentsFrom(const CBox&); // this is the big box diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 93608383..fc768b77 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -87,11 +87,15 @@ void CAnimationManager::tick() { CBox WLRBOXPREV = {0, 0, 0, 0}; if (PWINDOW) { - CBox bb = PWINDOW->getFullWindowBoundingBox(); - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); - if (PWINDOWWORKSPACE) - bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); - WLRBOXPREV = bb; + if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) { + g_pHyprRenderer->damageWindow(PWINDOW); + } else if (av->m_eDamagePolicy == AVARDAMAGE_BORDER) { + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); + PDECO->damageEntire(); + } else if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW) { + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); + PDECO->damageEntire(); + } PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); if (!PMONITOR) @@ -101,25 +105,35 @@ void CAnimationManager::tick() { PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); if (!PMONITOR) continue; - WLRBOXPREV = {PMONITOR->vecPosition, PMONITOR->vecSize}; + + // dont damage the whole monitor on workspace change, unless it's a special workspace, because dim/blur etc + if (PWORKSPACE->m_bIsSpecialWorkspace) + g_pHyprRenderer->damageMonitor(PMONITOR); // TODO: just make this into a damn callback already vax... for (auto& w : g_pCompositor->m_vWindows) { - if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating) - g_pHyprRenderer->damageWindow(w.get()); + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID) + continue; + + if (w->m_bIsFloating && !w->m_bPinned) { + // still doing the full damage hack for floating because sometimes when the window + // goes through multiple monitors the last rendered frame is missing damage somehow?? + const CBox windowBoxNoOffset = w->getFullWindowBoundingBox(); + const CBox monitorBox = {PMONITOR->vecPosition, PMONITOR->vecSize}; + if (windowBoxNoOffset.intersection(monitorBox) != windowBoxNoOffset) // on edges between multiple monitors + g_pHyprRenderer->damageWindow(w.get(), true); + } + + if (PWORKSPACE->m_bIsSpecialWorkspace) + g_pHyprRenderer->damageWindow(w.get(), true); // hack for special too because it can cross multiple monitors } - // if a special workspace window is on any monitor, damage it + // damage any workspace window that is on any monitor for (auto& w : g_pCompositor->m_vWindows) { - for (auto& m : g_pCompositor->m_vMonitors) { - if (w->m_iWorkspaceID == PWORKSPACE->m_iID && PWORKSPACE->m_bIsSpecialWorkspace && g_pCompositor->windowValidMapped(w.get()) && - g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) { - CBox bb = w->getFullWindowBoundingBox(); - bb.translate(PWORKSPACE->m_vRenderOffset.value()); - bb.intersection({m->vecPosition, m->vecSize}); - g_pHyprRenderer->damageBox(&bb); - } - } + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID || w->m_bPinned) + continue; + + g_pHyprRenderer->damageWindow(w.get()); } } else if (PLAYER) { WLRBOXPREV = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; @@ -194,26 +208,13 @@ void CAnimationManager::tick() { if (PWINDOW) { PWINDOW->updateWindowDecos(); - auto bb = PWINDOW->getFullWindowBoundingBox(); - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); - if (PWINDOWWORKSPACE) - bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); - g_pHyprRenderer->damageBox(&bb); + g_pHyprRenderer->damageWindow(PWINDOW); } else if (PWORKSPACE) { for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden()) - continue; - - if (w->m_iWorkspaceID != PWORKSPACE->m_iID) + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID) continue; w->updateWindowDecos(); - - if (w->m_bIsFloating) { - auto bb = w->getFullWindowBoundingBox(); - bb.translate(PWORKSPACE->m_vRenderOffset.value()); - g_pHyprRenderer->damageBox(&bb); - } } } else if (PLAYER) { if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) @@ -229,31 +230,8 @@ void CAnimationManager::tick() { case AVARDAMAGE_BORDER: { RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!"); - // TODO: move this to the border class - - // damage only the border. - const auto ROUNDING = PWINDOW->rounding(); - const auto ROUNDINGSIZE = ROUNDING + 1; - const auto BORDERSIZE = PWINDOW->getRealBorderSize(); - - // damage for old box - g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top - g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height + 2 * BORDERSIZE); // left - g_pHyprRenderer->damageBox(WLRBOXPREV.x + WLRBOXPREV.width - ROUNDINGSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, - WLRBOXPREV.height + 2 * BORDERSIZE); // right - g_pHyprRenderer->damageBox(WLRBOXPREV.x, WLRBOXPREV.y + WLRBOXPREV.height - ROUNDINGSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, - BORDERSIZE + ROUNDINGSIZE); // bottom - - // damage for new box - CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value(), PWINDOW->m_vRealSize.value()}; - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); - if (PWINDOWWORKSPACE) - WLRBOXNEW.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); - g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top - g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left - g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, - WLRBOXNEW.height + 2 * BORDERSIZE); // right - g_pHyprRenderer->damageBox(WLRBOXNEW.x, WLRBOXNEW.y + WLRBOXNEW.height - ROUNDINGSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // bottom + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); + PDECO->damageEntire(); break; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 960add70..18110256 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -211,7 +211,7 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET; } -bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWorkspace* pWorkspace) { +bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { CBox geometry = pWindow->getFullWindowBoundingBox(); if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr())) @@ -234,9 +234,12 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo } } - if (pWindow->m_iWorkspaceID == pWorkspace->m_iID && pWorkspace->m_iMonitorID == pMonitor->ID) + if (pWindow->m_iMonitorID == pMonitor->ID) return true; + if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_iMonitorID != pMonitor->ID) + return false; + // if not, check if it maybe is active on a different monitor. if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors @@ -244,12 +247,20 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID) return true; + // if window is tiled and it's flying in, don't render on other mons (for slide) + if (!pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID) + return false; + if (pWindow->m_vRealPosition.isBeingAnimated()) { if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) return false; // render window if window and monitor intersect // (when moving out of or through a monitor) - CBox windowBox = pWindow->getFullWindowBoundingBox(); + CBox windowBox = pWindow->getFullWindowBoundingBox(); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + windowBox.translate(pWindow->m_vFloatingOffset); + const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize}; if (!windowBox.intersection(monitorBox).empty()) return true; @@ -292,7 +303,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // loop over the tiled windows that are fading out for (auto& w : g_pCompositor->m_vWindows) { - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (w->m_fAlpha.value() == 0.f) @@ -309,7 +320,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // and floating ones too for (auto& w : g_pCompositor->m_vWindows) { - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (w->m_fAlpha.value() == 0.f) @@ -345,7 +356,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (shouldRenderWindow(w.get(), pMonitor)) renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); if (w->m_iWorkspaceID != pWorkspace->m_iID) @@ -388,7 +399,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (w->m_bIsFloating) continue; // floating are in the second pass - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) @@ -418,7 +429,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; // render the bad boy @@ -433,7 +444,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (!w->m_bIsFloating || w->m_bPinned) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) @@ -510,47 +521,16 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha)); } - // clip box for animated offsets - const Vector2D PREOFFSETPOS = {renderdata.x, renderdata.y}; - if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bPinned && !pWindow->m_bIsFullscreen) { - Vector2D offset; - - if (PWORKSPACE->m_vRenderOffset.value().x != 0) { - const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x; - const auto WINBB = pWindow->getFullWindowBoundingBox(); - - if (WINBB.x < PWSMON->vecPosition.x) { - offset.x = (PWSMON->vecPosition.x - WINBB.x) * PROGRESS; - } else if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) { - offset.x = (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS; - } - } else if (PWORKSPACE->m_vRenderOffset.value().y != 0) { - const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y; - const auto WINBB = pWindow->getFullWindowBoundingBox(); - - if (WINBB.y < PWSMON->vecPosition.y) { - offset.y = (PWSMON->vecPosition.y - WINBB.y) * PROGRESS; - } else if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y) { - offset.y = (WINBB.y + WINBB.width - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS; - } - } - - renderdata.x += offset.x; - renderdata.y += offset.y; - } + renderdata.x += pWindow->m_vFloatingOffset.x; + renderdata.y += pWindow->m_vFloatingOffset.y; // if window is floating and we have a slide animation, clip it to its full bb if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bIsFullscreen && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) { - CRegion rg = pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value()).scale(pMonitor->scale); + CRegion rg = + pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale); g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents(); } - // if window is tiled and it's flying in, don't render on other mons (for slide) - if (!ignorePosition && !pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID) - return; - // render window decorations first, if not fullscreen full if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { @@ -569,14 +549,14 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_BOTTOM) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } for (auto& wd : pWindow->m_dWindowDecorations) { if (wd->getDecorationLayer() != DECORATION_LAYER_UNDER) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } @@ -601,7 +581,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_OVER) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } @@ -662,7 +642,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_OVERLAY) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } } @@ -861,7 +841,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* if (!w->m_bPinned || !w->m_bIsFloating) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; // render the bad boy @@ -1739,15 +1719,22 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1); } -void CHyprRenderer::damageWindow(CWindow* pWindow) { +void CHyprRenderer::damageWindow(CWindow* pWindow, bool forceFull) { if (g_pCompositor->m_bUnsafeState) return; - CBox damageBox = pWindow->getFullWindowBoundingBox(); + CBox windowBox = pWindow->getFullWindowBoundingBox(); + const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + windowBox.translate(pWindow->m_vFloatingOffset); + for (auto& m : g_pCompositor->m_vMonitors) { - CBox fixedDamageBox = {damageBox.x - m->vecPosition.x, damageBox.y - m->vecPosition.y, damageBox.width, damageBox.height}; - fixedDamageBox.scale(m->scale); - m->addDamage(&fixedDamageBox); + if (g_pHyprRenderer->shouldRenderWindow(pWindow, m.get()) || forceFull) { // only damage if window is rendered on monitor + CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height}; + fixedDamageBox.scale(m->scale); + m->addDamage(&fixedDamageBox); + } } for (auto& wd : pWindow->m_dWindowDecorations) @@ -1756,7 +1743,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) { static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); if (*PLOGDAMAGE) - Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, damageBox.x, damageBox.y, damageBox.width, damageBox.height); + Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, windowBox.x, windowBox.y, windowBox.width, windowBox.height); } void CHyprRenderer::damageMonitor(CMonitor* pMonitor) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 0a684af3..613706a5 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -46,14 +46,14 @@ class CHyprRenderer { void outputMgrApplyTest(wlr_output_configuration_v1*, bool); void arrangeLayersForMonitor(const int&); void damageSurface(wlr_surface*, double, double, double scale = 1.0); - void damageWindow(CWindow*); + void damageWindow(CWindow*, bool forceFull = false); void damageBox(CBox*); void damageBox(const int& x, const int& y, const int& w, const int& h); void damageRegion(const CRegion&); void damageMonitor(CMonitor*); void damageMirrorsWith(CMonitor*, const CRegion&); bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false); - bool shouldRenderWindow(CWindow*, CMonitor*, CWorkspace*); + bool shouldRenderWindow(CWindow*, CMonitor*); bool shouldRenderWindow(CWindow*); void ensureCursorRenderingMode(); bool shouldRenderCursor(); diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index ea40ee65..4981d2ea 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -45,14 +45,14 @@ CBox CHyprBorderDecoration::assignedBoxGlobal() { return box.translate(WORKSPACEOFFSET); } -void CHyprBorderDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) { +void CHyprBorderDecoration::draw(CMonitor* pMonitor, float a) { if (doesntWantBorders()) return; if (m_bAssignedGeometry.width < m_seExtents.topLeft.x + 1 || m_bAssignedGeometry.height < m_seExtents.topLeft.y + 1) return; - CBox windowBox = assignedBoxGlobal().translate(-pMonitor->vecPosition + offset).expand(-m_pWindow->getRealBorderSize()).scale(pMonitor->scale).round(); + CBox windowBox = assignedBoxGlobal().translate(-pMonitor->vecPosition + m_pWindow->m_vFloatingOffset).expand(-m_pWindow->getRealBorderSize()).scale(pMonitor->scale).round(); if (windowBox.width < 1 || windowBox.height < 1) return; @@ -87,7 +87,35 @@ void CHyprBorderDecoration::updateWindow(CWindow*) { } void CHyprBorderDecoration::damageEntire() { - ; // ignored, done in animationManager. todo, move. + if (!g_pCompositor->windowValidMapped(m_pWindow)) + return; + + auto surfaceBox = m_pWindow->getWindowMainSurfaceBox(); + const auto ROUNDING = m_pWindow->rounding(); + const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1; + const auto BORDERSIZE = m_pWindow->getRealBorderSize(); + + const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) + surfaceBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + surfaceBox.translate(m_pWindow->m_vFloatingOffset); + + CBox surfaceBoxExpandedBorder = surfaceBox; + surfaceBoxExpandedBorder.expand(BORDERSIZE); + CBox surfaceBoxShrunkRounding = surfaceBox; + surfaceBoxShrunkRounding.expand(-ROUNDINGSIZE); + + CRegion borderRegion(surfaceBoxExpandedBorder); + borderRegion.subtract(surfaceBoxShrunkRounding); + + for (auto& m : g_pCompositor->m_vMonitors) { + if (!g_pHyprRenderer->shouldRenderWindow(m_pWindow, m.get())) { + const CRegion monitorRegion({m->vecPosition, m->vecSize}); + borderRegion.subtract(monitorRegion); + } + } + + g_pHyprRenderer->damageRegion(borderRegion); } eDecorationLayer CHyprBorderDecoration::getDecorationLayer() { diff --git a/src/render/decorations/CHyprBorderDecoration.hpp b/src/render/decorations/CHyprBorderDecoration.hpp index 9c0bcc33..9b9df7ab 100644 --- a/src/render/decorations/CHyprBorderDecoration.hpp +++ b/src/render/decorations/CHyprBorderDecoration.hpp @@ -11,7 +11,7 @@ class CHyprBorderDecoration : public IHyprWindowDecoration { virtual void onPositioningReply(const SDecorationPositioningReply& reply); - virtual void draw(CMonitor*, float a, const Vector2D& offset); + virtual void draw(CMonitor*, float a); virtual eDecorationType getDecorationType(); diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 588b23a4..99d08828 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -41,9 +41,37 @@ void CHyprDropShadowDecoration::damageEntire() { if (*PSHADOWS != 1) return; // disabled - CBox dm = {m_vLastWindowPos.x - m_seExtents.topLeft.x, m_vLastWindowPos.y - m_seExtents.topLeft.y, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, - m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y}; - g_pHyprRenderer->damageBox(&dm); + CBox shadowBox = {m_pWindow->m_vRealPosition.value().x - m_seExtents.topLeft.x, m_pWindow->m_vRealPosition.value().y - m_seExtents.topLeft.y, + m_pWindow->m_vRealSize.value().x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, + m_pWindow->m_vRealSize.value().y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y}; + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) + shadowBox.translate(PWORKSPACE->m_vRenderOffset.value()); + shadowBox.translate(m_pWindow->m_vFloatingOffset); + + static auto PSHADOWIGNOREWINDOW = CConfigValue("decoration:shadow_ignore_window"); + const auto ROUNDING = m_pWindow->rounding(); + const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1; + + CRegion shadowRegion(shadowBox); + if (*PSHADOWIGNOREWINDOW) { + CBox surfaceBox = m_pWindow->getWindowMainSurfaceBox(); + if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) + surfaceBox.translate(PWORKSPACE->m_vRenderOffset.value()); + surfaceBox.translate(m_pWindow->m_vFloatingOffset); + surfaceBox.expand(-ROUNDINGSIZE); + shadowRegion.subtract(CRegion(surfaceBox)); + } + + for (auto& m : g_pCompositor->m_vMonitors) { + if (!g_pHyprRenderer->shouldRenderWindow(m_pWindow, m.get())) { + const CRegion monitorRegion({m->vecPosition, m->vecSize}); + shadowRegion.subtract(monitorRegion); + } + } + + g_pHyprRenderer->damageRegion(shadowRegion); } void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) { @@ -54,7 +82,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) { m_bLastWindowBoxWithDecos = g_pDecorationPositioner->getBoxWithIncludedDecos(pWindow); } -void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) { +void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) { if (!g_pCompositor->windowValidMapped(m_pWindow)) return; @@ -98,12 +126,13 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D // scale the box in relation to the center of the box fullBox.scaleFromCenter(SHADOWSCALE).translate(*PSHADOWOFFSET); + updateWindow(m_pWindow); m_vLastWindowPos += WORKSPACEOFFSET; m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2}, {fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2, fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}}; - fullBox.translate(offset); + fullBox.translate(m_pWindow->m_vFloatingOffset); if (fullBox.width < 1 || fullBox.height < 1) return; // don't draw invisible shadows @@ -125,6 +154,9 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D windowBox.translate(-pMonitor->vecPosition + WORKSPACEOFFSET); withDecos.translate(-pMonitor->vecPosition + WORKSPACEOFFSET); + windowBox.translate(m_pWindow->m_vFloatingOffset); + withDecos.translate(m_pWindow->m_vFloatingOffset); + auto scaledExtentss = withDecos.extentsFrom(windowBox); scaledExtentss = scaledExtentss * pMonitor->scale; scaledExtentss = scaledExtentss.round(); diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 3b389550..fcc5f873 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -11,7 +11,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { virtual void onPositioningReply(const SDecorationPositioningReply& reply); - virtual void draw(CMonitor*, float a, const Vector2D& offset); + virtual void draw(CMonitor*, float a); virtual eDecorationType getDecorationType(); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index a03d97f9..ce683ac1 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -83,10 +83,11 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) { void CHyprGroupBarDecoration::damageEntire() { auto box = assignedBoxGlobal(); + box.translate(m_pWindow->m_vFloatingOffset); g_pHyprRenderer->damageBox(&box); } -void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) { +void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) { // get how many bars we will draw int barsToDraw = m_dwGroupMembers.size(); @@ -110,8 +111,9 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& int xoff = 0; for (int i = 0; i < barsToDraw; ++i) { - CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x, - ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + offset.y, m_fBarWidth, BAR_INDICATOR_HEIGHT}; + CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, + ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth, + BAR_INDICATOR_HEIGHT}; if (rect.width <= 0 || rect.height <= 0) break; @@ -135,7 +137,8 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& color.a *= a; g_pHyprOpenGL->renderRect(&rect, color); - rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x, ASSIGNEDBOX.y - pMonitor->vecPosition.y + offset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth, + rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, + ASSIGNEDBOX.y - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth, ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT * 2}; rect.scale(pMonitor->scale); @@ -505,9 +508,8 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); - if (!PWORKSPACE) - return box; + if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) + box.translate(PWORKSPACE->m_vRenderOffset.value()); - const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D(); - return box.translate(WORKSPACEOFFSET); + return box; } diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index 04f5123b..24635f6e 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -27,7 +27,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { virtual void onPositioningReply(const SDecorationPositioningReply& reply); - virtual void draw(CMonitor*, float a, const Vector2D& offset); + virtual void draw(CMonitor*, float a); virtual eDecorationType getDecorationType(); diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index d3d1a5dd..10426439 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -39,7 +39,7 @@ class IHyprWindowDecoration { virtual void onPositioningReply(const SDecorationPositioningReply& reply) = 0; - virtual void draw(CMonitor*, float a, const Vector2D& offset = Vector2D()) = 0; + virtual void draw(CMonitor*, float a) = 0; virtual eDecorationType getDecorationType() = 0; From e1e41e54480282d9bec9957d3c578eb87bc1f2f2 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sun, 31 Mar 2024 06:59:22 -0700 Subject: [PATCH 0093/2772] reenderer: Add 1 border damage to fix number rounding issues (#5343) * add 1 to border damage to avoid rounding issues * add 1 to rounding too --- src/render/decorations/CHyprBorderDecoration.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 4981d2ea..76e60348 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -92,8 +92,8 @@ void CHyprBorderDecoration::damageEntire() { auto surfaceBox = m_pWindow->getWindowMainSurfaceBox(); const auto ROUNDING = m_pWindow->rounding(); - const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1; - const auto BORDERSIZE = m_pWindow->getRealBorderSize(); + const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 2; + const auto BORDERSIZE = m_pWindow->getRealBorderSize() + 1; const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) From 4156b55cf91a7cb90fd14582a1c5a9df5792933e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 31 Mar 2024 21:30:30 +0100 Subject: [PATCH 0094/2772] textinput: send deactivate on disable ti ref #5288 --- src/managers/input/TextInput.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index eeea899d..6b6f38c8 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -96,6 +96,9 @@ void CTextInput::onDisabled() { hyprListener_surfaceDestroyed.removeCallback(); hyprListener_surfaceUnmapped.removeCallback(); + if (!g_pInputManager->m_sIMERelay.m_pWLRIME->active) + return; + wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); g_pInputManager->m_sIMERelay.commitIMEState(this); } @@ -204,6 +207,12 @@ void CTextInput::leave() { } setFocusedSurface(nullptr); + + if (!g_pInputManager->m_sIMERelay.m_pWLRIME->active) + return; + + wlr_input_method_v2_send_deactivate(g_pInputManager->m_sIMERelay.m_pWLRIME); + g_pInputManager->m_sIMERelay.commitIMEState(this); } wlr_surface* CTextInput::focusedSurface() { From 64c8ba2fb1977a055b9718c7c7cfb1740756d963 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 31 Mar 2024 21:34:11 +0100 Subject: [PATCH 0095/2772] avar: fix warp onEnd conditions ref #5348 --- src/helpers/AnimatedVariable.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 82e30892..2add41be 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -279,7 +279,7 @@ class CAnimatedVariable : public CBaseAnimatedVariable { } void warp(bool endCallback = true) override { - if (m_Value == m_Goal) + if (!m_bIsBeingAnimated) return; m_Value = m_Goal; @@ -289,8 +289,7 @@ class CAnimatedVariable : public CBaseAnimatedVariable { if (m_fUpdateCallback) m_fUpdateCallback(this); - if (endCallback) - onAnimationEnd(); + onAnimationEnd(); } private: From 9e8f0518961041b60e6c4843f545734e833d5355 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 31 Mar 2024 21:43:08 +0100 Subject: [PATCH 0096/2772] avar: minor fixes --- src/helpers/AnimatedVariable.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 2add41be..85ffb9ab 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -274,7 +274,8 @@ class CAnimatedVariable : public CBaseAnimatedVariable { // Sets the actual value and goal void setValueAndWarp(const VarType& v) { - m_Goal = v; + m_Goal = v; + m_bIsBeingAnimated = true; warp(); } @@ -289,7 +290,8 @@ class CAnimatedVariable : public CBaseAnimatedVariable { if (m_fUpdateCallback) m_fUpdateCallback(this); - onAnimationEnd(); + if (endCallback) + onAnimationEnd(); } private: From 8cb38d41d203f95ea9c2be79996a5f0deda3eabf Mon Sep 17 00:00:00 2001 From: Micovec <30734146+Micovec@users.noreply.github.com> Date: Sun, 31 Mar 2024 22:45:22 +0200 Subject: [PATCH 0097/2772] hyprctl: fix plugin list on no plugins (#5357) --- src/debug/HyprCtl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 903b7d7f..f61f5544 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1449,7 +1449,10 @@ std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) { g_pPluginSystem->unloadPlugin(PLUGIN); } else if (OPERATION == "list") { - const auto PLUGINS = g_pPluginSystem->getAllPlugins(); + const auto PLUGINS = g_pPluginSystem->getAllPlugins(); + + if (PLUGINS.size() == 0) + return "no plugins loaded"; std::string list = ""; for (auto& p : PLUGINS) { From ecc1f22e050e6542948fd022694d1d7f8716a560 Mon Sep 17 00:00:00 2001 From: Sungyoon Cho Date: Mon, 1 Apr 2024 08:41:00 +0900 Subject: [PATCH 0098/2772] textinput: fix typo (#5365) --- src/managers/input/TextInput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp index 6b6f38c8..8be13a4c 100644 --- a/src/managers/input/TextInput.cpp +++ b/src/managers/input/TextInput.cpp @@ -194,7 +194,7 @@ void CTextInput::leave() { return; enterLocks--; - if (enterLocks != 1) { + if (enterLocks != 0) { Debug::log(ERR, "BUG THIS: TextInput has != 0 locks in leave"); enterLocks = 0; } From 9ae0c47a21476d064ab93b6fb87cedbf20096b8e Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sun, 31 Mar 2024 18:58:21 -0700 Subject: [PATCH 0099/2772] deco: fix groupbar offset (#5364) --- src/render/decorations/CHyprGroupBarDecoration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index ce683ac1..50bf4627 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -508,7 +508,7 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); - if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) + if (PWORKSPACE && !m_pWindow->m_bPinned) box.translate(PWORKSPACE->m_vRenderOffset.value()); return box; From ef7ac53e99c9c443241fd50a38e6edf528df3d7b Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Sun, 31 Mar 2024 19:02:47 -0700 Subject: [PATCH 0100/2772] master: Make master workspace orientation rule dynamic (#5339) * make master workspace orientation rule dynamic * fix rebase * fix special ws resizing * style --- src/layout/MasterLayout.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 9c49197e..cac64c6d 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -53,17 +53,16 @@ SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) { orientationForWs = wsRule.layoutopts.at("orientation"); } - if (orientationForWs == "top") { + if (orientationForWs == "top") PWORKSPACEDATA->orientation = ORIENTATION_TOP; - } else if (orientationForWs == "right") { + else if (orientationForWs == "right") PWORKSPACEDATA->orientation = ORIENTATION_RIGHT; - } else if (orientationForWs == "bottom") { + else if (orientationForWs == "bottom") PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM; - } else if (orientationForWs == "center") { + else if (orientationForWs == "center") PWORKSPACEDATA->orientation = ORIENTATION_CENTER; - } else { + else PWORKSPACEDATA->orientation = ORIENTATION_LEFT; - } return PWORKSPACEDATA; } @@ -339,6 +338,26 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { if (!PMASTERNODE) return; + // dynamic workspace rules + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(ws)); + std::string orientationForWs; + + for (auto& wsRule : WORKSPACERULES) { + if (wsRule.layoutopts.contains("orientation")) + orientationForWs = wsRule.layoutopts.at("orientation"); + } + + if (orientationForWs == "top") + PWORKSPACEDATA->orientation = ORIENTATION_TOP; + else if (orientationForWs == "right") + PWORKSPACEDATA->orientation = ORIENTATION_RIGHT; + else if (orientationForWs == "bottom") + PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM; + else if (orientationForWs == "center") + PWORKSPACEDATA->orientation = ORIENTATION_CENTER; + else if (orientationForWs == "left") + PWORKSPACEDATA->orientation = ORIENTATION_LEFT; + eOrientation orientation = PWORKSPACEDATA->orientation; bool centerMasterWindow = false; static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); @@ -753,7 +772,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne } const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); - const auto PWORKSPACEDATA = getMasterWorkspaceData(PMONITOR->activeWorkspace); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); From 416b3d6167a996c7e94bd537cec20a12a0784efa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 1 Apr 2024 03:54:05 +0100 Subject: [PATCH 0101/2772] socket2: sanitize data for newlines --- src/managers/EventManager.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp index 8365c8c8..57824430 100644 --- a/src/managers/EventManager.cpp +++ b/src/managers/EventManager.cpp @@ -15,6 +15,7 @@ #include #include +#include CEventManager::CEventManager() {} @@ -139,7 +140,9 @@ void CEventManager::postEvent(const SHyprIPCEvent event) { } std::thread( - [&](const SHyprIPCEvent ev) { + [this](SHyprIPCEvent ev) { + std::replace(ev.data.begin(), ev.data.end(), '\n', ' '); + eventQueueMutex.lock(); m_dQueuedEvents.push_back(ev); eventQueueMutex.unlock(); From 800dbf71b0db04bf43ff5a87a9cff6e48de325a2 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:16:18 -0700 Subject: [PATCH 0102/2772] renderer: Fix rendering when swiping workspaces (#5367) * fix rendering on swiping * add alpha check * fix floating fs check --- src/render/Renderer.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 18110256..aecd9524 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -225,13 +225,16 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_iMonitorID == pMonitor->ID) { - if (PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) { + if (PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) return true; - } else { - if (PWINDOWWORKSPACE->m_bHasFullscreenWindow && !pWindow->m_bIsFullscreen && !pWindow->m_bIsFloating && !pWindow->m_bCreatedOverFullscreen && - pWindow->m_fAlpha.value() == 0) - return false; - } + + // if hidden behind fullscreen + if (PWINDOWWORKSPACE->m_bHasFullscreenWindow && !pWindow->m_bIsFullscreen && (!pWindow->m_bIsFloating || !pWindow->m_bCreatedOverFullscreen) && + pWindow->m_fAlpha.value() == 0) + return false; + + if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID)) + return false; } if (pWindow->m_iMonitorID == pMonitor->ID) From 7513c0cea59f4e1f5336dc31ebfabd8362e02d69 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:21:45 -0700 Subject: [PATCH 0103/2772] renderer: Fix layer and window damage sometimes missing 1 frame (#5370) * fix the layer and window damage missing 1 frame sometimes * remove extra loop --- src/managers/AnimationManager.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index fc768b77..6cc89cde 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -85,7 +85,6 @@ void CAnimationManager::tick() { CMonitor* PMONITOR = nullptr; bool animationsDisabled = animGlobalDisabled; - CBox WLRBOXPREV = {0, 0, 0, 0}; if (PWINDOW) { if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) { g_pHyprRenderer->damageWindow(PWINDOW); @@ -136,8 +135,12 @@ void CAnimationManager::tick() { g_pHyprRenderer->damageWindow(w.get()); } } else if (PLAYER) { - WLRBOXPREV = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; - PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f); + // "some fucking layers miss 1 pixel???" -- vaxry + CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; + expandBox.expand(5); + g_pHyprRenderer->damageBox(&expandBox); + + PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f); if (!PMONITOR) continue; animationsDisabled = animationsDisabled || PLAYER->noAnimations; @@ -204,8 +207,6 @@ void CAnimationManager::tick() { switch (av->m_eDamagePolicy) { case AVARDAMAGE_ENTIRE: { - g_pHyprRenderer->damageBox(&WLRBOXPREV); - if (PWINDOW) { PWINDOW->updateWindowDecos(); g_pHyprRenderer->damageWindow(PWINDOW); @@ -215,13 +216,17 @@ void CAnimationManager::tick() { continue; w->updateWindowDecos(); + + // damage any workspace window that is on any monitor + if (!w->m_bPinned) + g_pHyprRenderer->damageWindow(w.get()); } } else if (PLAYER) { if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // some fucking layers miss 1 pixel??? - CBox expandBox = WLRBOXPREV; + CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; expandBox.expand(5); g_pHyprRenderer->damageBox(&expandBox); } From 108163f1e5e0e1423a170e78688a826963ec7a81 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 1 Apr 2024 16:22:21 +0100 Subject: [PATCH 0104/2772] animations: simplify window loop --- src/managers/AnimationManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 6cc89cde..ab81841c 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -111,7 +111,7 @@ void CAnimationManager::tick() { // TODO: just make this into a damn callback already vax... for (auto& w : g_pCompositor->m_vWindows) { - if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID) + if (!w->m_bIsMapped || w->isHidden() || w->m_iWorkspaceID != PWORKSPACE->m_iID) continue; if (w->m_bIsFloating && !w->m_bPinned) { From db1506130b507f92e0daf3a36495fb985e242bbc Mon Sep 17 00:00:00 2001 From: Sungyoon Cho Date: Tue, 2 Apr 2024 00:37:59 +0900 Subject: [PATCH 0105/2772] IME: Fix ime popup coordinates and artifacts (#5373) * ime: fix incorrect popup coordinate * ime: fix popup artifacts --- src/managers/input/InputMethodPopup.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index 326b982e..3332e9c3 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -77,10 +77,8 @@ void CInputPopup::damageEntire() { return; } - Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos(); - CBox global = lastBoxLocal.copy().translate(pos); - - g_pHyprRenderer->damageBox(&global); + Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos() + lastBoxLocal.pos(); + g_pHyprRenderer->damageBox(pos.x, pos.y, surface.wlr()->current.width, surface.wlr()->current.height); } void CInputPopup::damageSurface() { @@ -127,7 +125,9 @@ void CInputPopup::updateBox() { CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle()); if (cursorBoxLocal.y + parentBox.y + surface.wlr()->current.height + cursorBoxLocal.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) - cursorBoxLocal.y -= surface.wlr()->current.height + cursorBoxLocal.height; + cursorBoxLocal.y -= surface.wlr()->current.height; + else + cursorBoxLocal.y += cursorBoxLocal.height; if (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) cursorBoxLocal.x -= (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); From 3875679755014997776e091ff8903acfb311dd2f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 1 Apr 2024 19:30:37 +0100 Subject: [PATCH 0106/2772] props: bump ver to 0.38.0 --- props.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/props.json b/props.json index 81f6a4cb..dba78901 100644 --- a/props.json +++ b/props.json @@ -1,3 +1,3 @@ { - "version": "0.37.1" + "version": "0.38.0" } \ No newline at end of file From c377caee7abcd093fd09c386b20c32f291e86747 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Mon, 1 Apr 2024 20:18:18 +0000 Subject: [PATCH 0107/2772] hyprerror: align 32-bit types after 4c796683c05a (#5375) src/hyprerror/HyprError.cpp:64:33: error: no matching function for call to 'min' const auto VISLINECOUNT = std::min(LINECOUNT, *LINELIMIT); ^~~~~~~~ /usr/include/c++/v1/__algorithm/min.h:40:1: note: candidate template ignored: deduced conflicting types for parameter '_Tp' ('int' vs. 'long long') min(const _Tp& __a, const _Tp& __b) ^ /usr/include/c++/v1/__algorithm/min.h:51:1: note: candidate template ignored: could not match 'initializer_list<_Tp>' against 'int' min(initializer_list<_Tp> __t, _Compare __comp) ^ /usr/include/c++/v1/__algorithm/min.h:60:1: note: candidate function template not viable: requires single argument '__t', but 2 arguments were provided min(initializer_list<_Tp> __t) ^ /usr/include/c++/v1/__algorithm/min.h:31:1: note: candidate function template not viable: requires 3 arguments, but 2 were provided min(const _Tp& __a, const _Tp& __b, _Compare __comp) ^ --- src/hyprerror/HyprError.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 73f9c5d5..de386097 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -58,7 +58,7 @@ void CHyprError::createQueued() { cairo_paint(CAIRO); cairo_restore(CAIRO); - const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n'); + const auto LINECOUNT = Hyprlang::INT{1} + std::count(m_szQueued.begin(), m_szQueued.end(), '\n'); static auto LINELIMIT = CConfigValue("debug:error_limit"); const auto VISLINECOUNT = std::min(LINECOUNT, *LINELIMIT); From af3a61a4e437fe728ef69c2739cae79e5a6254c0 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 2 Apr 2024 01:15:58 +0100 Subject: [PATCH 0108/2772] core: assert attempted UAFs in windowExists in prep of removing the thing altogether --- src/Compositor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3ac9a73f..5fefb2b8 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -704,6 +704,11 @@ bool CCompositor::windowExists(CWindow* pWindow) { return true; } + // FIXME: this is here only temporarily, + // remove this func altogether if no reports + // of this being hit. + RASSERT(!pWindow, "windowExists: attempted UAF"); + return false; } @@ -1388,7 +1393,7 @@ bool CCompositor::isWindowActive(CWindow* pWindow) { if (!m_pLastWindow && !m_pLastFocus) return false; - if (!windowValidMapped(pWindow)) + if (!pWindow->m_bIsMapped) return false; const auto PSURFACE = pWindow->m_pWLSurface.wlr(); From 2e5b146e57364795aabeb2dea6fd2257db8b2c3a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 2 Apr 2024 12:10:03 +0100 Subject: [PATCH 0109/2772] workspace: remove lastFocusedWindow on unmap --- src/desktop/Workspace.cpp | 9 +++++++++ src/desktop/Workspace.hpp | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index a0c14bba..9200b4d7 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -30,6 +30,13 @@ CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { m_szName = rule.defaultName.value(); } + m_pFocusedWindowHook = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any param) { + const auto PWINDOW = std::any_cast(param); + + if (PWINDOW == m_pLastFocusedWindow) + m_pLastFocusedWindow = nullptr; + }); + g_pEventManager->postEvent({"createworkspace", m_szName}); g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)}); EMIT_HOOK_EVENT("createWorkspace", this); @@ -40,6 +47,8 @@ CWorkspace::~CWorkspace() { Debug::log(LOG, "Destroying workspace ID {}", m_iID); + g_pHookSystem->unhook(m_pFocusedWindowHook); + g_pEventManager->postEvent({"destroyworkspace", m_szName}); g_pEventManager->postEvent({"destroyworkspacev2", std::format("{},{}", m_iID, m_szName)}); EMIT_HOOK_EVENT("destroyWorkspace", this); diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index f1bdb333..0cae1859 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -66,4 +66,7 @@ class CWorkspace { std::string getConfigName(); bool matchesStaticSelector(const std::string& selector); + + private: + HOOK_CALLBACK_FN* m_pFocusedWindowHook = nullptr; }; From 04a35891a1cef8d1b5aad4229186611fcf096f1b Mon Sep 17 00:00:00 2001 From: Sungyoon Cho Date: Tue, 2 Apr 2024 20:22:41 +0900 Subject: [PATCH 0110/2772] IME: fix incorrect popup damage (#5383) --- src/managers/input/InputMethodPopup.cpp | 21 +++++++++++++-------- src/managers/input/InputMethodPopup.hpp | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index 3332e9c3..36f25dd7 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -77,8 +77,10 @@ void CInputPopup::damageEntire() { return; } - Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos() + lastBoxLocal.pos(); - g_pHyprRenderer->damageBox(pos.x, pos.y, surface.wlr()->current.width, surface.wlr()->current.height); + Vector2D pos = OWNER->getSurfaceBoxGlobal().value_or(CBox{0, 0, 0, 0}).pos() + lastBoxLocal.pos(); + CBox global = {pos, lastPopupSize}; + + g_pHyprRenderer->damageBox(&global); } void CInputPopup::damageSurface() { @@ -119,20 +121,23 @@ void CInputPopup::updateBox() { cursorBoxLocal = {0, 0, (int)parentBox.w, (int)parentBox.h}; } - if (cursorBoxLocal != lastBoxLocal) + Vector2D currentPopupSize = {surface.wlr()->current.width, surface.wlr()->current.height}; + + if (cursorBoxLocal != lastBoxLocal || currentPopupSize != lastPopupSize) damageEntire(); CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle()); - if (cursorBoxLocal.y + parentBox.y + surface.wlr()->current.height + cursorBoxLocal.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) - cursorBoxLocal.y -= surface.wlr()->current.height; + if (cursorBoxLocal.y + parentBox.y + currentPopupSize.y + cursorBoxLocal.height > pMonitor->vecPosition.y + pMonitor->vecSize.y) + cursorBoxLocal.y -= currentPopupSize.y; else cursorBoxLocal.y += cursorBoxLocal.height; - if (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width > pMonitor->vecPosition.x + pMonitor->vecSize.x) - cursorBoxLocal.x -= (cursorBoxLocal.x + parentBox.x + surface.wlr()->current.width) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); + if (cursorBoxLocal.x + parentBox.x + currentPopupSize.x > pMonitor->vecPosition.x + pMonitor->vecSize.x) + cursorBoxLocal.x -= (cursorBoxLocal.x + parentBox.x + currentPopupSize.x) - (pMonitor->vecPosition.x + pMonitor->vecSize.x); - lastBoxLocal = cursorBoxLocal; + lastBoxLocal = cursorBoxLocal; + lastPopupSize = currentPopupSize; wlr_input_popup_surface_v2_send_text_input_rectangle(pWlr, cursorBoxLocal.pWlr()); diff --git a/src/managers/input/InputMethodPopup.hpp b/src/managers/input/InputMethodPopup.hpp index 8bcf1101..71b2fe64 100644 --- a/src/managers/input/InputMethodPopup.hpp +++ b/src/managers/input/InputMethodPopup.hpp @@ -32,6 +32,7 @@ class CInputPopup { wlr_input_popup_surface_v2* pWlr = nullptr; CWLSurface surface; CBox lastBoxLocal; + Vector2D lastPopupSize; uint64_t lastMonitor = -1; DYNLISTENER(mapPopup); From 05eb2d4af212f279cc3c25ae9c654bce627db05c Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 2 Apr 2024 12:46:05 +0100 Subject: [PATCH 0111/2772] master: guard window in moveWindowTo fixes #5374 --- src/layout/MasterLayout.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index cac64c6d..375840fb 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -1005,6 +1005,9 @@ void CHyprMasterLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) { const auto PWINDOW2 = g_pCompositor->getWindowInDirection(pWindow, dir[0]); + if (!PWINDOW2) + return; + pWindow->setAnimationsToMove(); if (pWindow->m_iWorkspaceID != PWINDOW2->m_iWorkspaceID) { From fc0a7af7ba5c52f7a70309020f5cb27c19d068e6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 2 Apr 2024 16:10:55 +0100 Subject: [PATCH 0112/2772] IME: fix blurry ime on scaled ref #5387 --- src/managers/input/InputMethodPopup.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index 36f25dd7..bc2876ad 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -57,6 +57,13 @@ void CInputPopup::onMap() { updateBox(); damageEntire(); + + const auto PMONITOR = g_pCompositor->getMonitorFromVector(globalBox().middle()); + + if (!PMONITOR) + return; + + g_pProtocolManager->m_pFractionalScaleProtocolManager->setPreferredScaleForSurface(surface.wlr(), PMONITOR->scale); } void CInputPopup::onUnmap() { @@ -121,7 +128,7 @@ void CInputPopup::updateBox() { cursorBoxLocal = {0, 0, (int)parentBox.w, (int)parentBox.h}; } - Vector2D currentPopupSize = {surface.wlr()->current.width, surface.wlr()->current.height}; + Vector2D currentPopupSize = surface.getViewporterCorrectedSize(); if (cursorBoxLocal != lastBoxLocal || currentPopupSize != lastPopupSize) damageEntire(); From ef23ef60c5641c5903f9cf40571ead7ad6aba1b9 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:32:39 +0100 Subject: [PATCH 0113/2772] Workspace/core: Refactor workspace storage (#5380) * refactor workspaces to use ptrs * clang-format --- src/Compositor.cpp | 173 +++++++++--------- src/Compositor.hpp | 16 +- src/config/ConfigManager.cpp | 8 +- src/config/ConfigManager.hpp | 2 +- src/debug/HyprCtl.cpp | 83 ++++----- src/desktop/DesktopTypes.hpp | 6 + src/desktop/Window.cpp | 64 ++++--- src/desktop/Window.hpp | 42 +++-- src/desktop/Workspace.cpp | 36 +++- src/desktop/Workspace.hpp | 25 ++- src/events/Layers.cpp | 4 +- src/events/Windows.cpp | 30 +-- src/helpers/AnimatedVariable.cpp | 2 +- src/helpers/AnimatedVariable.hpp | 13 +- src/helpers/MiscFunctions.cpp | 20 +- src/helpers/Monitor.cpp | 80 ++++---- src/helpers/Monitor.hpp | 18 +- src/helpers/WLClasses.hpp | 14 +- src/layout/DwindleLayout.cpp | 53 +++--- src/layout/DwindleLayout.hpp | 2 +- src/layout/IHyprLayout.cpp | 22 +-- src/layout/MasterLayout.cpp | 116 ++++++------ src/layout/MasterLayout.hpp | 2 +- src/managers/AnimationManager.cpp | 18 +- src/managers/KeybindManager.cpp | 62 +++---- src/managers/XWaylandManager.cpp | 2 +- src/managers/input/IdleInhibitor.cpp | 2 +- src/managers/input/InputManager.cpp | 8 +- src/managers/input/Swipe.cpp | 14 +- src/managers/input/Touch.cpp | 2 +- src/render/OpenGL.cpp | 8 +- src/render/OpenGL.hpp | 2 +- src/render/Renderer.cpp | 80 ++++---- src/render/Renderer.hpp | 12 +- .../decorations/CHyprBorderDecoration.cpp | 4 +- .../decorations/CHyprDropShadowDecoration.cpp | 4 +- .../decorations/CHyprGroupBarDecoration.cpp | 4 +- 37 files changed, 544 insertions(+), 509 deletions(-) create mode 100644 src/desktop/DesktopTypes.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 5fefb2b8..001d7ca8 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -751,20 +751,20 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert auto floating = [&](bool aboveFullscreen) -> CWindow* { for (auto& w : m_vWindows | std::views::reverse) { - if (special && !isWorkspaceSpecial(w->m_iWorkspaceID)) // because special floating may creep up into regular + if (special && !w->onSpecialWorkspace()) // because special floating may creep up into regular continue; const auto BB = w->getWindowBoxUnified(properties); const auto PWINDOWMONITOR = getMonitorFromID(w->m_iMonitorID); // to avoid focusing windows behind special workspaces from other monitors - if (!*PSPECIALFALLTHRU && PWINDOWMONITOR && PWINDOWMONITOR->specialWorkspaceID && w->m_iWorkspaceID != PWINDOWMONITOR->specialWorkspaceID && + if (!*PSPECIALFALLTHRU && PWINDOWMONITOR && PWINDOWMONITOR->activeSpecialWorkspace && w->m_pWorkspace != PWINDOWMONITOR->activeSpecialWorkspace && BB.x >= PWINDOWMONITOR->vecPosition.x && BB.y >= PWINDOWMONITOR->vecPosition.y && BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x && BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y) continue; CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->workspaceID()) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) { // OR windows should add focus to parent if (w->m_bX11ShouldntFocus && w->m_iX11Type != 2) @@ -801,7 +801,7 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert if (properties & FLOATING_ONLY) return floating(false); - const int64_t WORKSPACEID = special ? PMONITOR->specialWorkspaceID : PMONITOR->activeWorkspace; + const int64_t WORKSPACEID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); const auto PWORKSPACE = getWorkspaceByID(WORKSPACEID); if (PWORKSPACE->m_bHasFullscreenWindow) @@ -813,10 +813,10 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert // for windows, we need to check their extensions too, first. for (auto& w : m_vWindows) { - if (special != isWorkspaceSpecial(w->m_iWorkspaceID)) + if (special != w->onSpecialWorkspace()) continue; - if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) { if (w->hasPopupAt(pos)) return w.get(); @@ -824,11 +824,11 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert } for (auto& w : m_vWindows) { - if (special != isWorkspaceSpecial(w->m_iWorkspaceID)) + if (special != w->onSpecialWorkspace()) 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->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) return w.get(); } @@ -837,10 +837,10 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert }; // special workspace - if (PMONITOR->specialWorkspaceID && !*PSPECIALFALLTHRU) + if (PMONITOR->activeSpecialWorkspace && !*PSPECIALFALLTHRU) return windowForWorkspace(true); - if (PMONITOR->specialWorkspaceID) { + if (PMONITOR->activeSpecialWorkspace) { const auto PWINDOW = windowForWorkspace(true); if (PWINDOW) @@ -997,15 +997,15 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { return; if (pWindow->m_bPinned) - pWindow->m_iWorkspaceID = m_pLastMonitor->activeWorkspace; + pWindow->m_pWorkspace = m_pLastMonitor->activeWorkspace; const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); - if (!isWorkspaceVisible(pWindow->m_iWorkspaceID)) { - const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID); + if (!isWorkspaceVisible(pWindow->workspaceID())) { + const auto PWORKSPACE = pWindow->m_pWorkspace; // This is to fix incorrect feedback on the focus history. PWORKSPACE->m_pLastFocusedWindow = pWindow; - PWORKSPACE->rememberPrevWorkspace(getWorkspaceByID(m_pLastMonitor->activeWorkspace)); + PWORKSPACE->rememberPrevWorkspace(m_pLastMonitor->activeWorkspace); PMONITOR->changeWorkspace(PWORKSPACE, false, true); // changeworkspace already calls focusWindow return; @@ -1016,7 +1016,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { /* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which window focuses are "via keybinds" and which ones aren't. */ - if (PMONITOR->specialWorkspaceID && PMONITOR->specialWorkspaceID != pWindow->m_iWorkspaceID && !pWindow->m_bPinned && !*PSPECIALFALLTHROUGH) + if (PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace != pWindow->m_pWorkspace && !pWindow->m_bPinned && !*PSPECIALFALLTHROUGH) PMONITOR->setSpecialWorkspace(nullptr); // we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window @@ -1233,7 +1233,7 @@ CWindow* CCompositor::getWindowFromZWLRHandle(wl_resource* handle) { CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == ID && w->m_bIsFullscreen) + if (w->workspaceID() == ID && w->m_bIsFullscreen) return w.get(); } @@ -1242,20 +1242,20 @@ CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { bool CCompositor::isWorkspaceVisible(const int& w) { for (auto& m : m_vMonitors) { - if (m->activeWorkspace == w) + if (m->activeWorkspaceID() == w) return true; - if (m->specialWorkspaceID == w) + if (m->activeSpecialWorkspaceID() == w) return true; } return false; } -CWorkspace* CCompositor::getWorkspaceByID(const int& id) { +PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { for (auto& w : m_vWorkspaces) { - if (w->m_iID == id) - return w.get(); + if (w->m_iID == id && !w->inert()) + return w; } return nullptr; @@ -1265,7 +1265,7 @@ void CCompositor::sanityCheckWorkspaces() { auto it = m_vWorkspaces.begin(); while (it != m_vWorkspaces.end()) { - const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(it->get()); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(*it); bool isPersistent = false; for (auto& wsRule : WORKSPACERULES) { if (wsRule.isPersistent) @@ -1290,10 +1290,11 @@ void CCompositor::sanityCheckWorkspaces() { const auto PMONITOR = getMonitorFromID(WORKSPACE->m_iMonitorID); - if (PMONITOR && PMONITOR->specialWorkspaceID == WORKSPACE->m_iID) + if (PMONITOR && PMONITOR->activeSpecialWorkspace == WORKSPACE) PMONITOR->setSpecialWorkspace(nullptr); } + it->get()->markInert(); it = m_vWorkspaces.erase(it); continue; } @@ -1314,7 +1315,7 @@ void CCompositor::sanityCheckWorkspaces() { int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTiled) { int no = 0; for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == id && w->m_bIsMapped && !(onlyTiled.has_value() && !w->m_bIsFloating != onlyTiled.value())) + if (w->workspaceID() == id && w->m_bIsMapped && !(onlyTiled.has_value() && !w->m_bIsFloating != onlyTiled.value())) no++; } @@ -1332,7 +1333,7 @@ CWindow* CCompositor::getUrgentWindow() { bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == id && w->m_bIsMapped && w->m_bIsUrgent) + if (w->workspaceID() == id && w->m_bIsMapped && w->m_bIsUrgent) return true; } @@ -1341,7 +1342,7 @@ bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) { for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == id && w->m_bIsMapped && !w->isHidden()) + if (w->workspaceID() == id && w->m_bIsMapped && !w->isHidden()) return w.get(); } @@ -1357,7 +1358,7 @@ CWindow* CCompositor::getTopLeftWindowOnWorkspace(const int& id) { const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID); for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID != id || !w->m_bIsMapped || w->isHidden()) + if (w->workspaceID() != id || !w->m_bIsMapped || w->isHidden()) continue; const auto WINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved(); @@ -1575,7 +1576,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { const auto POSA = Vector2D(WINDOWIDEALBB.x, WINDOWIDEALBB.y); const auto SIZEA = Vector2D(WINDOWIDEALBB.width, WINDOWIDEALBB.height); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; auto leaderValue = -1; CWindow* leaderWindow = nullptr; @@ -1583,10 +1584,10 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { // for tiled windows, we calc edges for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->m_iWorkspaceID)) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) continue; - if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_iWorkspaceID != w->m_iWorkspaceID) + if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) continue; if (PWORKSPACE->m_bHasFullscreenWindow && !w->m_bIsFullscreen && !w->m_bCreatedOverFullscreen) @@ -1672,10 +1673,10 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { constexpr float THRESHOLD = 0.3 * M_PI; for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->m_iWorkspaceID)) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) continue; - if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_iWorkspaceID != w->m_iWorkspaceID) + if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) continue; if (PWORKSPACE->m_bHasFullscreenWindow && !w->m_bIsFullscreen && !w->m_bCreatedOverFullscreen) @@ -1718,7 +1719,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) + if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1726,7 +1727,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) + if (w.get() != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1747,7 +1748,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) + if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1755,7 +1756,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) + if (w.get() != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1772,16 +1773,16 @@ int CCompositor::getNextAvailableNamedWorkspace() { return lowest - 1; } -CWorkspace* CCompositor::getWorkspaceByName(const std::string& name) { +PHLWORKSPACE CCompositor::getWorkspaceByName(const std::string& name) { for (auto& w : m_vWorkspaces) { - if (w->m_szName == name) - return w.get(); + if (w->m_szName == name && !w->inert()) + return w; } return nullptr; } -CWorkspace* CCompositor::getWorkspaceByString(const std::string& str) { +PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) { if (str.starts_with("name:")) { return getWorkspaceByName(str.substr(str.find_first_of(':') + 1)); } @@ -1896,7 +1897,7 @@ void CCompositor::updateAllWindowsAnimatedDecorationValues() { void CCompositor::updateWorkspaceWindows(const int64_t& id) { for (auto& w : m_vWindows) { - if (!w->m_bIsMapped || w->m_iWorkspaceID != id) + if (!w->m_bIsMapped || w->workspaceID() != id) continue; w->updateDynamicRules(); @@ -1964,7 +1965,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) { pWindow->m_fBorderAngleAnimationProgress.setValueAndWarp(0.f); // opacity - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; if (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) { pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA; } else { @@ -2020,16 +2021,16 @@ int CCompositor::getNextAvailableMonitorID(std::string const& name) { void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) { - const auto PWORKSPACEA = g_pCompositor->getWorkspaceByID(pMonitorA->activeWorkspace); - const auto PWORKSPACEB = g_pCompositor->getWorkspaceByID(pMonitorB->activeWorkspace); + const auto PWORKSPACEA = pMonitorA->activeWorkspace; + const auto PWORKSPACEB = pMonitorB->activeWorkspace; PWORKSPACEA->m_iMonitorID = pMonitorB->ID; PWORKSPACEA->moveToMonitor(pMonitorB->ID); for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == PWORKSPACEA->m_iID) { + if (w->m_pWorkspace == PWORKSPACEA) { if (w->m_bPinned) { - w->m_iWorkspaceID = PWORKSPACEB->m_iID; + w->m_pWorkspace = PWORKSPACEB; continue; } @@ -2052,9 +2053,9 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) PWORKSPACEB->moveToMonitor(pMonitorA->ID); for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == PWORKSPACEB->m_iID) { + if (w->m_pWorkspace == PWORKSPACEB) { if (w->m_bPinned) { - w->m_iWorkspaceID = PWORKSPACEA->m_iID; + w->m_pWorkspace = PWORKSPACEA; continue; } @@ -2073,8 +2074,8 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) } } - pMonitorA->activeWorkspace = PWORKSPACEB->m_iID; - pMonitorB->activeWorkspace = PWORKSPACEA->m_iID; + pMonitorA->activeWorkspace = PWORKSPACEB; + pMonitorB->activeWorkspace = PWORKSPACEA; PWORKSPACEA->rememberPrevWorkspace(PWORKSPACEB); PWORKSPACEB->rememberPrevWorkspace(PWORKSPACEA); @@ -2099,10 +2100,10 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) // event g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)}); - EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEA, pMonitorB})); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEA, pMonitorB})); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)}); - EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEB, pMonitorA})); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEB, pMonitorA})); } CMonitor* CCompositor::getMonitorFromString(const std::string& name) { @@ -2179,9 +2180,9 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) { return nullptr; } -void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMonitor, bool noWarpCursor) { +void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMonitor, bool noWarpCursor) { - // We trust the workspace and monitor to be correct. + // We trust the monitor to be correct. if (pWorkspace->m_iMonitorID == pMonitor->ID) return; @@ -2190,7 +2191,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni const auto POLDMON = getMonitorFromID(pWorkspace->m_iMonitorID); - const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace->m_iID : false; + const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace : false; // fix old mon int nextWorkspaceOnMonitorID = -1; @@ -2227,9 +2228,9 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni pWorkspace->moveToMonitor(pMonitor->ID); for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == pWorkspace->m_iID) { + if (w->m_pWorkspace == pWorkspace) { if (w->m_bPinned) { - w->m_iWorkspaceID = nextWorkspaceOnMonitorID; + w->m_pWorkspace = g_pCompositor->getWorkspaceByID(nextWorkspaceOnMonitorID); continue; } @@ -2255,13 +2256,13 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni } if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_pLastMonitor) { // if it was active, preserve its' status. If it wasn't, don't. - Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspace, pWorkspace->m_iID); + Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspaceID(), pWorkspace->m_iID); - if (const auto PWORKSPACE = getWorkspaceByID(pMonitor->activeWorkspace); PWORKSPACE) - getWorkspaceByID(pMonitor->activeWorkspace)->startAnim(false, false); + if (valid(pMonitor->activeWorkspace)) + pMonitor->activeWorkspace->startAnim(false, false); setActiveMonitor(pMonitor); - pMonitor->activeWorkspace = pWorkspace->m_iID; + pMonitor->activeWorkspace = pWorkspace; g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitor->ID); pWorkspace->startAnim(true, true, true); @@ -2275,7 +2276,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni // finalize if (POLDMON) { g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID); - updateFullscreenFadeOnWorkspace(getWorkspaceByID(POLDMON->activeWorkspace)); + updateFullscreenFadeOnWorkspace(POLDMON->activeWorkspace); } updateFullscreenFadeOnWorkspace(pWorkspace); @@ -2283,7 +2284,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni // event g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)}); - EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); } bool CCompositor::workspaceIDOutOfBounds(const int64_t& id) { @@ -2304,12 +2305,12 @@ bool CCompositor::workspaceIDOutOfBounds(const int64_t& id) { return std::clamp(id, lowestID, highestID) != id; } -void CCompositor::updateFullscreenFadeOnWorkspace(CWorkspace* pWorkspace) { +void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) { const auto FULLSCREEN = pWorkspace->m_bHasFullscreenWindow; for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == pWorkspace->m_iID) { + if (w->m_pWorkspace == pWorkspace) { if (w->m_bFadingOut || w->m_bPinned || w->m_bIsFullscreen) continue; @@ -2323,7 +2324,7 @@ void CCompositor::updateFullscreenFadeOnWorkspace(CWorkspace* pWorkspace) { const auto PMONITOR = getMonitorFromID(pWorkspace->m_iMonitorID); - if (pWorkspace->m_iID == PMONITOR->activeWorkspace || pWorkspace->m_iID == PMONITOR->specialWorkspaceID) { + if (pWorkspace->m_iID == PMONITOR->activeWorkspaceID() || pWorkspace->m_iID == PMONITOR->activeSpecialWorkspaceID()) { for (auto& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { if (!ls->fadingOut) ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 1.f; @@ -2347,7 +2348,7 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); - const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; const auto MODE = mode == FULLSCREEN_INVALID ? PWORKSPACE->m_efFullscreenMode : mode; @@ -2364,14 +2365,14 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode // make all windows on the same workspace under the fullscreen window for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == PWORKSPACE->m_iID && !w->m_bIsFullscreen && !w->m_bFadingOut && !w->m_bPinned) + if (w->m_pWorkspace == PWORKSPACE && !w->m_bIsFullscreen && !w->m_bFadingOut && !w->m_bPinned) w->m_bCreatedOverFullscreen = false; } updateFullscreenFadeOnWorkspace(PWORKSPACE); g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal(), true); - forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID); + forceReportSizesToWindowsOnWorkspace(pWindow->workspaceID()); g_pInputManager->recheckIdleInhibitorStatus(); @@ -2398,7 +2399,7 @@ CWindow* CCompositor::getX11Parent(CWindow* pWindow) { void CCompositor::updateWorkspaceWindowDecos(const int& id) { for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID != id) + if (w->workspaceID() != id) continue; w->updateWindowDecos(); @@ -2440,7 +2441,7 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) { const bool FLOAT = regexp.starts_with("floating"); for (auto& w : m_vWindows) { - if (!w->m_bIsMapped || w->m_bIsFloating != FLOAT || w->m_iWorkspaceID != m_pLastWindow->m_iWorkspaceID || w->isHidden()) + if (!w->m_bIsMapped || w->m_bIsFloating != FLOAT || w->m_pWorkspace != m_pLastWindow->m_pWorkspace || w->isHidden()) continue; return w.get(); @@ -2608,13 +2609,13 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { for (auto& w : m_vWindows) { - if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->isHidden()) { + if (w->workspaceID() == wid && w->m_bIsMapped && !w->isHidden()) { g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.value(), true); } } } -CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name) { +PHLWORKSPACE CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name) { const auto NAME = name == "" ? std::to_string(id) : name; auto monID = monid; @@ -2625,7 +2626,7 @@ CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, con const bool SPECIAL = id >= SPECIAL_WORKSPACE_START && id <= -2; - const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique(id, monID, NAME, SPECIAL)).get(); + const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, monID, NAME, SPECIAL)); PWORKSPACE->m_fAlpha.setValueAndWarp(0); @@ -2656,7 +2657,7 @@ void CCompositor::setActiveMonitor(CMonitor* pMonitor) { return; } - const auto PWORKSPACE = getWorkspaceByID(pMonitor->activeWorkspace); + const auto PWORKSPACE = pMonitor->activeWorkspace; g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + (PWORKSPACE ? PWORKSPACE->m_szName : "?")}); EMIT_HOOK_EVENT("focusedMon", pMonitor); @@ -2682,7 +2683,7 @@ void CCompositor::performUserChecks() { ; // intentional } -void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorkspace) { +void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, PHLWORKSPACE pWorkspace) { if (!pWindow || !pWorkspace) return; @@ -2690,17 +2691,17 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks return; const bool FULLSCREEN = pWindow->m_bIsFullscreen; - const auto FULLSCREENMODE = getWorkspaceByID(pWindow->m_iWorkspaceID)->m_efFullscreenMode; + const auto FULLSCREENMODE = pWindow->m_pWorkspace->m_efFullscreenMode; if (FULLSCREEN) setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); - pWindow->moveToWorkspace(pWorkspace->m_iID); + pWindow->moveToWorkspace(pWorkspace); if (!pWindow->m_bIsFloating) { g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(pWindow); - pWindow->m_iWorkspaceID = pWorkspace->m_iID; - pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; + pWindow->m_pWorkspace = pWorkspace; + pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow); } else { const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); @@ -2708,8 +2709,8 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); - pWindow->m_iWorkspaceID = pWorkspace->m_iID; - pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; + pWindow->m_pWorkspace = pWorkspace; + pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; } @@ -2721,7 +2722,7 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks if (pWindow->m_sGroupData.pNextWindow) { CWindow* next = pWindow->m_sGroupData.pNextWindow; while (next != pWindow) { - next->moveToWorkspace(pWorkspace->m_iID); + next->moveToWorkspace(pWorkspace); next->updateToplevel(); next = next->m_sGroupData.pNextWindow; } @@ -2731,12 +2732,12 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks setWindowFullscreen(pWindow, true, FULLSCREENMODE); g_pCompositor->updateWorkspaceWindows(pWorkspace->m_iID); - g_pCompositor->updateWorkspaceWindows(pWindow->m_iWorkspaceID); + g_pCompositor->updateWorkspaceWindows(pWindow->workspaceID()); } CWindow* CCompositor::getForceFocus() { for (auto& w : m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->m_iWorkspaceID)) + if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->workspaceID())) continue; if (!w->m_bStayFocused) @@ -2885,6 +2886,6 @@ void CCompositor::updateSuspendedStates() { if (!w->m_bIsMapped) continue; - w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->m_iWorkspaceID)); + w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->workspaceID())); } } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index ace2a388..98bbe899 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -92,7 +92,7 @@ class CCompositor { std::vector> m_vMonitors; std::vector> m_vRealMonitors; // for all monitors, even those turned off std::vector> m_vWindows; - std::vector> m_vWorkspaces; + std::vector m_vWorkspaces; std::vector m_vWindowsFadingOut; std::vector m_vSurfacesFadingOut; @@ -145,9 +145,9 @@ class CCompositor { CWindow* getWindowFromHandle(uint32_t); CWindow* getWindowFromZWLRHandle(wl_resource*); bool isWorkspaceVisible(const int&); - CWorkspace* getWorkspaceByID(const int&); - CWorkspace* getWorkspaceByName(const std::string&); - CWorkspace* getWorkspaceByString(const std::string&); + PHLWORKSPACE getWorkspaceByID(const int&); + PHLWORKSPACE getWorkspaceByName(const std::string&); + PHLWORKSPACE getWorkspaceByString(const std::string&); void sanityCheckWorkspaces(); void updateWorkspaceWindowDecos(const int&); int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}); @@ -172,12 +172,12 @@ class CCompositor { void updateWorkspaceWindows(const int64_t& id); void updateWindowAnimatedDecorationValues(CWindow*); int getNextAvailableMonitorID(std::string const& name); - void moveWorkspaceToMonitor(CWorkspace*, CMonitor*, bool noWarpCursor = false); + void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false); void swapActiveWorkspaces(CMonitor*, CMonitor*); CMonitor* getMonitorFromString(const std::string&); bool workspaceIDOutOfBounds(const int64_t&); void setWindowFullscreen(CWindow*, bool, eFullscreenMode mode = FULLSCREEN_INVALID); - void updateFullscreenFadeOnWorkspace(CWorkspace*); + void updateFullscreenFadeOnWorkspace(PHLWORKSPACE); CWindow* getX11Parent(CWindow*); void scheduleFrameForMonitor(CMonitor*); void addToFadingOutSafe(SLayerSurface*); @@ -189,13 +189,13 @@ class CCompositor { void closeWindow(CWindow*); Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); void forceReportSizesToWindowsOnWorkspace(const int&); - CWorkspace* createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! + PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! void renameWorkspace(const int&, const std::string& name = ""); void setActiveMonitor(CMonitor*); bool isWorkspaceSpecial(const int&); int getNewSpecialID(); void performUserChecks(); - void moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorkspace); + void moveWindowToWorkspaceSafe(CWindow* pWindow, PHLWORKSPACE pWorkspace); CWindow* getForceFocus(); void notifyIdleActivity(); void setIdleActivityInhibit(bool inhibit); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index df2006ae..87bb5bbd 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -956,7 +956,7 @@ SMonitorRule CConfigManager::getMonitorRuleFor(const CMonitor& PMONITOR) { return SMonitorRule{.name = "", .resolution = Vector2D(0, 0), .offset = Vector2D(-INT32_MAX, -INT32_MAX), .scale = -1}; // 0, 0 is preferred and -1, -1 is auto } -std::vector CConfigManager::getWorkspaceRulesFor(CWorkspace* pWorkspace) { +std::vector CConfigManager::getWorkspaceRulesFor(PHLWORKSPACE pWorkspace) { std::vector results; for (auto& rule : m_dWorkspaceRules) { if (pWorkspace->matchesStaticSelector(rule.workspaceString)) @@ -1056,13 +1056,13 @@ std::vector CConfigManager::getMatchingRules(CWindow* pWindow, bool } if (!rule.szOnWorkspace.empty()) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; if (!PWORKSPACE || !PWORKSPACE->matchesStaticSelector(rule.szOnWorkspace)) continue; } if (!rule.szWorkspace.empty()) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; if (!PWORKSPACE) continue; @@ -1287,7 +1287,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) { /* fullscreen */ m->vrrActive = true; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m->activeWorkspace); + const auto PWORKSPACE = m->activeWorkspace; if (!PWORKSPACE) return; // ??? diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 5406d853..2ef94ca7 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -105,7 +105,7 @@ class CConfigManager { static std::string getMainConfigPath(); SMonitorRule getMonitorRuleFor(const CMonitor&); - std::vector getWorkspaceRulesFor(CWorkspace*); + std::vector getWorkspaceRulesFor(PHLWORKSPACE workspace); std::string getDefaultWorkspaceFor(const std::string&); CMonitor* getBoundMonitorForWS(const std::string&); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index f61f5544..3c53d97f 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -24,15 +24,6 @@ static void trimTrailingComma(std::string& str) { str.pop_back(); } -static std::string getWorkspaceNameFromSpecialID(const int workspaceID) { - if (workspaceID == 0) - return ""; - const auto* workspace = g_pCompositor->getWorkspaceByID(workspaceID); - if (!workspace) - return ""; - return workspace->m_szName; -} - static std::string formatToString(uint32_t drmFormat) { switch (drmFormat) { case DRM_FORMAT_XRGB2101010: return "XRGB2101010"; @@ -116,8 +107,8 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { }},)#", m->ID, escapeJSONStrings(m->szName), escapeJSONStrings(m->szShortDescription), (m->output->make ? m->output->make : ""), (m->output->model ? m->output->model : ""), (m->output->serial ? m->output->serial : ""), (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, - m->activeWorkspace, (m->activeWorkspace == -1 ? "" : escapeJSONStrings(g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName)), m->specialWorkspaceID, - escapeJSONStrings(getWorkspaceNameFromSpecialID(m->specialWorkspaceID)), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, + m->activeWorkspaceID(), (!m->activeWorkspace ? "" : escapeJSONStrings(m->activeWorkspace->m_szName)), m->activeSpecialWorkspaceID(), + escapeJSONStrings(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.get() == g_pCompositor->m_pLastMonitor ? "true" : "false"), (m->dpmsStatus ? "true" : "false"), (m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ? "true" : "false"), m->tearingState.activelyTearing ? "true" : "false", formatToString(m->drmFormat), availableModesForOutput(m.get(), format)); @@ -131,18 +122,17 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { if (!m->output || m->ID == -1ull) continue; - result += - std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\tspecial " - "workspace: {} ({})\n\treserved: {} " - "{} {} {}\n\tscale: {:.2f}\n\ttransform: " - "{}\n\tfocused: {}\n\tdpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\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->make : ""), (m->output->model ? m->output->model : ""), (m->output->serial ? m->output->serial : ""), m->activeWorkspace, - (m->activeWorkspace == -1 ? "" : g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName), m->specialWorkspaceID, - getWorkspaceNameFromSpecialID(m->specialWorkspaceID), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, - (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, - (int)(m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED), m->tearingState.activelyTearing, formatToString(m->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\tspecial " + "workspace: {} ({})\n\treserved: {} " + "{} {} {}\n\tscale: {:.2f}\n\ttransform: " + "{}\n\tfocused: {}\n\tdpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\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->make : ""), (m->output->model ? m->output->model : ""), (m->output->serial ? 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.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, (int)(m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED), + m->tearingState.activelyTearing, formatToString(m->drmFormat), availableModesForOutput(m.get(), format)); } } @@ -211,30 +201,23 @@ static std::string getWindowData(CWindow* w, eHyprCtlOutputFormat format) { "focusHistoryID": {} }},)#", (uintptr_t)w, (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, - (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_iWorkspaceID, - escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" : - g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : - std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))), - ((int)w->m_bIsFloating == 1 ? "true" : "false"), (int64_t)w->m_iMonitorID, escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w)), - escapeJSONStrings(g_pXWaylandManager->getTitle(w)), escapeJSONStrings(w->m_szInitialClass), escapeJSONStrings(w->m_szInitialTitle), w->getPID(), - ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"), (w->m_bIsFullscreen ? "true" : "false"), - (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? (int)g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0), + (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, + escapeJSONStrings(!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), ((int)w->m_bIsFloating == 1 ? "true" : "false"), (int64_t)w->m_iMonitorID, + escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w)), escapeJSONStrings(g_pXWaylandManager->getTitle(w)), escapeJSONStrings(w->m_szInitialClass), + escapeJSONStrings(w->m_szInitialTitle), w->getPID(), ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"), + (w->m_bIsFullscreen ? "true" : "false"), (w->m_bIsFullscreen ? (w->m_pWorkspace ? (int)w->m_pWorkspace->m_efFullscreenMode : 0) : 0), w->m_bFakeFullscreenState ? "true" : "false", getGroupedData(w, format), (uintptr_t)w->m_pSwallowed, getFocusHistoryID(w)); } else { - return std::format( - "Window {:x} -> {}:\n\tmapped: {}\n\thidden: {}\n\tat: {},{}\n\tsize: {},{}\n\tworkspace: {} ({})\n\tfloating: {}\n\tmonitor: {}\n\tclass: {}\n\ttitle: " - "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " - "{}\n\txwayland: {}\n\tpinned: " - "{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n", - (uintptr_t)w, w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, (int)w->m_vRealSize.goal().x, - (int)w->m_vRealSize.goal().y, w->m_iWorkspaceID, - (w->m_iWorkspaceID == -1 ? "" : - g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : - std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))), - (int)w->m_bIsFloating, (int64_t)w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w), g_pXWaylandManager->getTitle(w), w->m_szInitialClass, w->m_szInitialTitle, - w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, - (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0), - (int)w->m_bFakeFullscreenState, getGroupedData(w, format), (uintptr_t)w->m_pSwallowed, getFocusHistoryID(w)); + return std::format("Window {:x} -> {}:\n\tmapped: {}\n\thidden: {}\n\tat: {},{}\n\tsize: {},{}\n\tworkspace: {} ({})\n\tfloating: {}\n\tmonitor: {}\n\tclass: {}\n\ttitle: " + "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " + "{}\n\txwayland: {}\n\tpinned: " + "{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n", + (uintptr_t)w, w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, + (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, + (!w->m_pWorkspace ? "" : std::to_string(w->workspaceID())), (int)w->m_bIsFloating, (int64_t)w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w), + g_pXWaylandManager->getTitle(w), w->m_szInitialClass, w->m_szInitialTitle, w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, + (w->m_bIsFullscreen ? (w->m_pWorkspace ? w->m_pWorkspace->m_efFullscreenMode : 0) : 0), (int)w->m_bFakeFullscreenState, getGroupedData(w, format), + (uintptr_t)w->m_pSwallowed, getFocusHistoryID(w)); } } @@ -264,7 +247,7 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) { return result; } -static std::string getWorkspaceData(CWorkspace* w, eHyprCtlOutputFormat format) { +static std::string getWorkspaceData(PHLWORKSPACE w, eHyprCtlOutputFormat format) { const auto PLASTW = w->getLastFocusedWindow(); const auto PMONITOR = g_pCompositor->getMonitorFromID(w->m_iMonitorID); if (format == eHyprCtlOutputFormat::FORMAT_JSON) { @@ -339,9 +322,9 @@ std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string requ return "unsafe state"; std::string result = ""; - auto w = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); + auto w = g_pCompositor->m_pLastMonitor->activeWorkspace; - if (!w) + if (!valid(w)) return "internal error"; return getWorkspaceData(w, format); @@ -353,7 +336,7 @@ std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) if (format == eHyprCtlOutputFormat::FORMAT_JSON) { result += "["; for (auto& w : g_pCompositor->m_vWorkspaces) { - result += getWorkspaceData(w.get(), format); + result += getWorkspaceData(w, format); result += ","; } @@ -361,7 +344,7 @@ std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) result += "]"; } else { for (auto& w : g_pCompositor->m_vWorkspaces) { - result += getWorkspaceData(w.get(), format); + result += getWorkspaceData(w, format); } } diff --git a/src/desktop/DesktopTypes.hpp b/src/desktop/DesktopTypes.hpp new file mode 100644 index 00000000..1548f694 --- /dev/null +++ b/src/desktop/DesktopTypes.hpp @@ -0,0 +1,6 @@ +#pragma once +#include + +class CWorkspace; + +typedef std::shared_ptr PHLWORKSPACE; \ No newline at end of file diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 891fd652..34ae857f 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -4,6 +4,7 @@ #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprBorderDecoration.hpp" #include "../config/ConfigValue.hpp" +#include CWindow::CWindow() { m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE); @@ -377,43 +378,37 @@ void CWindow::updateSurfaceScaleTransformDetails() { this); } -void CWindow::moveToWorkspace(int workspaceID) { - if (m_iWorkspaceID == workspaceID) +void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { + if (m_pWorkspace == pWorkspace) return; static auto PCLOSEONLASTSPECIAL = CConfigValue("misc:close_special_on_empty"); - const int OLDWORKSPACE = m_iWorkspaceID; + const auto OLDWORKSPACE = m_pWorkspace; - m_iWorkspaceID = workspaceID; - - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + m_pWorkspace = pWorkspace; setAnimationsToMove(); updateSpecialRenderData(); - if (PWORKSPACE) { - g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, PWORKSPACE->m_szName)}); - g_pEventManager->postEvent(SHyprIPCEvent{"movewindowv2", std::format("{:x},{},{}", (uintptr_t)this, PWORKSPACE->m_iID, PWORKSPACE->m_szName)}); - EMIT_HOOK_EVENT("moveWindow", (std::vector{this, PWORKSPACE})); + if (valid(pWorkspace)) { + g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, pWorkspace->m_szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{"movewindowv2", std::format("{:x},{},{}", (uintptr_t)this, pWorkspace->m_iID, pWorkspace->m_szName)}); + EMIT_HOOK_EVENT("moveWindow", (std::vector{this, pWorkspace})); } if (m_pSwallowed) { - m_pSwallowed->moveToWorkspace(workspaceID); + m_pSwallowed->moveToWorkspace(pWorkspace); m_pSwallowed->m_iMonitorID = m_iMonitorID; } // update xwayland coords g_pXWaylandManager->setWindowSize(this, m_vRealSize.value()); - if (g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE) == 0 && *PCLOSEONLASTSPECIAL) { - const auto PWS = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); - - if (PWS) { - if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWS->m_iMonitorID); PMONITOR) - PMONITOR->setSpecialWorkspace(nullptr); - } + if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE->m_iID) == 0 && *PCLOSEONLASTSPECIAL) { + if (const auto PMONITOR = g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID); PMONITOR) + PMONITOR->setSpecialWorkspace(nullptr); } } @@ -455,6 +450,8 @@ void CWindow::onUnmap() { if (g_pCompositor->m_pLastWindow == this) g_pCompositor->m_pLastWindow = nullptr; + m_iLastWorkspace = onSpecialWorkspace(); + m_vRealPosition.setCallbackOnEnd(unregisterVar); m_vRealSize.setCallbackOnEnd(unregisterVar); m_fBorderFadeAnimationProgress.setCallbackOnEnd(unregisterVar); @@ -470,9 +467,9 @@ void CWindow::onUnmap() { hyprListener_unmapWindow.removeCallback(); - if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(m_iWorkspaceID) == 0 && g_pCompositor->isWorkspaceSpecial(m_iWorkspaceID)) { + if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(workspaceID()) == 0 && onSpecialWorkspace()) { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); - if (PMONITOR && PMONITOR->specialWorkspaceID == m_iWorkspaceID) + if (PMONITOR && PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace == m_pWorkspace) PMONITOR->setSpecialWorkspace(nullptr); } @@ -481,13 +478,14 @@ void CWindow::onUnmap() { if (PMONITOR && PMONITOR->solitaryClient == this) PMONITOR->solitaryClient = nullptr; - g_pCompositor->updateWorkspaceWindows(m_iWorkspaceID); + g_pCompositor->updateWorkspaceWindows(workspaceID()); if (m_bIsX11) return; m_pSubsurfaceHead.reset(); m_pPopupHead.reset(); + m_pWorkspace.reset(); } void CWindow::onMap() { @@ -943,7 +941,7 @@ void CWindow::setGroupCurrent(CWindow* pWindow) { const auto PCURRENT = getGroupCurrent(); const bool FULLSCREEN = PCURRENT->m_bIsFullscreen; - const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PCURRENT->m_iWorkspaceID); + const auto WORKSPACE = PCURRENT->m_pWorkspace; const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal(); const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal(); @@ -1034,11 +1032,13 @@ void CWindow::updateGroupOutputs() { if (!m_sGroupData.pNextWindow) return; - CWindow* curr = m_sGroupData.pNextWindow; + CWindow* curr = m_sGroupData.pNextWindow; + + const auto WS = m_pWorkspace; while (curr != this) { curr->m_iMonitorID = m_iMonitorID; - curr->moveToWorkspace(m_iWorkspaceID); + curr->moveToWorkspace(WS); curr->m_vRealPosition = m_vRealPosition.goal(); curr->m_vRealSize = m_vRealSize.goal(); @@ -1058,7 +1058,7 @@ bool CWindow::opaque() { if (m_vRealSize.goal().floor() != m_vReportedSize) return false; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + const auto PWORKSPACE = m_pWorkspace; if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall) return false; @@ -1088,7 +1088,7 @@ float CWindow::rounding() { } void CWindow::updateSpecialRenderData() { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + const auto PWORKSPACE = m_pWorkspace; const auto WORKSPACERULES = PWORKSPACE ? g_pConfigManager->getWorkspaceRulesFor(PWORKSPACE) : std::vector{}; bool border = true; @@ -1137,7 +1137,7 @@ bool CWindow::canBeTorn() { } bool CWindow::shouldSendFullscreenState() { - const auto MODE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID)->m_efFullscreenMode; + const auto MODE = m_pWorkspace->m_efFullscreenMode; return m_bDontSendFullscreen ? false : (m_bFakeFullscreenState || (m_bIsFullscreen && (MODE == FULLSCREEN_FULL))); } @@ -1173,7 +1173,7 @@ void CWindow::onWorkspaceAnimUpdate() { } Vector2D offset; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); + const auto PWORKSPACE = m_pWorkspace; if (!PWORKSPACE) return; @@ -1212,3 +1212,11 @@ int CWindow::popupsCount() { m_uSurface.xdg, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no); return no; } + +int CWindow::workspaceID() { + return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace; +} + +bool CWindow::onSpecialWorkspace() { + return m_pWorkspace ? m_pWorkspace->m_bIsSpecialWorkspace : g_pCompositor->isWorkspaceSpecial(m_iLastWorkspace); +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index bc1820a0..ae62e77e 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -11,6 +11,7 @@ #include "Popup.hpp" #include "../macros.hpp" #include "../managers/XWaylandManager.hpp" +#include "DesktopTypes.hpp" enum eIdleInhibitMode { IDLEINHIBIT_NONE = 0, @@ -241,24 +242,24 @@ class CWindow { Vector2D m_vFloatingOffset = Vector2D(0, 0); // this is used for pseudotiling - bool m_bIsPseudotiled = false; - Vector2D m_vPseudoSize = Vector2D(0, 0); + bool m_bIsPseudotiled = false; + Vector2D m_vPseudoSize = Vector2D(0, 0); - bool m_bFirstMap = false; // for layouts - bool m_bIsFloating = false; - bool m_bDraggingTiled = false; // for dragging around tiled windows - bool m_bIsFullscreen = false; - bool m_bDontSendFullscreen = false; - bool m_bWasMaximized = false; - uint64_t m_iMonitorID = -1; - std::string m_szTitle = ""; - std::string m_szInitialTitle = ""; - std::string m_szInitialClass = ""; - int m_iWorkspaceID = -1; + bool m_bFirstMap = false; // for layouts + bool m_bIsFloating = false; + bool m_bDraggingTiled = false; // for dragging around tiled windows + bool m_bIsFullscreen = false; + bool m_bDontSendFullscreen = false; + bool m_bWasMaximized = false; + uint64_t m_iMonitorID = -1; + std::string m_szTitle = ""; + std::string m_szInitialTitle = ""; + std::string m_szInitialClass = ""; + PHLWORKSPACE m_pWorkspace; - bool m_bIsMapped = false; + bool m_bIsMapped = false; - bool m_bRequestsFloat = false; + bool m_bRequestsFloat = false; // This is for fullscreen apps bool m_bCreatedOverFullscreen = false; @@ -384,7 +385,7 @@ class CWindow { void destroyToplevelHandle(); void updateToplevel(); void updateSurfaceScaleTransformDetails(); - void moveToWorkspace(int); + void moveToWorkspace(PHLWORKSPACE); CWindow* X11TransientFor(); void onUnmap(); void onMap(); @@ -400,6 +401,8 @@ class CWindow { bool shouldSendFullscreenState(); void setSuspended(bool suspend); bool visibleOnMonitor(CMonitor* pMonitor); + int workspaceID(); + bool onSpecialWorkspace(); int getRealBorderSize(); void updateSpecialRenderData(); @@ -428,8 +431,9 @@ class CWindow { private: // For hidden windows and stuff - bool m_bHidden = false; - bool m_bSuspended = false; + bool m_bHidden = false; + bool m_bSuspended = false; + int m_iLastWorkspace = WORKSPACE_INVALID; }; /** @@ -464,7 +468,7 @@ struct std::formatter : std::formatter { std::format_to(out, "["); std::format_to(out, "Window {:x}: title: \"{}\"", (uintptr_t)w, w->m_szTitle); if (formatWorkspace) - std::format_to(out, ", workspace: {}", w->m_iWorkspaceID); + std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID); if (formatMonitor) std::format_to(out, ", monitor: {}", w->m_iMonitorID); if (formatClass) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 9200b4d7..ccb0fa25 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -2,6 +2,12 @@ #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool special) { + PHLWORKSPACE workspace = std::make_shared(id, monitorID, name, special); + workspace->init(workspace); + return workspace; +} + CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); @@ -14,17 +20,22 @@ CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { m_iID = id; m_szName = name; m_bIsSpecialWorkspace = special; +} - m_vRenderOffset.create(special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), this, - AVARDAMAGE_ENTIRE); - m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), this, +void CWorkspace::init(PHLWORKSPACE self) { + m_pSelf = self; + + m_vRenderOffset.create(m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), + self, AVARDAMAGE_ENTIRE); + m_fAlpha.create(AVARTYPE_FLOAT, + m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), self, AVARDAMAGE_ENTIRE); m_fAlpha.setValueAndWarp(1.f); m_vRenderOffset.registerVar(); m_fAlpha.registerVar(); - const auto RULESFORTHIS = g_pConfigManager->getWorkspaceRulesFor(this); + const auto RULESFORTHIS = g_pConfigManager->getWorkspaceRulesFor(self); for (auto& rule : RULESFORTHIS) { if (rule.defaultName.has_value()) m_szName = rule.defaultName.value(); @@ -37,6 +48,8 @@ CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { m_pLastFocusedWindow = nullptr; }); + m_bInert = false; + g_pEventManager->postEvent({"createworkspace", m_szName}); g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)}); EMIT_HOOK_EVENT("createWorkspace", this); @@ -61,7 +74,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { // set floating windows offset callbacks m_vRenderOffset.setUpdateCallback([&](void*) { for (auto& w : g_pCompositor->m_vWindows) { - if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != m_iID) + if (!g_pCompositor->windowValidMapped(w.get()) || w->workspaceID() != m_iID) continue; w->onWorkspaceAnimUpdate(); @@ -169,13 +182,13 @@ void CWorkspace::moveToMonitor(const int& id) { } CWindow* CWorkspace::getLastFocusedWindow() { - if (!g_pCompositor->windowValidMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->m_iWorkspaceID != m_iID) + if (!g_pCompositor->windowValidMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->workspaceID() != m_iID) return nullptr; return m_pLastFocusedWindow; } -void CWorkspace::rememberPrevWorkspace(const CWorkspace* prev) { +void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) { if (!prev) { m_sPrevWorkspace.iID = -1; m_sPrevWorkspace.name = ""; @@ -405,3 +418,12 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { UNREACHABLE(); return false; } + +void CWorkspace::markInert() { + m_bInert = true; + m_iID = WORKSPACE_INVALID; +} + +bool CWorkspace::inert() { + return m_bInert; +} diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 0cae1859..1630baf5 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -3,6 +3,7 @@ #include "../helpers/AnimatedVariable.hpp" #include #include "../defines.hpp" +#include "DesktopTypes.hpp" enum eFullscreenMode : int8_t { FULLSCREEN_INVALID = -1, @@ -14,6 +15,8 @@ class CWindow; class CWorkspace { public: + static PHLWORKSPACE create(int id, int monitorID, std::string name, bool special = false); + // use create() don't use this CWorkspace(int id, int monitorID, std::string name, bool special = false); ~CWorkspace(); @@ -53,7 +56,10 @@ class CWorkspace { std::string m_szLastMonitor = ""; // Whether the user configured command for on-created-empty has been executed, if any - bool m_bOnCreatedEmptyExecuted = false; + bool m_bOnCreatedEmptyExecuted = false; + + // Inert: destroyed and invalid. If this is true, release the ptr you have. + bool inert(); void startAnim(bool in, bool left, bool instant = false); void setActive(bool on); @@ -61,12 +67,25 @@ class CWorkspace { void moveToMonitor(const int&); CWindow* getLastFocusedWindow(); - void rememberPrevWorkspace(const CWorkspace* prevWorkspace); + void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); std::string getConfigName(); bool matchesStaticSelector(const std::string& selector); + void markInert(); + private: - HOOK_CALLBACK_FN* m_pFocusedWindowHook = nullptr; + void init(PHLWORKSPACE self); + + HOOK_CALLBACK_FN* m_pFocusedWindowHook = nullptr; + bool m_bInert = true; + std::weak_ptr m_pSelf; }; + +inline bool valid(const PHLWORKSPACE& ref) { + if (!ref) + return false; + + return !ref->inert(); +} diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index a1fef175..bd27004b 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -163,7 +163,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) { CBox geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height}; g_pHyprRenderer->damageBox(&geomFixed); - const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const auto WORKSPACE = PMONITOR->activeWorkspace; const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL; layersurface->startAnimation(!(layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS)); @@ -237,7 +237,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface); - if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_iWorkspaceID)) { + if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->workspaceID())) { // if there isn't any, focus the last window const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->focusWindow(nullptr); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 00546550..eb876cf2 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -57,9 +57,9 @@ void Events::listener_mapWindow(void* owner, void* data) { g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({})); PMONITOR = g_pCompositor->m_pLastMonitor; } - auto PWORKSPACE = PMONITOR->specialWorkspaceID ? g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + auto PWORKSPACE = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace; PWINDOW->m_iMonitorID = PMONITOR->ID; - PWINDOW->m_iWorkspaceID = PMONITOR->specialWorkspaceID ? PMONITOR->specialWorkspaceID : PMONITOR->activeWorkspace; + PWINDOW->m_pWorkspace = PWORKSPACE; PWINDOW->m_bIsMapped = true; PWINDOW->m_bReadyToDelete = false; PWINDOW->m_bFadingOut = false; @@ -153,7 +153,7 @@ void Events::listener_mapWindow(void* owner, void* data) { g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->m_iMonitorID)); PMONITOR = PMONITORFROMID; } - PWINDOW->m_iWorkspaceID = PMONITOR->specialWorkspaceID ? PMONITOR->specialWorkspaceID : PMONITOR->activeWorkspace; + PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace; Debug::log(LOG, "Rule monitor, applying to {:mw}", PWINDOW); } catch (std::exception& e) { Debug::log(ERR, "Rule monitor failed, rule: {} -> {} | err: {}", r.szRule, r.szValue, e.what()); } @@ -287,16 +287,16 @@ void Events::listener_mapWindow(void* owner, void* data) { PWORKSPACE = pWorkspace; - PWINDOW->m_iWorkspaceID = pWorkspace->m_iID; - PWINDOW->m_iMonitorID = pWorkspace->m_iMonitorID; + PWINDOW->m_pWorkspace = pWorkspace; + PWINDOW->m_iMonitorID = pWorkspace->m_iMonitorID; - if (g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->specialWorkspaceID && !pWorkspace->m_bIsSpecialWorkspace) + if (g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeSpecialWorkspace && !pWorkspace->m_bIsSpecialWorkspace) workspaceSilent = true; if (!workspaceSilent) { if (pWorkspace->m_bIsSpecialWorkspace) g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID)->setSpecialWorkspace(pWorkspace); - else if (PMONITOR->activeWorkspace != REQUESTEDWORKSPACEID) + else if (PMONITOR->activeWorkspaceID() != REQUESTEDWORKSPACEID) g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspaceName); PMONITOR = g_pCompositor->m_pLastMonitor; @@ -632,7 +632,7 @@ void Events::listener_mapWindow(void* owner, void* data) { // fix some xwayland apps that don't behave nicely PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; - g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); + g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID()); if (PMONITOR && PWINDOW->m_iX11Type == 2) PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale; @@ -704,7 +704,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { } // remove the fullscreen window status from workspace if we closed it - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACE = PWINDOW->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow && PWINDOW->m_bIsFullscreen) PWORKSPACE->m_bHasFullscreenWindow = false; @@ -723,7 +723,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { if (PWINDOWCANDIDATE != g_pCompositor->m_pLastWindow && PWINDOWCANDIDATE) g_pCompositor->focusWindow(PWINDOWCANDIDATE); - if (!PWINDOWCANDIDATE && g_pCompositor->getWindowsOnWorkspace(PWINDOW->m_iWorkspaceID) == 0) + if (!PWINDOWCANDIDATE && g_pCompositor->getWindowsOnWorkspace(PWINDOW->workspaceID()) == 0) g_pInputManager->refocus(); g_pInputManager->sendMotionEventsToFocused(); @@ -758,7 +758,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { g_pInputManager->recheckIdleInhibitorStatus(); // force report all sizes (QT sometimes has an issue with this) - g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID); + g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->workspaceID()); // update lastwindow after focus PWINDOW->onUnmap(); @@ -934,7 +934,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) { const auto REQUESTED = &PWINDOW->m_uSurface.xdg->toplevel->requested; if (REQUESTED->fullscreen && PWINDOW->m_bIsFullscreen) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACE = PWINDOW->m_pWorkspace; if (PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) { // Store that we were maximized PWINDOW->m_bWasMaximized = true; @@ -1094,10 +1094,10 @@ void Events::listener_configureX11(void* owner, void* data) { PWINDOW->updateWindowDecos(); - if (!g_pCompositor->isWorkspaceVisible(PWINDOW->m_iWorkspaceID)) + if (!g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID())) return; // further things are only for visible windows - PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; + PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; g_pCompositor->changeWindowZOrder(PWINDOW, true); @@ -1155,7 +1155,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal(); PWINDOW->m_vSize = PWINDOW->m_vRealSize.goal(); - PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; + PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; g_pCompositor->changeWindowZOrder(PWINDOW, true); PWINDOW->updateWindowDecos(); diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 74575c83..65206af0 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -22,7 +22,7 @@ void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, SLayer m_bDummy = false; } -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy) { +void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, AVARDAMAGEPOLICY policy) { m_eDamagePolicy = policy; m_pConfig = pAnimConfig; m_pWorkspace = pWorkspace; diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 85ffb9ab..4c24f642 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -8,6 +8,7 @@ #include "Color.hpp" #include "../macros.hpp" #include "../debug/Log.hpp" +#include "../desktop/DesktopTypes.hpp" enum ANIMATEDVARTYPE { AVARTYPE_INVALID = -1, @@ -48,11 +49,11 @@ enum AVARDAMAGEPOLICY { }; class CAnimationManager; -class CWorkspace; struct SLayerSurface; struct SAnimationPropertyConfig; class CHyprRenderer; class CWindow; +class CWorkspace; // Utility to define a concept as a list of possible type template @@ -69,7 +70,7 @@ class CBaseAnimatedVariable { CBaseAnimatedVariable(ANIMATEDVARTYPE type); void create(SAnimationPropertyConfig* pAnimConfig, CWindow* pWindow, AVARDAMAGEPOLICY policy); void create(SAnimationPropertyConfig* pAnimConfig, SLayerSurface* pLayer, AVARDAMAGEPOLICY policy); - void create(SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy); + void create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, AVARDAMAGEPOLICY policy); void create(SAnimationPropertyConfig* pAnimConfig, AVARDAMAGEPOLICY policy); CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; @@ -144,9 +145,9 @@ class CBaseAnimatedVariable { } protected: - void* m_pWindow = nullptr; - void* m_pWorkspace = nullptr; - void* m_pLayer = nullptr; + void* m_pWindow = nullptr; + std::weak_ptr m_pWorkspace; + void* m_pLayer = nullptr; SAnimationPropertyConfig* m_pConfig = nullptr; @@ -217,7 +218,7 @@ class CAnimatedVariable : public CBaseAnimatedVariable { m_Value = value; m_Goal = value; } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, CWorkspace* pWorkspace, AVARDAMAGEPOLICY policy) { + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, AVARDAMAGEPOLICY policy) { create(pAnimConfig, pWorkspace, policy); m_Value = value; m_Goal = value; diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 2b83832c..779b45b1 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -289,9 +289,9 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { if (!g_pCompositor->m_pLastMonitor) return WORKSPACE_INVALID; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; - if (!PWORKSPACE) + if (!valid(PWORKSPACE)) return WORKSPACE_INVALID; const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.iID); @@ -347,7 +347,8 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { std::sort(namedWSes.begin(), namedWSes.end()); // Just take a blind guess at where we'll probably end up - int predictedWSID = g_pCompositor->m_pLastMonitor->activeWorkspace + remains; + 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]; @@ -355,20 +356,20 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { predictedWSID = std::max(predictedWSID, 0); // Count how many invalidWSes are in between (how bad the prediction was) - int beginID = in[1] == '+' ? g_pCompositor->m_pLastMonitor->activeWorkspace + 1 : predictedWSID; - int endID = in[1] == '+' ? predictedWSID : g_pCompositor->m_pLastMonitor->activeWorkspace; + 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 >= for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) { remainingWSes++; } // Handle named workspaces. They are treated like always before other workspaces - if (g_pCompositor->m_pLastMonitor->activeWorkspace < 0) { + if (activeWSID < 0) { // Behaviour similar to 'm' // Find current int currentItem = -1; for (size_t i = 0; i < namedWSes.size(); i++) { - if (namedWSes[i] == g_pCompositor->m_pLastMonitor->activeWorkspace) { + if (namedWSes[i] == activeWSID) { currentItem = i; break; } @@ -473,9 +474,10 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { 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; int currentItem = -1; for (size_t i = 0; i < validWSes.size(); i++) { - if (validWSes[i] == g_pCompositor->m_pLastMonitor->activeWorkspace) { + if (validWSes[i] == activeWSID) { currentItem = i; break; } @@ -496,7 +498,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { } else { if (in[0] == '+' || in[0] == '-') { if (g_pCompositor->m_pLastMonitor) { - const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspaceID()); if (!PLUSMINUSRESULT.has_value()) return WORKSPACE_INVALID; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 219257b9..4018cc8b 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -170,7 +170,7 @@ void CMonitor::onConnect(bool noRule) { for (auto& ws : g_pCompositor->m_vWorkspaces) { if (ws->m_szLastMonitor == szName || g_pCompositor->m_vMonitors.size() == 1 /* avoid lost workspaces on recover */) { - g_pCompositor->moveWorkspaceToMonitor(ws.get(), this); + g_pCompositor->moveWorkspaceToMonitor(ws, this); ws->startAnim(true, true, true); ws->m_szLastMonitor = ""; } @@ -281,10 +281,10 @@ void CMonitor::onDisconnect(bool destroy) { BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f); // move workspaces - std::deque wspToMove; + std::deque wspToMove; for (auto& w : g_pCompositor->m_vWorkspaces) { if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) { - wspToMove.push_back(w.get()); + wspToMove.push_back(w); } } @@ -299,7 +299,7 @@ void CMonitor::onDisconnect(bool destroy) { g_pCompositor->m_pLastMonitor = nullptr; } - activeWorkspace = -1; + activeWorkspace.reset(); if (!destroy) wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output); @@ -403,17 +403,17 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { if (PNEWWORKSPACE) { // workspace exists, move it to the newly connected monitor g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this); - activeWorkspace = PNEWWORKSPACE->m_iID; + activeWorkspace = PNEWWORKSPACE; g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); PNEWWORKSPACE->startAnim(true, true, true); } else { if (newDefaultWorkspaceName == "") newDefaultWorkspaceName = std::to_string(WORKSPACEID); - PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique(WORKSPACEID, ID, newDefaultWorkspaceName)).get(); + PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(WORKSPACEID, ID, newDefaultWorkspaceName)); } - activeWorkspace = PNEWWORKSPACE->m_iID; + activeWorkspace = PNEWWORKSPACE; PNEWWORKSPACE->setActive(true); PNEWWORKSPACE->m_szLastMonitor = ""; @@ -481,10 +481,10 @@ void CMonitor::setMirror(const std::string& mirrorOf) { } // move all the WS - std::deque wspToMove; + std::deque wspToMove; for (auto& w : g_pCompositor->m_vWorkspaces) { if (w->m_iMonitorID == ID) { - wspToMove.push_back(w.get()); + wspToMove.push_back(w); } } @@ -493,7 +493,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) { w->startAnim(true, true, true); } - activeWorkspace = -1; + activeWorkspace.reset(); wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output); @@ -532,24 +532,24 @@ float CMonitor::getDefaultScale() { return 1; } -void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool noMouseMove, bool noFocus) { +void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bool noMouseMove, bool noFocus) { if (!pWorkspace) return; if (pWorkspace->m_bIsSpecialWorkspace) { - if (specialWorkspaceID != pWorkspace->m_iID) { + if (activeSpecialWorkspace != pWorkspace) { Debug::log(LOG, "changeworkspace on special, togglespecialworkspace to id {}", pWorkspace->m_iID); g_pKeybindManager->m_mDispatchers["togglespecialworkspace"](pWorkspace->m_szName == "special" ? "" : pWorkspace->m_szName); } return; } - if (pWorkspace->m_iID == activeWorkspace) + if (pWorkspace == activeWorkspace) return; - const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(activeWorkspace); + const auto POLDWORKSPACE = activeWorkspace; - activeWorkspace = pWorkspace->m_iID; + activeWorkspace = pWorkspace; if (!internal) { const auto ANIMTOLEFT = pWorkspace->m_iID > POLDWORKSPACE->m_iID; @@ -558,12 +558,11 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool // move pinned windows for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == POLDWORKSPACE->m_iID && w->m_bPinned) { - w->m_iWorkspaceID = pWorkspace->m_iID; - } + if (w->m_pWorkspace == POLDWORKSPACE && w->m_bPinned) + w->moveToWorkspace(pWorkspace); } - if (!noFocus && !g_pCompositor->m_pLastMonitor->specialWorkspaceID) { + if (!noFocus && !g_pCompositor->m_pLastMonitor->activeSpecialWorkspace) { static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); CWindow* pWindow = pWorkspace->getLastFocusedWindow(); @@ -599,37 +598,33 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool g_pCompositor->updateSuspendedStates(); - if (specialWorkspaceID) { - const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(specialWorkspaceID); - if (PSPECIALWS->m_bHasFullscreenWindow) - g_pCompositor->updateFullscreenFadeOnWorkspace(PSPECIALWS); - } + if (activeSpecialWorkspace) + g_pCompositor->updateFullscreenFadeOnWorkspace(activeSpecialWorkspace); } void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) { changeWorkspace(g_pCompositor->getWorkspaceByID(id), internal, noMouseMove, noFocus); } -void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) { +void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { g_pHyprRenderer->damageMonitor(this); if (!pWorkspace) { // remove special if exists - if (const auto EXISTINGSPECIAL = g_pCompositor->getWorkspaceByID(specialWorkspaceID); EXISTINGSPECIAL) { - EXISTINGSPECIAL->startAnim(false, false); + if (activeSpecialWorkspace) { + activeSpecialWorkspace->startAnim(false, false); g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + szName}); } - specialWorkspaceID = 0; + activeSpecialWorkspace.reset(); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(activeWorkspace); - if (const auto PLAST = PWORKSPACE->getLastFocusedWindow(); PLAST) + if (const auto PLAST = activeWorkspace->getLastFocusedWindow(); PLAST) g_pCompositor->focusWindow(PLAST); else g_pInputManager->refocus(); - g_pCompositor->updateFullscreenFadeOnWorkspace(PWORKSPACE); + g_pCompositor->updateFullscreenFadeOnWorkspace(activeWorkspace); g_pConfigManager->ensureVRR(this); @@ -638,20 +633,18 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) { return; } - if (specialWorkspaceID) { - if (const auto EXISTINGSPECIAL = g_pCompositor->getWorkspaceByID(specialWorkspaceID); EXISTINGSPECIAL) - EXISTINGSPECIAL->startAnim(false, false); - } + if (activeSpecialWorkspace) + activeSpecialWorkspace->startAnim(false, false); bool animate = true; //close if open elsewhere const auto PMONITORWORKSPACEOWNER = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); - if (PMONITORWORKSPACEOWNER->specialWorkspaceID == pWorkspace->m_iID) { - PMONITORWORKSPACEOWNER->specialWorkspaceID = 0; + if (PMONITORWORKSPACEOWNER->activeSpecialWorkspace == pWorkspace) { + PMONITORWORKSPACEOWNER->activeSpecialWorkspace.reset(); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITORWORKSPACEOWNER->ID); g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + PMONITORWORKSPACEOWNER->szName}); - const auto PACTIVEWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITORWORKSPACEOWNER->activeWorkspace); + const auto PACTIVEWORKSPACE = PMONITORWORKSPACEOWNER->activeWorkspace; g_pCompositor->updateFullscreenFadeOnWorkspace(PACTIVEWORKSPACE); animate = false; @@ -659,12 +652,12 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) { // open special pWorkspace->m_iMonitorID = ID; - specialWorkspaceID = pWorkspace->m_iID; + activeSpecialWorkspace = pWorkspace; if (animate) pWorkspace->startAnim(true, true); for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == pWorkspace->m_iID) { + if (w->m_pWorkspace == pWorkspace) { w->m_iMonitorID = ID; w->updateSurfaceScaleTransformDetails(); w->setAnimationsToMove(); @@ -729,6 +722,13 @@ void CMonitor::updateMatrix() { } } +int64_t CMonitor::activeWorkspaceID() { + return activeWorkspace ? activeWorkspace->m_iID : 0; +} +int64_t CMonitor::activeSpecialWorkspaceID() { + return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0; +} + CMonitorState::CMonitorState(CMonitor* owner) { m_pOwner = owner; wlr_output_state_init(&m_state); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 051c5305..909abb44 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -57,10 +57,11 @@ class CMonitor { bool primary = false; - uint64_t ID = -1; - int activeWorkspace = -1; - float setScale = 1; // scale set by cfg - float scale = 1; // real scale + uint64_t ID = -1; + PHLWORKSPACE activeWorkspace = nullptr; + PHLWORKSPACE activeSpecialWorkspace = nullptr; + float setScale = 1; // scale set by cfg + float scale = 1; // real scale std::string szName = ""; std::string szDescription = ""; @@ -119,9 +120,6 @@ class CMonitor { bool frameScheduledWhileBusy = false; } tearingState; - // for the special workspace. 0 means not open. - int specialWorkspaceID = 0; - std::array>, 4> m_aLayerSurfaceLayers; DYNLISTENER(monitorFrame); @@ -142,13 +140,15 @@ class CMonitor { bool isMirror(); bool matchesStaticSelector(const std::string& selector) const; float getDefaultScale(); - void changeWorkspace(CWorkspace* const pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false); + 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(CWorkspace* const pWorkspace); + 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(); bool m_bEnabled = false; bool m_bRenderingInitPassed = false; diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index f1311e42..bad290e6 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -280,16 +280,16 @@ struct SIdleInhibitor { }; struct SSwipeGesture { - CWorkspace* pWorkspaceBegin = nullptr; + PHLWORKSPACE pWorkspaceBegin = nullptr; - double delta = 0; + double delta = 0; - int initialDirection = 0; - float avgSpeed = 0; - int speedPoints = 0; - int touch_id = 0; + int initialDirection = 0; + float avgSpeed = 0; + int speedPoints = 0; + int touch_id = 0; - CMonitor* pMonitor = nullptr; + CMonitor* pMonitor = nullptr; }; struct SIMEKbGrab { diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 93f60e3f..67390010 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -105,7 +105,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) { for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceID == pNode->workspaceID) { + if (m->activeSpecialWorkspaceID() == pNode->workspaceID) { PMONITOR = m.get(); break; } @@ -162,10 +162,10 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for PWINDOW->m_vSize = nodeBox.size(); PWINDOW->m_vPosition = nodeBox.pos(); - const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID); + const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->workspaceID()); - if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && - (NODESONWORKSPACE == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { + if (*PNOGAPSWHENONLY && !PWINDOW->onSpecialWorkspace() && + (NODESONWORKSPACE == 1 || (PWINDOW->m_bIsFullscreen && PWINDOW->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.shadow = false; @@ -229,7 +229,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for calcPos = calcPos + RESERVED.topLeft; calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight); - if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && !PWINDOW->m_bIsFullscreen) { + if (PWINDOW->onSpecialWorkspace() && !PWINDOW->m_bIsFullscreen) { // if special, we adjust the coords a bit static auto PSCALEFACTOR = CConfigValue("dwindle:special_scale_factor"); @@ -278,7 +278,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire overrideDirection = direction; // Populate the node with our window's data - PNODE->workspaceID = pWindow->m_iWorkspaceID; + PNODE->workspaceID = pWindow->workspaceID(); PNODE->pWindow = pWindow; PNODE->isNode = false; PNODE->layout = this; @@ -289,7 +289,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire const auto MONFROMCURSOR = g_pCompositor->getMonitorFromVector(MOUSECOORDS); if (PMONITOR->ID == MONFROMCURSOR->ID && - (PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !*PUSEACTIVE) { + (PNODE->workspaceID == PMONITOR->activeWorkspaceID() || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->activeSpecialWorkspace)) && !*PUSEACTIVE) { OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS)); if (!OPENINGON && g_pCompositor->isPointOnReservedArea(MOUSECOORDS, PMONITOR)) @@ -297,7 +297,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire } else if (*PUSEACTIVE) { if (g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && - g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) { + g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace && g_pCompositor->m_pLastWindow->m_bIsMapped) { OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow); } else { OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS)); @@ -307,7 +307,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS); } else - OPENINGON = getFirstNodeOnWorkspace(pWindow->m_iWorkspaceID); + OPENINGON = getFirstNodeOnWorkspace(pWindow->workspaceID()); Debug::log(LOG, "OPENINGON: {}, Monitor: {}", OPENINGON, PMONITOR->ID); @@ -551,40 +551,35 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) { void CHyprDwindleLayout::recalculateMonitor(const int& monid) { const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); - if (!PMONITOR) + if (!PMONITOR || !PMONITOR->activeWorkspace) return; // ??? g_pHyprRenderer->damageMonitor(PMONITOR); - if (PMONITOR->specialWorkspaceID) - calculateWorkspace(PMONITOR->specialWorkspaceID); + if (PMONITOR->activeSpecialWorkspace) + calculateWorkspace(PMONITOR->activeSpecialWorkspace); calculateWorkspace(PMONITOR->activeWorkspace); } -void CHyprDwindleLayout::calculateWorkspace(const int& ws) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); - - if (!PWORKSPACE) - return; - - const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); +void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); if (!PMONITOR) return; - if (PWORKSPACE->m_bHasFullscreenWindow) { + if (pWorkspace->m_bHasFullscreenWindow) { // massive hack from the fullscreen func - const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); + const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(pWorkspace->m_iID); - if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) { + if (pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL) { PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; - } else if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { + } else if (pWorkspace->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { SDwindleNodeData fakeNode; fakeNode.pWindow = PFULLWINDOW; fakeNode.box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; - fakeNode.workspaceID = PWORKSPACE->m_iID; + fakeNode.workspaceID = pWorkspace->m_iID; PFULLWINDOW->m_vPosition = fakeNode.box.pos(); PFULLWINDOW->m_vSize = fakeNode.box.size(); fakeNode.ignoreFullscreenChecks = true; @@ -596,7 +591,7 @@ void CHyprDwindleLayout::calculateWorkspace(const int& ws) { return; } - const auto TOPNODE = getMasterNodeOnWorkspace(ws); + const auto TOPNODE = getMasterNodeOnWorkspace(pWorkspace->m_iID); if (TOPNODE) { TOPNODE->box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; @@ -813,7 +808,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree return; // ignore const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow && on) { // if the window wants to be fullscreen but there already is one, @@ -868,7 +863,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree SDwindleNodeData fakeNode; fakeNode.pWindow = pWindow; fakeNode.box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight}; - fakeNode.workspaceID = pWindow->m_iWorkspaceID; + fakeNode.workspaceID = pWindow->workspaceID(); pWindow->m_vPosition = fakeNode.box.pos(); pWindow->m_vSize = fakeNode.box.size(); fakeNode.ignoreFullscreenChecks = true; @@ -981,7 +976,7 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { if (PNODE->workspaceID != PNODE2->workspaceID) { std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID); - std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); + std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace); } pWindow->setAnimationsToMove(); @@ -1137,7 +1132,7 @@ Vector2D CHyprDwindleLayout::predictSizeForNewWindowTiled() { CWindow* candidate = g_pCompositor->m_pLastWindow; if (!candidate) - candidate = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace); + candidate = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID); // create a fake node SDwindleNodeData node; diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index b8c752f4..30c6e74a 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -78,7 +78,7 @@ class CHyprDwindleLayout : public IHyprLayout { int getNodesOnWorkspace(const int&); void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); - void calculateWorkspace(const int& ws); + void calculateWorkspace(const PHLWORKSPACE& pWorkspace); SDwindleNodeData* getNodeFromWindow(CWindow*); SDwindleNodeData* getFirstNodeOnWorkspace(const int&); SDwindleNodeData* getClosestNodeOnWorkspace(const int&, const Vector2D&); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 1570fd73..3648faee 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -189,7 +189,7 @@ void IHyprLayout::onBeginDragWindow() { g_pCompositor->setWindowFullscreen(DRAGGINGWINDOW, false, FULLSCREEN_FULL); } - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(DRAGGINGWINDOW->m_iWorkspaceID); + const auto PWORKSPACE = DRAGGINGWINDOW->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow && (!DRAGGINGWINDOW->m_bCreatedOverFullscreen || !DRAGGINGWINDOW->m_bIsFloating)) { Debug::log(LOG, "Rejecting drag on a fullscreen workspace. (window under fullscreen)"); @@ -329,7 +329,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { static auto TIMER = std::chrono::high_resolution_clock::now(), MSTIMER = TIMER; - const auto SPECIAL = g_pCompositor->isWorkspaceSpecial(DRAGGINGWINDOW->m_iWorkspaceID); + const auto SPECIAL = DRAGGINGWINDOW->onSpecialWorkspace(); const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y); const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y); @@ -479,10 +479,10 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) { if (!TILED) { const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f); pWindow->m_iMonitorID = PNEWMON->ID; - pWindow->moveToWorkspace(PNEWMON->specialWorkspaceID != 0 ? PNEWMON->specialWorkspaceID : PNEWMON->activeWorkspace); + pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace); pWindow->updateGroupOutputs(); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNEWMON->specialWorkspaceID != 0 ? PNEWMON->specialWorkspaceID : PNEWMON->activeWorkspace); + const auto PWORKSPACE = PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow) g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false); @@ -569,17 +569,17 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { if (!pWindow) return nullptr; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; // first of all, if this is a fullscreen workspace, if (PWORKSPACE->m_bHasFullscreenWindow) - return g_pCompositor->getFullscreenWindowOnWorkspace(pWindow->m_iWorkspaceID); + return g_pCompositor->getFullscreenWindowOnWorkspace(pWindow->workspaceID()); if (pWindow->m_bIsFloating) { // find whether there is a floating window below this one for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && + if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_pWorkspace == pWindow->m_pWorkspace && !w->m_bX11ShouldntFocus && !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) { if (VECINRECT((pWindow->m_vSize / 2.f + pWindow->m_vPosition), w->m_vPosition.x, w->m_vPosition.y, w->m_vPosition.x + w->m_vSize.x, w->m_vPosition.y + w->m_vSize.y)) { @@ -589,7 +589,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { } // let's try the last tiled window. - if (m_pLastTiledWindow && m_pLastTiledWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID) + if (m_pLastTiledWindow && m_pLastTiledWindow->m_pWorkspace == pWindow->m_pWorkspace) return m_pLastTiledWindow; // if we don't, let's try to find any window that is in the middle @@ -599,7 +599,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { // if not, floating window for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && + if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_pWorkspace == pWindow->m_pWorkspace && !w->m_bX11ShouldntFocus && !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) return w.get(); } @@ -612,10 +612,10 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { auto pWindowCandidate = g_pCompositor->vectorToWindowUnified(pWindow->middle(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING); if (!pWindowCandidate) - pWindowCandidate = g_pCompositor->getTopLeftWindowOnWorkspace(pWindow->m_iWorkspaceID); + pWindowCandidate = g_pCompositor->getTopLeftWindowOnWorkspace(pWindow->workspaceID()); if (!pWindowCandidate) - pWindowCandidate = g_pCompositor->getFirstWindowOnWorkspace(pWindow->m_iWorkspaceID); + pWindowCandidate = g_pCompositor->getFirstWindowOnWorkspace(pWindow->workspaceID()); if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_bIsMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_bX11ShouldntFocus || pWindowCandidate->m_iX11Type == 2 || pWindowCandidate->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 375840fb..2066ca76 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -90,7 +90,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc const auto PNODE = *PNEWTOP ? &m_lMasterNodesData.emplace_front() : &m_lMasterNodesData.emplace_back(); - PNODE->workspaceID = pWindow->m_iWorkspaceID; + PNODE->workspaceID = pWindow->workspaceID(); PNODE->pWindow = pWindow; static auto PNEWISMASTER = CConfigValue("master:new_is_master"); @@ -99,9 +99,9 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc static auto PMFACT = CConfigValue("master:mfact"); float lastSplitPercent = *PMFACT; - auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID ? + auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace ? getNodeFromWindow(g_pCompositor->m_pLastWindow) : - getMasterNodeOnWorkspace(pWindow->m_iWorkspaceID); + getMasterNodeOnWorkspace(pWindow->workspaceID()); const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); @@ -133,7 +133,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc pWindow->applyGroupRules(); static auto PDROPATCURSOR = CConfigValue("master:drop_at_cursor"); - const auto PWORKSPACEDATA = getMasterWorkspaceData(pWindow->m_iWorkspaceID); + const auto PWORKSPACEDATA = getMasterWorkspaceData(pWindow->workspaceID()); eOrientation orientation = PWORKSPACEDATA->orientation; const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE); @@ -142,7 +142,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc if (*PDROPATCURSOR && g_pInputManager->dragMode == MBIND_MOVE) { if (WINDOWSONWORKSPACE > 2) { for (auto it = m_lMasterNodesData.begin(); it != m_lMasterNodesData.end(); ++it) { - if (it->workspaceID != pWindow->m_iWorkspaceID) + if (it->workspaceID != pWindow->workspaceID()) continue; const CBox box = it->pWindow->getWindowIdealBoundingBoxIgnoreReserved(); if (box.containsPoint(MOUSECOORDS)) { @@ -286,41 +286,36 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) { void CHyprMasterLayout::recalculateMonitor(const int& monid) { const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); - if (!PMONITOR) + if (!PMONITOR || !PMONITOR->activeWorkspace) return; g_pHyprRenderer->damageMonitor(PMONITOR); - if (PMONITOR->specialWorkspaceID) - calculateWorkspace(PMONITOR->specialWorkspaceID); + if (PMONITOR->activeSpecialWorkspace) + calculateWorkspace(PMONITOR->activeSpecialWorkspace); calculateWorkspace(PMONITOR->activeWorkspace); } -void CHyprMasterLayout::calculateWorkspace(const int& ws) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); - - if (!PWORKSPACE) - return; - - const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); +void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); if (!PMONITOR) return; - if (PWORKSPACE->m_bHasFullscreenWindow) { + if (pWorkspace->m_bHasFullscreenWindow) { // massive hack from the fullscreen func - const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); + const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(pWorkspace->m_iID); - if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) { + if (pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL) { PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; - } else if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { + } else if (pWorkspace->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { SMasterNodeData fakeNode; fakeNode.pWindow = PFULLWINDOW; fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; - fakeNode.workspaceID = PWORKSPACE->m_iID; + fakeNode.workspaceID = pWorkspace->m_iID; PFULLWINDOW->m_vPosition = fakeNode.position; PFULLWINDOW->m_vSize = fakeNode.size; fakeNode.ignoreFullscreenChecks = true; @@ -332,14 +327,14 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { return; } - const auto PWORKSPACEDATA = getMasterWorkspaceData(ws); - const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID); + const auto PWORKSPACEDATA = getMasterWorkspaceData(pWorkspace->m_iID); + const auto PMASTERNODE = getMasterNodeOnWorkspace(pWorkspace->m_iID); if (!PMASTERNODE) return; // dynamic workspace rules - const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(ws)); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(pWorkspace); std::string orientationForWs; for (auto& wsRule : WORKSPACERULES) { @@ -363,8 +358,8 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); - const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID); - const auto WINDOWS = getNodesOnWorkspace(PWORKSPACE->m_iID); + const auto MASTERS = getMastersOnWorkspace(pWorkspace->m_iID); + const auto WINDOWS = getNodesOnWorkspace(pWorkspace->m_iID); const auto STACKWINDOWS = WINDOWS - MASTERS; const auto WSSIZE = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; const auto WSPOS = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; @@ -387,7 +382,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { // check the total width and height so that later // if larger/smaller than screen size them down/up for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID == PWORKSPACE->m_iID) { + if (nd.workspaceID == pWorkspace->m_iID) { if (nd.isMaster) masterAccumulatedSize += totalSize / MASTERS * nd.percSize; else @@ -414,7 +409,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { nextY = WSSIZE.y - HEIGHT; for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || !nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || !nd.isMaster) continue; float WIDTH = mastersLeft > 1 ? widthLeft / mastersLeft * nd.percSize : widthLeft; @@ -451,7 +446,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { } for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || !nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || !nd.isMaster) continue; float HEIGHT = mastersLeft > 1 ? heightLeft / mastersLeft * nd.percSize : heightLeft; @@ -488,7 +483,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { nextY = PMASTERNODE->size.y; for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster) continue; float WIDTH = slavesLeft > 1 ? widthLeft / slavesLeft * nd.percSize : widthLeft; @@ -518,7 +513,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { nextX = PMASTERNODE->size.x; for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster) continue; float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft; @@ -558,7 +553,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { float slaveAccumulatedHeightR = 0; if (*PSMARTRESIZING) { for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster) continue; if (onRight) { @@ -572,7 +567,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { } for (auto& nd : m_lMasterNodesData) { - if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) + if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster) continue; if (onRight) { @@ -625,7 +620,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) { for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceID == pNode->workspaceID) { + if (m->activeSpecialWorkspaceID() == pNode->workspaceID) { PMONITOR = m.get(); break; } @@ -648,7 +643,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { const auto PWINDOW = pNode->pWindow; // get specific gaps and rules for this workspace, // if user specified them in config - const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)); + const auto WORKSPACERULES = g_pConfigManager->getWorkspaceRulesFor(PWINDOW->m_pWorkspace); if (PWINDOW->m_bIsFullscreen && !pNode->ignoreFullscreenChecks) return; @@ -679,9 +674,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { PWINDOW->m_vSize = pNode->size; PWINDOW->m_vPosition = pNode->position; - if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && - (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 || - (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { + if (*PNOGAPSWHENONLY && !PWINDOW->onSpecialWorkspace() && + (getNodesOnWorkspace(PWINDOW->workspaceID()) == 1 || (PWINDOW->m_bIsFullscreen && PWINDOW->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.shadow = false; @@ -721,7 +715,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { calcPos = calcPos + RESERVED.topLeft; calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight); - if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && !PWINDOW->m_bIsFullscreen) { + if (PWINDOW->onSpecialWorkspace() && !PWINDOW->m_bIsFullscreen) { static auto PSCALEFACTOR = CConfigValue("master:special_scale_factor"); CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR}; @@ -772,7 +766,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne } const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); - const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->workspaceID()); static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); @@ -793,7 +787,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne const auto WINDOWS = getNodesOnWorkspace(PNODE->workspaceID); const auto STACKWINDOWS = WINDOWS - MASTERS; - if (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 && !centered) + if (getNodesOnWorkspace(PWINDOW->workspaceID()) == 1 && !centered) return; m_bForceWarps = true; @@ -815,7 +809,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne default: UNREACHABLE(); } - const auto workspaceIdForResizing = PMONITOR->specialWorkspaceID == 0 ? PMONITOR->activeWorkspace : PMONITOR->specialWorkspaceID; + const auto workspaceIdForResizing = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeWorkspaceID() : PMONITOR->activeSpecialWorkspaceID(); for (auto& n : m_lMasterNodesData) { if (n.isMaster && n.workspaceID == workspaceIdForResizing) n.percMaster = std::clamp(n.percMaster + delta, 0.05, 0.95); @@ -908,7 +902,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen return; // ignore const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow && on) { // if the window wants to be fullscreen but there already is one, @@ -964,7 +958,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen fakeNode.pWindow = pWindow; fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; - fakeNode.workspaceID = pWindow->m_iWorkspaceID; + fakeNode.workspaceID = pWindow->workspaceID(); pWindow->m_vPosition = fakeNode.position; pWindow->m_vSize = fakeNode.size; fakeNode.ignoreFullscreenChecks = true; @@ -1010,10 +1004,10 @@ void CHyprMasterLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) { pWindow->setAnimationsToMove(); - if (pWindow->m_iWorkspaceID != PWINDOW2->m_iWorkspaceID) { + if (pWindow->m_pWorkspace != PWINDOW2->m_pWorkspace) { // if different monitors, send to monitor onWindowRemovedTiling(pWindow); - pWindow->moveToWorkspace(PWINDOW2->m_iWorkspaceID); + pWindow->moveToWorkspace(PWINDOW2->m_pWorkspace); pWindow->m_iMonitorID = PWINDOW2->m_iMonitorID; const auto pMonitor = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); g_pCompositor->setActiveMonitor(pMonitor); @@ -1035,7 +1029,7 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { if (PNODE->workspaceID != PNODE2->workspaceID) { std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID); - std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); + std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace); } // massive hack: just swap window pointers, lol @@ -1061,7 +1055,7 @@ void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exac if (!PNODE) return; - const auto PMASTER = getMasterNodeOnWorkspace(pWindow->m_iWorkspaceID); + const auto PMASTER = getMasterNodeOnWorkspace(pWindow->workspaceID()); float newRatio = exact ? ratio : PMASTER->percMaster + ratio; PMASTER->percMaster = std::clamp(newRatio, 0.05f, 0.95f); @@ -1097,7 +1091,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri return; if (header.pWindow->m_bIsFullscreen) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + const auto PWORKSPACE = header.pWindow->m_pWorkspace; const auto FSMODE = PWORKSPACE->m_efFullscreenMode; static auto INHERITFULLSCREEN = CConfigValue("master:inherit_fullscreen"); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); @@ -1137,7 +1131,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!isWindowTiled(PWINDOW)) return 0; - const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); + const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->workspaceID()); if (!PMASTER) return 0; @@ -1175,7 +1169,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); + const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->workspaceID()); if (!PMASTER) return 0; @@ -1252,8 +1246,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PNODE = getNodeFromWindow(header.pWindow); - const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID); - const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID); + const auto WINDOWS = getNodesOnWorkspace(header.pWindow->workspaceID()); + const auto MASTERS = getMastersOnWorkspace(header.pWindow->workspaceID()); static auto SMALLSPLIT = CConfigValue("master:allow_small_split"); if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0) @@ -1263,7 +1257,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PNODE || PNODE->isMaster) { // first non-master node for (auto& n : m_lMasterNodesData) { - if (n.workspaceID == header.pWindow->m_iWorkspaceID && !n.isMaster) { + if (n.workspaceID == header.pWindow->workspaceID() && !n.isMaster) { n.isMaster = true; break; } @@ -1284,8 +1278,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PNODE = getNodeFromWindow(header.pWindow); - const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID); - const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID); + const auto WINDOWS = getNodesOnWorkspace(header.pWindow->workspaceID()); + const auto MASTERS = getMastersOnWorkspace(header.pWindow->workspaceID()); if (WINDOWS < 2 || MASTERS < 2) return 0; @@ -1295,7 +1289,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PNODE || !PNODE->isMaster) { // first non-master node for (auto& nd : m_lMasterNodesData | std::views::reverse) { - if (nd.workspaceID == header.pWindow->m_iWorkspaceID && nd.isMaster) { + if (nd.workspaceID == header.pWindow->workspaceID() && nd.isMaster) { nd.isMaster = false; break; } @@ -1313,7 +1307,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); - const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->workspaceID()); if (command == "orientationleft") PWORKSPACEDATA->orientation = ORIENTATION_LEFT; @@ -1421,7 +1415,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); - const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->workspaceID()); int nextOrPrev = 0; for (size_t i = 0; i < cycle.size(); ++i) { @@ -1479,19 +1473,19 @@ Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() { if (!g_pCompositor->m_pLastMonitor) return {}; - const int NODES = getNodesOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace); + const int NODES = getNodesOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID); if (NODES <= 0) return g_pCompositor->m_pLastMonitor->vecSize; - const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID); if (!MASTER) // wtf return {}; if (*PNEWISMASTER) { return MASTER->size; } else { - const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID); // TODO: make this better return {g_pCompositor->m_pLastMonitor->vecSize.x - MASTER->size.x, g_pCompositor->m_pLastMonitor->vecSize.y / (SLAVES + 1)}; diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 1e48b5dd..922d7bb6 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -84,7 +84,7 @@ class CHyprMasterLayout : public IHyprLayout { SMasterNodeData* getNodeFromWindow(CWindow*); SMasterNodeData* getMasterNodeOnWorkspace(const int&); SMasterWorkspaceData* getMasterWorkspaceData(const int&); - void calculateWorkspace(const int&); + void calculateWorkspace(PHLWORKSPACE); CWindow* getNextWindow(CWindow*, bool); int getMastersOnWorkspace(const int&); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index ab81841c..a9a72941 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -79,11 +79,11 @@ void CAnimationManager::tick() { const float SPENT = av->getPercent(); // window stuff - const auto PWINDOW = (CWindow*)av->m_pWindow; - const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace; - const auto PLAYER = (SLayerSurface*)av->m_pLayer; - CMonitor* PMONITOR = nullptr; - bool animationsDisabled = animGlobalDisabled; + const auto PWINDOW = (CWindow*)av->m_pWindow; + PHLWORKSPACE PWORKSPACE = av->m_pWorkspace.lock(); + const auto PLAYER = (SLayerSurface*)av->m_pLayer; + CMonitor* PMONITOR = nullptr; + bool animationsDisabled = animGlobalDisabled; if (PWINDOW) { if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) { @@ -111,7 +111,7 @@ void CAnimationManager::tick() { // TODO: just make this into a damn callback already vax... for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_iWorkspaceID != PWORKSPACE->m_iID) + if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != PWORKSPACE) continue; if (w->m_bIsFloating && !w->m_bPinned) { @@ -129,7 +129,7 @@ void CAnimationManager::tick() { // damage any workspace window that is on any monitor for (auto& w : g_pCompositor->m_vWindows) { - if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID || w->m_bPinned) + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_pWorkspace != PWORKSPACE || w->m_bPinned) continue; g_pHyprRenderer->damageWindow(w.get()); @@ -146,7 +146,7 @@ void CAnimationManager::tick() { animationsDisabled = animationsDisabled || PLAYER->noAnimations; } - const bool VISIBLE = PWINDOW ? g_pCompositor->isWorkspaceVisible(PWINDOW->m_iWorkspaceID) : true; + const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID()) : true; // beziers are with a switch unforto // TODO: maybe do something cleaner @@ -212,7 +212,7 @@ void CAnimationManager::tick() { g_pHyprRenderer->damageWindow(PWINDOW); } else if (PWORKSPACE) { for (auto& w : g_pCompositor->m_vWindows) { - if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID) + if (!g_pCompositor->windowValidMapped(w.get()) || w->m_pWorkspace != PWORKSPACE) continue; w->updateWindowDecos(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 03887514..df27a8cf 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -225,13 +225,13 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) { return false; } - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); - const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace); + const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; + const auto PNEWMAINWORKSPACE = monitor->activeWorkspace; g_pInputManager->unconstrainMouse(); PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE); - const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE; + const auto PNEWWORKSPACE = monitor->activeSpecialWorkspace ? monitor->activeSpecialWorkspace : PNEWMAINWORKSPACE; const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow(); if (PNEWWINDOW) { @@ -259,8 +259,8 @@ void CKeybindManager::switchToWindow(CWindow* PWINDOWTOCHANGETO) { // remove constraints g_pInputManager->unconstrainMouse(); - if (PLASTWINDOW && PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID); + if (PLASTWINDOW && PLASTWINDOW->m_pWorkspace == PWINDOWTOCHANGETO->m_pWorkspace && PLASTWINDOW->m_bIsFullscreen) { + const auto PWORKSPACE = PLASTWINDOW->m_pWorkspace; const auto FSMODE = PWORKSPACE->m_efFullscreenMode; if (!PWINDOWTOCHANGETO->m_bPinned) @@ -874,11 +874,11 @@ void toggleActiveFloatingCore(std::string args, std::optional floatState) curr = curr->m_sGroupData.pNextWindow; } - g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); + g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID()); } else { PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; - g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); + g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID()); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); } @@ -927,7 +927,7 @@ void CKeybindManager::changeworkspace(std::string args) { if (!PMONITOR) return; - const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const auto PCURRENTWORKSPACE = PMONITOR->activeWorkspace; const bool EXPLICITPREVIOUS = args.starts_with("previous"); if (args.starts_with("previous")) { @@ -1044,14 +1044,14 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { return; } - if (WORKSPACEID == PWINDOW->m_iWorkspaceID) { + if (WORKSPACEID == PWINDOW->workspaceID()) { Debug::log(LOG, "Not moving to workspace because it didn't change."); return; } auto pWorkspace = g_pCompositor->getWorkspaceByID(WORKSPACEID); CMonitor* pMonitor = nullptr; - const auto POLDWS = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); + const auto POLDWS = PWINDOW->m_pWorkspace; static auto PALLOWWORKSPACECYCLES = CConfigValue("binds:allow_workspace_cycles"); g_pHyprRenderer->damageWindow(PWINDOW); @@ -1106,7 +1106,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { return; } - if (WORKSPACEID == PWINDOW->m_iWorkspaceID) + if (WORKSPACEID == PWINDOW->workspaceID()) return; g_pHyprRenderer->damageWindow(PWINDOW); @@ -1220,7 +1220,7 @@ void CKeybindManager::moveActiveTo(std::string args) { if (!PNEWMONITOR) return; - moveActiveToWorkspace(std::to_string(PNEWMONITOR->activeWorkspace)); + moveActiveToWorkspace(PNEWMONITOR->activeWorkspace->getConfigName()); return; } @@ -1265,7 +1265,7 @@ void CKeybindManager::moveActiveTo(std::string args) { if (!PMONITORTOCHANGETO) return; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITORTOCHANGETO->activeWorkspace); + const auto PWORKSPACE = PMONITORTOCHANGETO->activeWorkspace; moveActiveToWorkspace(PWORKSPACE->getConfigName()); } @@ -1324,7 +1324,7 @@ void CKeybindManager::toggleSplit(std::string args) { if (!header.pWindow) return; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + const auto PWORKSPACE = header.pWindow->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow) return; @@ -1339,7 +1339,7 @@ void CKeybindManager::swapSplit(std::string args) { if (!header.pWindow) return; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + const auto PWORKSPACE = header.pWindow->m_pWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow) return; @@ -1447,7 +1447,7 @@ void CKeybindManager::moveCursor(std::string args) { void CKeybindManager::workspaceOpt(std::string args) { // current workspace - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; if (!PWORKSPACE) return; // ???? @@ -1457,7 +1457,7 @@ void CKeybindManager::workspaceOpt(std::string args) { // apply for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->m_iWorkspaceID != PWORKSPACE->m_iID) + if (!w->m_bIsMapped || w->m_pWorkspace != PWORKSPACE) continue; w->m_bIsPseudotiled = PWORKSPACE->m_bDefaultPseudo; @@ -1472,7 +1472,7 @@ void CKeybindManager::workspaceOpt(std::string args) { ptrs.push_back(w.get()); for (auto& w : ptrs) { - if (!w->m_bIsMapped || w->m_iWorkspaceID != PWORKSPACE->m_iID || w->isHidden()) + if (!w->m_bIsMapped || w->m_pWorkspace != PWORKSPACE || w->isHidden()) continue; if (!w->m_bRequestsFloat && w->m_bIsFloating != PWORKSPACE->m_bDefaultFloating) { @@ -1526,7 +1526,7 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) { } // get the current workspace - const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto PCURRENTWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; if (!PCURRENTWORKSPACE) { Debug::log(ERR, "moveCurrentWorkspaceToMonitor invalid workspace!"); @@ -1595,7 +1595,7 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { static auto PBACKANDFORTH = CConfigValue("binds:workspace_back_and_forth"); - if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspace == workspaceID && pWorkspace->m_sPrevWorkspace.iID != -1) { + if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && pWorkspace->m_sPrevWorkspace.iID != -1) { const int PREVWORKSPACEID = pWorkspace->m_sPrevWorkspace.iID; const auto PREVWORKSPACENAME = pWorkspace->m_sPrevWorkspace.name; // Workspace to focus is previous workspace @@ -1612,7 +1612,7 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!"); return; } - if (POLDMONITOR->activeWorkspace == workspaceID) { + if (POLDMONITOR->activeWorkspaceID() == workspaceID) { g_pCompositor->swapActiveWorkspaces(POLDMONITOR, PCURRMONITOR); return; } else { @@ -1634,10 +1634,10 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) { bool requestedWorkspaceIsAlreadyOpen = false; const auto PMONITOR = g_pCompositor->m_pLastMonitor; - int specialOpenOnMonitor = PMONITOR->specialWorkspaceID; + int specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceID == workspaceID) { + if (m->activeSpecialWorkspaceID() == workspaceID) { requestedWorkspaceIsAlreadyOpen = true; break; } @@ -1750,8 +1750,8 @@ void CKeybindManager::circleNext(std::string arg) { if (!g_pCompositor->m_pLastWindow) { // if we have a clear focus, find the first window and get the next focusable. - if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace) > 0) { - const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace); + if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()) > 0) { + const auto PWINDOW = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspaceID()); switchToWindow(PWINDOW); } @@ -1781,13 +1781,13 @@ void CKeybindManager::focusWindow(std::string regexp) { Debug::log(LOG, "Focusing to window name: {}", PWINDOW->m_szTitle); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACE = PWINDOW->m_pWorkspace; if (!PWORKSPACE) { Debug::log(ERR, "BUG THIS: null workspace in focusWindow"); return; } - if (g_pCompositor->m_pLastMonitor->activeWorkspace != PWINDOW->m_iWorkspaceID) { + if (g_pCompositor->m_pLastMonitor->activeWorkspace != PWINDOW->m_pWorkspace) { Debug::log(LOG, "Fake executing workspace to move focus"); changeworkspace(PWORKSPACE->getConfigName()); } @@ -1975,7 +1975,7 @@ void CKeybindManager::swapnext(std::string arg) { const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; const auto PLASTCYCLED = g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow->m_pLastCycledWindow) && - g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID ? + g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_pWorkspace == PLASTWINDOW->m_pWorkspace ? g_pCompositor->m_pLastWindow->m_pLastCycledWindow : nullptr; @@ -2029,13 +2029,13 @@ void CKeybindManager::pinActive(std::string args) { if (!PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) return; - PWINDOW->m_bPinned = !PWINDOW->m_bPinned; - PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace; + PWINDOW->m_bPinned = !PWINDOW->m_bPinned; + PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace; PWINDOW->updateDynamicRules(); g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); + const auto PWORKSPACE = PWINDOW->m_pWorkspace; PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS); diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index e37a08f7..325229e7 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -74,7 +74,7 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) { } if (!pWindow->m_bPinned) - g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow; + pWindow->m_pWorkspace->m_pLastFocusedWindow = pWindow; } void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, CBox* pbox) { diff --git a/src/managers/input/IdleInhibitor.cpp b/src/managers/input/IdleInhibitor.cpp index 46e4fea1..12d768f5 100644 --- a/src/managers/input/IdleInhibitor.cpp +++ b/src/managers/input/IdleInhibitor.cpp @@ -65,7 +65,7 @@ void CInputManager::recheckIdleInhibitorStatus() { return; } - if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->m_iWorkspaceID)) { + if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->workspaceID())) { g_pCompositor->setIdleActivityInhibit(false); return; } diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 4e2bf709..a37cfbe5 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -230,7 +230,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface); // then, we check if the workspace doesnt have a fullscreen window - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const auto PWORKSPACE = PMONITOR->activeWorkspace; if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) { pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); @@ -244,7 +244,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (PWINDOWIDEAL && ((PWINDOWIDEAL->m_bIsFloating && PWINDOWIDEAL->m_bCreatedOverFullscreen) /* floating over fullscreen */ - || (PMONITOR->specialWorkspaceID == PWINDOWIDEAL->m_iWorkspaceID) /* on an open special workspace */)) + || (PMONITOR->activeSpecialWorkspace == PWINDOWIDEAL->m_pWorkspace) /* on an open special workspace */)) pFoundWindow = PWINDOWIDEAL; if (!pFoundWindow->m_bIsX11) { @@ -260,10 +260,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (!foundSurface) { if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { - if (PMONITOR->specialWorkspaceID) { + if (PMONITOR->activeSpecialWorkspace) { pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING); - if (pFoundWindow && !g_pCompositor->isWorkspaceSpecial(pFoundWindow->m_iWorkspaceID)) { + if (pFoundWindow && !pFoundWindow->onSpecialWorkspace()) { pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); } } else { diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 5c3b7c28..47a6f5bd 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -24,7 +24,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) { } void CInputManager::beginWorkspaceSwipe() { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); + const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; Debug::log(LOG, "Starting a swipe from {}", PWORKSPACE->m_szName); @@ -80,14 +80,14 @@ void CInputManager::endWorkspaceSwipe() { workspaceIDRight = maxWorkspace + 1; } - auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER - auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER + auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER + auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER - const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.value(); - const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP; - const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; + const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.value(); + const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP; + const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; - CWorkspace* pSwitchedTo = nullptr; + PHLWORKSPACE pSwitchedTo = nullptr; if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) { diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 92f8316d..6fbda869 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -37,7 +37,7 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { return; // TODO: Don't swipe if you touched a floating window. } else if (*PSWIPETOUCH && (!m_pFoundLSToFocus || m_pFoundLSToFocus->layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const auto PWORKSPACE = PMONITOR->activeWorkspace; const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); // TODO: support no_gaps_when_only? diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f5cf2624..0628838c 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -224,7 +224,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { if (w->popupsCount() > 0 && *PBLURPOPUPS) return true; - if (!w->m_bIsFloating && *POPTIM && !g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (!w->m_bIsFloating && *POPTIM && !w->onSpecialWorkspace()) continue; if (w->m_sAdditionalConfigData.forceNoBlur.toUnderlying() == true || w->m_sAdditionalConfigData.xray.toUnderlying() == true) @@ -1342,7 +1342,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { const auto PSURFACE = pWindow->m_pWLSurface.wlr(); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; const float A = pWindow->m_fAlpha.value() * pWindow->m_fActiveInactiveAlpha.value() * PWORKSPACE->m_fAlpha.value(); if (A >= 1.f) { @@ -1364,7 +1364,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { bool hasWindows = false; for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || *PBLURXRAY)) { + if (w->m_pWorkspace == pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || *PBLURXRAY)) { // check if window is valid if (!windowShouldBeBlurred(w.get())) @@ -1456,7 +1456,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWind if (pLayer && pLayer->xray == 0) return false; - if ((*PBLURNEWOPTIMIZE && pWindow && !pWindow->m_bIsFloating && !g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) || *PBLURXRAY) + if ((*PBLURNEWOPTIMIZE && pWindow && !pWindow->m_bIsFloating && !pWindow->onSpecialWorkspace()) || *PBLURXRAY) return true; if ((pLayer && pLayer->xray == 1) || (pWindow && pWindow->m_sAdditionalConfigData.xray.toUnderlying() == 1)) diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index b18e9108..65f3e6ba 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -91,7 +91,7 @@ struct SMonitorRenderData { struct SCurrentRenderData { CMonitor* pMonitor = nullptr; - CWorkspace* pWorkspace = nullptr; + PHLWORKSPACE pWorkspace = nullptr; float projection[9]; float savedProjection[9]; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index aecd9524..cc682fad 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -217,13 +217,13 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr())) return false; - if (pWindow->m_iWorkspaceID == -1) + if (!pWindow->m_pWorkspace && !pWindow->m_bFadingOut) return false; if (pWindow->m_bPinned) return true; - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWINDOWWORKSPACE = pWindow->m_pWorkspace; if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_iMonitorID == pMonitor->ID) { if (PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) return true; @@ -233,21 +233,21 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { pWindow->m_fAlpha.value() == 0) return false; - if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID)) + if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) return false; } if (pWindow->m_iMonitorID == pMonitor->ID) return true; - if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_iMonitorID != pMonitor->ID) + if (!g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_iMonitorID != pMonitor->ID) return false; // if not, check if it maybe is active on a different monitor. - if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) + if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors - if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID) + if (pMonitor->activeSpecialWorkspace == pWindow->m_pWorkspace) return true; // if window is tiled and it's flying in, don't render on other mons (for slide) @@ -277,29 +277,29 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) { if (!g_pCompositor->windowValidMapped(pWindow)) return false; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; - if (pWindow->m_iWorkspaceID == -1) + if (!pWindow->m_pWorkspace) return false; if (pWindow->m_bPinned || PWORKSPACE->m_bForceRendering) return true; - if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID)) + if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) return true; for (auto& m : g_pCompositor->m_vMonitors) { if (PWORKSPACE && PWORKSPACE->m_iMonitorID == m->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())) return true; - if (m->specialWorkspaceID && g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) + if (m->activeSpecialWorkspace && pWindow->onSpecialWorkspace()) return true; } return false; } -void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) { +void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* time) { CWindow* pWorkspaceWindow = nullptr; EMIT_HOOK_EVENT("render", RENDER_PRE_WINDOWS); @@ -315,7 +315,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (w->m_bIsFullscreen || w->m_bIsFloating) continue; - if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL); @@ -332,7 +332,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (w->m_bIsFullscreen || !w->m_bIsFloating) continue; - if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID) @@ -343,9 +343,9 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // TODO: this pass sucks for (auto& w : g_pCompositor->m_vWindows) { - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID); + const auto PWORKSPACE = w->m_pWorkspace; - if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen) { + if (w->m_pWorkspace != pWorkspace || !w->m_bIsFullscreen) { if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering))) continue; @@ -356,13 +356,13 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (!w->m_bIsFullscreen) continue; - if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (shouldRenderWindow(w.get(), pMonitor)) renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); - if (w->m_iWorkspaceID != pWorkspace->m_iID) + if (w->m_pWorkspace != pWorkspace) continue; pWorkspaceWindow = w.get(); @@ -376,10 +376,10 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // then render windows over fullscreen. for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->m_bIsFullscreen) + if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->m_bIsFullscreen) continue; - if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID) @@ -389,7 +389,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp } } -void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) { +void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* time) { CWindow* lastWindow = nullptr; EMIT_HOOK_EVENT("render", RENDER_PRE_WINDOWS); @@ -405,7 +405,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (!shouldRenderWindow(w.get(), pMonitor)) continue; - if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; // render active window after all others of this pass @@ -429,7 +429,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (w->m_bIsFloating) continue; // floating are in the second pass - if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (!shouldRenderWindow(w.get(), pMonitor)) @@ -450,7 +450,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (!shouldRenderWindow(w.get(), pMonitor)) continue; - if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) + if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID) @@ -476,7 +476,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* TRACY_GPU_ZONE("RenderWindow"); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWORKSPACE = pWindow->m_pWorkspace; const auto REALPOS = pWindow->m_vRealPosition.value() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.value()); static auto PDIMAROUND = CConfigValue("decoration:dim_around"); static auto PBLUR = CConfigValue("decoration:blur:enabled"); @@ -732,7 +732,7 @@ void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, CMon wlr_surface_for_each_surface(pSurface->pWlrLockSurface->surface, renderSurface, &renderdata); } -void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time, const Vector2D& translate, const float& scale) { +void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* time, const Vector2D& translate, const float& scale) { static auto PDIMSPECIAL = CConfigValue("decoration:dim_special"); static auto PBLURSPECIAL = CConfigValue("decoration:blur:special"); static auto PBLUR = CConfigValue("decoration:blur:enabled"); @@ -810,7 +810,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* for (auto& ws : g_pCompositor->m_vWorkspaces) { if (ws->m_iMonitorID == pMonitor->ID && ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { const auto SPECIALANIMPROGRS = ws->m_vRenderOffset.isBeingAnimated() ? ws->m_vRenderOffset.getCurveValue() : ws->m_fAlpha.getCurveValue(); - const bool ANIMOUT = !pMonitor->specialWorkspaceID; + const bool ANIMOUT = !pMonitor->activeSpecialWorkspace; if (*PDIMSPECIAL != 0.f) { CBox monbox = {translate.x, translate.y, pMonitor->vecTransformedSize.x * scale, pMonitor->vecTransformedSize.y * scale}; @@ -830,9 +830,9 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* for (auto& ws : g_pCompositor->m_vWorkspaces) { if (ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { if (ws->m_bHasFullscreenWindow) - renderWorkspaceWindowsFullscreen(pMonitor, ws.get(), time); + renderWorkspaceWindowsFullscreen(pMonitor, ws, time); else - renderWorkspaceWindows(pMonitor, ws.get(), time); + renderWorkspaceWindows(pMonitor, ws, time); } } @@ -1273,7 +1273,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { renderCursor = false; } else { CBox renderBox = {0, 0, (int)pMonitor->vecPixelSize.x, (int)pMonitor->vecPixelSize.y}; - renderWorkspace(pMonitor, g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace), &now, renderBox); + renderWorkspace(pMonitor, pMonitor->activeWorkspace, &now, renderBox); renderLockscreen(pMonitor, &now, renderBox); @@ -1379,7 +1379,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { } } -void CHyprRenderer::renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry) { +void CHyprRenderer::renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) { Vector2D translate = {geometry.x, geometry.y}; float scale = (float)geometry.width / pMonitor->vecPixelSize.x; @@ -1727,7 +1727,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow, bool forceFull) { return; CBox windowBox = pWindow->getFullWindowBoundingBox(); - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + const auto PWINDOWWORKSPACE = pWindow->m_pWorkspace; if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); windowBox.translate(pWindow->m_vFloatingOffset); @@ -2402,16 +2402,16 @@ void CHyprRenderer::initiateManualCrash() { **PDT = 0; } -void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, CWorkspace* pWorkspace) { +void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, PHLWORKSPACE pWorkspace) { CRegion rg; const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); - if (!PMONITOR->specialWorkspaceID) + if (!PMONITOR->activeSpecialWorkspace) return; for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_iWorkspaceID != PMONITOR->specialWorkspaceID) + if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != PMONITOR->activeSpecialWorkspace) continue; if (!w->opaque()) @@ -2431,13 +2431,13 @@ void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, CWorkspace* pWo region.subtract(rg); } -void CHyprRenderer::setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace) { +void CHyprRenderer::setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWorkspace) { CRegion rg; const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_iWorkspaceID != pWorkspace->m_iID) + if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != pWorkspace) continue; if (!w->opaque()) @@ -2489,9 +2489,9 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) { if (g_pHyprNotificationOverlay->hasAny()) return; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace); + const auto PWORKSPACE = pMonitor->activeWorkspace; - if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceID || + if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->activeSpecialWorkspace || PWORKSPACE->m_fAlpha.value() != 1.f || PWORKSPACE->m_vRenderOffset.value() != Vector2D{}) return; @@ -2519,11 +2519,11 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) { if (w.get() == PCANDIDATE || (!w->m_bIsMapped && !w->m_bFadingOut) || w->isHidden()) continue; - if (w->m_iWorkspaceID == PCANDIDATE->m_iWorkspaceID && w->m_bIsFloating && w->m_bCreatedOverFullscreen && w->visibleOnMonitor(pMonitor)) + if (w->m_pWorkspace == PCANDIDATE->m_pWorkspace && w->m_bIsFloating && w->m_bCreatedOverFullscreen && w->visibleOnMonitor(pMonitor)) return; } - if (pMonitor->specialWorkspaceID != 0) + if (pMonitor->activeSpecialWorkspace) return; // check if it did not open any subsurfaces or shit diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 613706a5..bc5ff43c 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -61,8 +61,8 @@ class CHyprRenderer { void calculateUVForSurface(CWindow*, wlr_surface*, bool main = false, const Vector2D& projSize = {}, bool fixMisalignedFSV1 = false); std::tuple getRenderTimes(CMonitor* pMonitor); // avg max min void renderLockscreen(CMonitor* pMonitor, timespec* now, const CBox& geometry); - void setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace); - void setOccludedForMainWorkspace(CRegion& region, CWorkspace* pWorkspace); // TODO: merge occlusion methods + void setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWorkspace); + void setOccludedForMainWorkspace(CRegion& region, PHLWORKSPACE pWorkspace); // TODO: merge occlusion methods bool canSkipBackBufferClear(CMonitor* pMonitor); void recheckSolitaryForMonitor(CMonitor* pMonitor); void setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY, bool force = false); @@ -111,15 +111,15 @@ class CHyprRenderer { private: void arrangeLayerArray(CMonitor*, const std::vector>&, bool, CBox*); - void renderWorkspaceWindowsFullscreen(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) - void renderWorkspaceWindows(CMonitor*, CWorkspace*, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) + void renderWorkspaceWindowsFullscreen(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) + void renderWorkspaceWindows(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); void renderLayer(SLayerSurface*, CMonitor*, timespec*, bool popups = false); void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); void renderDragIcon(CMonitor*, timespec*); void renderIMEPopup(CInputPopup*, CMonitor*, timespec*); - void renderWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const CBox& geometry); - void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); + void renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry); + void renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); bool m_bCursorHidden = false; bool m_bCursorHasSurface = false; diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 76e60348..a45b2a5c 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -36,7 +36,7 @@ CBox CHyprBorderDecoration::assignedBoxGlobal() { CBox box = m_bAssignedGeometry; box.translate(g_pDecorationPositioner->getEdgeDefinedPoint(DECORATION_EDGE_BOTTOM | DECORATION_EDGE_LEFT | DECORATION_EDGE_RIGHT | DECORATION_EDGE_TOP, m_pWindow)); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + const auto PWORKSPACE = m_pWindow->m_pWorkspace; if (!PWORKSPACE) return box; @@ -95,7 +95,7 @@ void CHyprBorderDecoration::damageEntire() { const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 2; const auto BORDERSIZE = m_pWindow->getRealBorderSize() + 1; - const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + const auto PWINDOWWORKSPACE = m_pWindow->m_pWorkspace; if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) surfaceBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); surfaceBox.translate(m_pWindow->m_vFloatingOffset); diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 99d08828..62b2192d 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -45,7 +45,7 @@ void CHyprDropShadowDecoration::damageEntire() { m_pWindow->m_vRealSize.value().x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, m_pWindow->m_vRealSize.value().y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y}; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + const auto PWORKSPACE = m_pWindow->m_pWorkspace; if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) shadowBox.translate(PWORKSPACE->m_vRenderOffset.value()); shadowBox.translate(m_pWindow->m_vFloatingOffset); @@ -110,7 +110,7 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) { const auto ROUNDINGBASE = m_pWindow->rounding(); const auto ROUNDING = ROUNDINGBASE > 0 ? ROUNDINGBASE + m_pWindow->getRealBorderSize() : 0; - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + const auto PWORKSPACE = m_pWindow->m_pWorkspace; const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D(); // draw the shadow diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 50bf4627..e9aa5f0c 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -423,7 +423,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, CWindow } bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) { - if (m_pWindow->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_FULL) + if (m_pWindow->m_bIsFullscreen && m_pWindow->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL) return true; const float BARRELATIVEX = pos.x - assignedBoxGlobal().x; @@ -506,7 +506,7 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() { CBox box = m_bAssignedBox; box.translate(g_pDecorationPositioner->getEdgeDefinedPoint(DECORATION_EDGE_TOP, m_pWindow)); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID); + const auto PWORKSPACE = m_pWindow->m_pWorkspace; if (PWORKSPACE && !m_pWindow->m_bPinned) box.translate(PWORKSPACE->m_vRenderOffset.value()); From 153c8f35ce5f24b066de916269a94fce1d4f3357 Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:58:45 +0000 Subject: [PATCH 0114/2772] workspace: fix special unnamed workspace rules (#5390) modified: src/desktop/Workspace.cpp --- src/desktop/Workspace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index ccb0fa25..8e49c998 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -233,7 +233,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { } else if (selector.starts_with("name:")) { return m_szName == selector.substr(5); - } else if (selector.starts_with("special:")) { + } else if (selector.starts_with("special")) { return m_szName == selector; } else { // parse selector From 3965faafacf18f6e43be91ba326ddfce3948eb3d Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:22:27 -0700 Subject: [PATCH 0115/2772] master: fix center resizing (#5394) --- src/layout/MasterLayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 2066ca76..f8f710f6 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -799,7 +799,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne case ORIENTATION_TOP: delta = pixResize.y / PMONITOR->vecSize.y; break; case ORIENTATION_CENTER: delta = pixResize.x / PMONITOR->vecSize.x; - if (WINDOWS > 2) { + if (WINDOWS > 2 || *ALWAYSCENTER) { if (!NONE || !PNODE->isMaster) delta *= 2; if ((!PNODE->isMaster && DISPLAYLEFT) || (PNODE->isMaster && LEFT && *PSMARTRESIZING)) From fbdaf74a82b38e11a0a6914b3c9f7cb934ac1624 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:22:59 -0700 Subject: [PATCH 0116/2772] master: fix swapped workspaces (#5397) --- src/layout/MasterLayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index f8f710f6..ea906943 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -809,7 +809,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne default: UNREACHABLE(); } - const auto workspaceIdForResizing = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeWorkspaceID() : PMONITOR->activeSpecialWorkspaceID(); + const auto workspaceIdForResizing = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); for (auto& n : m_lMasterNodesData) { if (n.isMaster && n.workspaceID == workspaceIdForResizing) n.percMaster = std::clamp(n.percMaster + delta, 0.05, 0.95); From 347b83903474ab9e95fa9d4ba123f6f78ab38d40 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 10:09:42 +0100 Subject: [PATCH 0117/2772] workspaces: add visible flag --- src/Compositor.cpp | 26 +++++------- src/Compositor.hpp | 2 +- src/desktop/Popup.cpp | 10 +++++ src/desktop/Subsurface.cpp | 2 +- src/desktop/Workspace.cpp | 7 ---- src/desktop/Workspace.hpp | 3 ++ src/events/Layers.cpp | 2 +- src/events/Windows.cpp | 59 ++++++++++++++-------------- src/helpers/Monitor.cpp | 15 +++++-- src/managers/AnimationManager.cpp | 2 +- src/managers/input/IdleInhibitor.cpp | 2 +- src/render/Renderer.cpp | 8 ++-- 12 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 001d7ca8..3b7b5d9b 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -764,7 +764,7 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert continue; CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->workspaceID()) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_pWorkspace) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) { // OR windows should add focus to parent if (w->m_bX11ShouldntFocus && w->m_iX11Type != 2) @@ -1001,7 +1001,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); - if (!isWorkspaceVisible(pWindow->workspaceID())) { + if (!isWorkspaceVisible(pWindow->m_pWorkspace)) { const auto PWORKSPACE = pWindow->m_pWorkspace; // This is to fix incorrect feedback on the focus history. PWORKSPACE->m_pLastFocusedWindow = pWindow; @@ -1240,16 +1240,8 @@ CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { return nullptr; } -bool CCompositor::isWorkspaceVisible(const int& w) { - for (auto& m : m_vMonitors) { - if (m->activeWorkspaceID() == w) - return true; - - if (m->activeSpecialWorkspaceID() == w) - return true; - } - - return false; +bool CCompositor::isWorkspaceVisible(PHLWORKSPACE w) { + return w->m_bVisible; } PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { @@ -1280,7 +1272,7 @@ void CCompositor::sanityCheckWorkspaces() { const auto WINDOWSONWORKSPACE = getWindowsOnWorkspace(WORKSPACE->m_iID); if (WINDOWSONWORKSPACE == 0) { - if (!isWorkspaceVisible(WORKSPACE->m_iID)) { + if (!isWorkspaceVisible(WORKSPACE)) { if (WORKSPACE->m_bIsSpecialWorkspace) { if (WORKSPACE->m_fAlpha.value() > 0.f /* don't abruptly end the fadeout */) { @@ -1584,7 +1576,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { // for tiled windows, we calc edges for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) @@ -1673,7 +1665,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { constexpr float THRESHOLD = 0.3 * M_PI; for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) @@ -2737,7 +2729,7 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, PHLWORKSPACE pWork CWindow* CCompositor::getForceFocus() { for (auto& w : m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->workspaceID())) + if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (!w->m_bStayFocused) @@ -2886,6 +2878,6 @@ void CCompositor::updateSuspendedStates() { if (!w->m_bIsMapped) continue; - w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->workspaceID())); + w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->m_pWorkspace)); } } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 98bbe899..4604f687 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -144,7 +144,7 @@ class CCompositor { CWindow* getWindowFromSurface(wlr_surface*); CWindow* getWindowFromHandle(uint32_t); CWindow* getWindowFromZWLRHandle(wl_resource*); - bool isWorkspaceVisible(const int&); + bool isWorkspaceVisible(PHLWORKSPACE); PHLWORKSPACE getWorkspaceByID(const int&); PHLWORKSPACE getWorkspaceByName(const std::string&); PHLWORKSPACE getWorkspaceByString(const std::string&); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 77e486fd..a32b28d6 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -1,4 +1,5 @@ #include "Popup.hpp" +#include "../config/ConfigValue.hpp" #include "../Compositor.hpp" CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) { @@ -145,6 +146,15 @@ void CPopup::onCommit(bool ignoreSiblings) { return; } + if (m_pWindowOwner && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) { + m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height}; + + static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); + if (*PLOGDAMAGE) + Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner); + return; + } + const auto COORDS = coordsGlobal(); const auto COORDSLOCAL = coordsRelativeToParent(); diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index c3538ee1..e337c798 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -117,7 +117,7 @@ void CSubsurface::recheckDamageForSubsurfaces() { void CSubsurface::onCommit() { // no damaging if it's not visible - if (m_pWindowParent && !g_pHyprRenderer->shouldRenderWindow(m_pWindowParent)) { + if (m_pWindowParent && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) { m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 8e49c998..1df18c3b 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -9,13 +9,6 @@ PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool sp } CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); - - if (!PMONITOR) { - Debug::log(ERR, "Attempted a creation of CWorkspace with an invalid monitor?"); - return; - } - m_iMonitorID = monitorID; m_iID = id; m_szName = name; diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 1630baf5..deb108ec 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -42,6 +42,9 @@ class CWorkspace { CAnimatedVariable m_fAlpha; bool m_bForceRendering = false; + // allows damage to propagate. + bool m_bVisible = false; + // "scratchpad" bool m_bIsSpecialWorkspace = false; diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index bd27004b..ab002ef6 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -237,7 +237,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface); - if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->workspaceID())) { + if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) { // if there isn't any, focus the last window const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->focusWindow(nullptr); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index eb876cf2..b1db5286 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -800,6 +800,35 @@ void Events::listener_commitWindow(void* owner, void* data) { PWINDOW->m_pPendingSizeAck.reset(); } + if (!PWINDOW->m_bIsX11 && !PWINDOW->m_bIsFullscreen && PWINDOW->m_bIsFloating) { + const auto MINSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.min_width, PWINDOW->m_uSurface.xdg->toplevel->current.min_height}; + const auto MAXSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.max_width, PWINDOW->m_uSurface.xdg->toplevel->current.max_height}; + + if (MAXSIZE > Vector2D{1, 1}) { + const auto REALSIZE = PWINDOW->m_vRealSize.goal(); + Vector2D newSize = REALSIZE; + + if (MAXSIZE.x < newSize.x) + newSize.x = MAXSIZE.x; + if (MAXSIZE.y < newSize.y) + newSize.y = MAXSIZE.y; + if (MINSIZE.x > newSize.x) + newSize.x = MINSIZE.x; + if (MINSIZE.y > newSize.y) + newSize.y = MINSIZE.y; + + const Vector2D DELTA = REALSIZE - newSize; + + PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0; + PWINDOW->m_vRealSize = newSize; + g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true); + g_pHyprRenderer->damageWindow(PWINDOW); + } + } + + if (!PWINDOW->m_pWorkspace->m_bVisible) + return; + g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y, PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0); @@ -823,34 +852,6 @@ void Events::listener_commitWindow(void* owner, void* data) { } } } - - if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) - return; - - const auto MINSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.min_width, PWINDOW->m_uSurface.xdg->toplevel->current.min_height}; - const auto MAXSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.max_width, PWINDOW->m_uSurface.xdg->toplevel->current.max_height}; - - if (MAXSIZE < Vector2D{1, 1}) - return; - - const auto REALSIZE = PWINDOW->m_vRealSize.goal(); - Vector2D newSize = REALSIZE; - - if (MAXSIZE.x < newSize.x) - newSize.x = MAXSIZE.x; - if (MAXSIZE.y < newSize.y) - newSize.y = MAXSIZE.y; - if (MINSIZE.x > newSize.x) - newSize.x = MINSIZE.x; - if (MINSIZE.y > newSize.y) - newSize.y = MINSIZE.y; - - const Vector2D DELTA = REALSIZE - newSize; - - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0; - PWINDOW->m_vRealSize = newSize; - g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true); - g_pHyprRenderer->damageWindow(PWINDOW); } void Events::listener_destroyWindow(void* owner, void* data) { @@ -1094,7 +1095,7 @@ void Events::listener_configureX11(void* owner, void* data) { PWINDOW->updateWindowDecos(); - if (!g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID())) + if (!g_pCompositor->isWorkspaceVisible(PWINDOW->m_pWorkspace)) return; // further things are only for visible windows PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 4018cc8b..152356e4 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -416,6 +416,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { activeWorkspace = PNEWWORKSPACE; PNEWWORKSPACE->setActive(true); + PNEWWORKSPACE->m_bVisible = true; PNEWWORKSPACE->m_szLastMonitor = ""; } @@ -547,7 +548,9 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo if (pWorkspace == activeWorkspace) return; - const auto POLDWORKSPACE = activeWorkspace; + const auto POLDWORKSPACE = activeWorkspace; + POLDWORKSPACE->m_bVisible = false; + pWorkspace->m_bVisible = true; activeWorkspace = pWorkspace; @@ -612,6 +615,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { if (!pWorkspace) { // remove special if exists if (activeSpecialWorkspace) { + activeSpecialWorkspace->m_bVisible = false; activeSpecialWorkspace->startAnim(false, false); g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + szName}); } @@ -633,8 +637,10 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { return; } - if (activeSpecialWorkspace) + if (activeSpecialWorkspace) { + activeSpecialWorkspace->m_bVisible = false; activeSpecialWorkspace->startAnim(false, false); + } bool animate = true; //close if open elsewhere @@ -651,8 +657,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { } // open special - pWorkspace->m_iMonitorID = ID; - activeSpecialWorkspace = pWorkspace; + pWorkspace->m_iMonitorID = ID; + activeSpecialWorkspace = pWorkspace; + activeSpecialWorkspace->m_bVisible = true; if (animate) pWorkspace->startAnim(true, true); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index a9a72941..ac849b58 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -146,7 +146,7 @@ void CAnimationManager::tick() { animationsDisabled = animationsDisabled || PLAYER->noAnimations; } - const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID()) : true; + const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? g_pCompositor->isWorkspaceVisible(PWINDOW->m_pWorkspace) : true; // beziers are with a switch unforto // TODO: maybe do something cleaner diff --git a/src/managers/input/IdleInhibitor.cpp b/src/managers/input/IdleInhibitor.cpp index 12d768f5..7e7ee3c9 100644 --- a/src/managers/input/IdleInhibitor.cpp +++ b/src/managers/input/IdleInhibitor.cpp @@ -65,7 +65,7 @@ void CInputManager::recheckIdleInhibitorStatus() { return; } - if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->workspaceID())) { + if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->m_pWorkspace)) { g_pCompositor->setIdleActivityInhibit(false); return; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index cc682fad..446cb9bf 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -233,18 +233,18 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { pWindow->m_fAlpha.value() == 0) return false; - if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) + if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) return false; } if (pWindow->m_iMonitorID == pMonitor->ID) return true; - if (!g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_iMonitorID != pMonitor->ID) + if (!g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace) && pWindow->m_iMonitorID != pMonitor->ID) return false; // if not, check if it maybe is active on a different monitor. - if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) + if (g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors if (pMonitor->activeSpecialWorkspace == pWindow->m_pWorkspace) @@ -285,7 +285,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) { if (pWindow->m_bPinned || PWORKSPACE->m_bForceRendering) return true; - if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) + if (g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) return true; for (auto& m : g_pCompositor->m_vMonitors) { From efdc1af04420b59917f8530a20ccfabe658f636a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 14:09:58 +0100 Subject: [PATCH 0118/2772] renderer: some fixes for renderModif --- src/protocols/Screencopy.cpp | 4 ++ src/render/OpenGL.cpp | 61 +++++++++++++++++-- src/render/OpenGL.hpp | 5 ++ src/render/Renderer.cpp | 27 +++++++- .../decorations/CHyprDropShadowDecoration.cpp | 3 + 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index a0c05b22..9807cc55 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -485,7 +485,9 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec* CBox monbox = CBox{0, 0, frame->pMonitor->vecTransformedSize.x, frame->pMonitor->vecTransformedSize.y}.translate({-frame->box.x, -frame->box.y}); g_pHyprOpenGL->setMonitorTransformEnabled(true); + g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); + g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); #ifndef GLES2 @@ -544,7 +546,9 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) { .translate({-frame->box.x, -frame->box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh. .transform(wlr_output_transform_invert(frame->pMonitor->output->transform), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y); g_pHyprOpenGL->setMonitorTransformEnabled(true); + g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); + g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); g_pHyprRenderer->endRender(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 0628838c..f9b44a80 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -795,6 +795,8 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion } glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib); + + scissor((CBox*)nullptr); } void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, CBox* pBox, float alpha, int round, bool allowCustomUV) { @@ -1480,6 +1482,8 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo if (texDamage.empty()) return; + m_RenderData.renderModif.applyToRegion(texDamage); + if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && (m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur || m_pCurrentWindow->m_sAdditionalConfigData.forceRGBX))) { renderTexture(tex, pBox, a, round, false, true); @@ -1509,7 +1513,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo CFramebuffer* POUTFB = nullptr; if (!USENEWOPTIMIZE) { - inverseOpaque.translate({pBox->x, pBox->y}).intersect(texDamage); + inverseOpaque.translate({pBox->x, pBox->y}); + m_RenderData.renderModif.applyToRegion(inverseOpaque); + inverseOpaque.intersect(texDamage); POUTFB = blurMainFramebufferWithDamage(a, &inverseOpaque); } else { @@ -1542,12 +1548,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; // render our great blurred FB static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); - m_bEndFrame = true; // fix transformed - const auto SAVEDRENDERMODIF = m_RenderData.renderModif; - m_RenderData.renderModif = {}; // fix shit + setMonitorTransformEnabled(true); + setRenderModifEnabled(false); renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false); - m_bEndFrame = false; - m_RenderData.renderModif = SAVEDRENDERMODIF; + setMonitorTransformEnabled(false); + setRenderModifEnabled(true); // render the window, but clear stencil glClearStencil(0); @@ -1587,6 +1592,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in return; int scaledBorderSize = std::round(borderSize * m_RenderData.pMonitor->scale); + scaledBorderSize = std::round(scaledBorderSize * m_RenderData.renderModif.combinedScale()); // adjust box box->x -= scaledBorderSize; @@ -2223,6 +2229,10 @@ void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) { m_bEndFrame = enabled; } +void CHyprOpenGLImpl::setRenderModifEnabled(bool enabled) { + m_RenderData.renderModif.enabled = enabled; +} + inline const SGLPixelFormat GLES2_FORMATS[] = { { .drmFormat = DRM_FORMAT_ARGB8888, @@ -2358,6 +2368,9 @@ const SGLPixelFormat* CHyprOpenGLImpl::getPixelFormatFromDRM(uint32_t drmFormat) } void SRenderModifData::applyToBox(CBox& box) { + if (!enabled) + return; + for (auto& [type, val] : modifs) { try { switch (type) { @@ -2378,3 +2391,39 @@ void SRenderModifData::applyToBox(CBox& box) { } catch (std::bad_any_cast& e) { Debug::log(ERR, "BUG THIS OR PLUGIN ERROR: caught a bad_any_cast in SRenderModifData::applyToBox!"); } } } + +void SRenderModifData::applyToRegion(CRegion& rg) { + if (!enabled) + return; + + for (auto& [type, val] : modifs) { + try { + switch (type) { + case RMOD_TYPE_SCALE: rg.scale(std::any_cast(val)); break; + case RMOD_TYPE_SCALECENTER: rg.scale(std::any_cast(val)); break; + case RMOD_TYPE_TRANSLATE: rg.translate(std::any_cast(val)); break; + case RMOD_TYPE_ROTATE: /* TODO */ + case RMOD_TYPE_ROTATECENTER: break; + } + } catch (std::bad_any_cast& e) { Debug::log(ERR, "BUG THIS OR PLUGIN ERROR: caught a bad_any_cast in SRenderModifData::applyToRegion!"); } + } +} + +float SRenderModifData::combinedScale() { + if (!enabled) + return 1; + + float scale = 1.f; + for (auto& [type, val] : modifs) { + try { + switch (type) { + case RMOD_TYPE_SCALE: scale *= std::any_cast(val); break; + case RMOD_TYPE_SCALECENTER: + case RMOD_TYPE_TRANSLATE: + case RMOD_TYPE_ROTATE: + case RMOD_TYPE_ROTATECENTER: break; + } + } catch (std::bad_any_cast& e) { Debug::log(ERR, "BUG THIS OR PLUGIN ERROR: caught a bad_any_cast in SRenderModifData::combinedScale!"); } + } + return scale; +} diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 65f3e6ba..6af2a00f 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -47,6 +47,10 @@ struct SRenderModifData { std::vector> modifs; void applyToBox(CBox& box); + void applyToRegion(CRegion& rg); + float combinedScale(); + + bool enabled = true; }; struct SGLPixelFormat { @@ -138,6 +142,7 @@ class CHyprOpenGLImpl { void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte); void setMonitorTransformEnabled(bool enabled); + void setRenderModifEnabled(bool enabled); void saveMatrix(); void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 446cb9bf..e738de9b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -760,13 +760,35 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC // g_pHyprOpenGL->setMatrixScaleTranslate(translate, scale); g_pHyprOpenGL->m_RenderData.renderModif = RENDERMODIFDATA; + if (!pWorkspace) { + // allow rendering without a workspace. In this case, just render layers. + g_pHyprOpenGL->blend(true); + + for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { + renderLayer(ls.get(), pMonitor, time); + } + for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { + renderLayer(ls.get(), pMonitor, time); + } + for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { + renderLayer(ls.get(), pMonitor, time); + } + for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { + renderLayer(ls.get(), pMonitor, time); + } + + g_pHyprOpenGL->m_RenderData.renderModif = {}; + + return; + } + // for storing damage when we optimize for occlusion CRegion preOccludedDamage{g_pHyprOpenGL->m_RenderData.damage}; // Render layer surfaces below windows for monitor // if we have a fullscreen, opaque window that convers the screen, we can skip this. // TODO: check better with solitary after MR for tearing. - const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(pWorkspace->m_iID); + const auto PFULLWINDOW = pWorkspace ? g_pCompositor->getFullscreenWindowOnWorkspace(pWorkspace->m_iID) : nullptr; if (!pWorkspace->m_bHasFullscreenWindow || pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL || !PFULLWINDOW || PFULLWINDOW->m_vRealSize.isBeingAnimated() || !PFULLWINDOW->opaque() || pWorkspace->m_vRenderOffset.value() != Vector2D{}) { @@ -804,8 +826,6 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC g_pHyprOpenGL->m_RenderData.damage = preOccludedDamage; - g_pHyprOpenGL->m_RenderData.renderModif = {}; - // and then special for (auto& ws : g_pCompositor->m_vWorkspaces) { if (ws->m_iMonitorID == pMonitor->ID && ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { @@ -2450,6 +2470,7 @@ void CHyprRenderer::setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWork CBox box = {POS.x, POS.y, SIZE.x, SIZE.y}; box.scale(PMONITOR->scale); + g_pHyprOpenGL->m_RenderData.renderModif.applyToBox(box); rg.add(box); } diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 62b2192d..bba2c639 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -171,6 +171,7 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) { g_pHyprOpenGL->m_RenderData.damage = fullBox; g_pHyprOpenGL->m_RenderData.damage.subtract(windowBox.copy().expand(-ROUNDING * pMonitor->scale)).intersect(saveDamage); + g_pHyprOpenGL->m_RenderData.renderModif.applyToRegion(g_pHyprOpenGL->m_RenderData.damage); alphaFB.bind(); @@ -194,7 +195,9 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) { CBox monbox = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; g_pHyprOpenGL->setMonitorTransformEnabled(true); + g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTextureMatte(alphaSwapFB.m_cTex, &monbox, alphaFB); + g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); g_pHyprOpenGL->m_RenderData.damage = saveDamage; From 3981f85e9487224e8c193160cbd7ae7137a11204 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 14:23:19 +0100 Subject: [PATCH 0119/2772] opengl: log framebuffer errors --- src/render/Framebuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp index d35e5119..83325dd7 100644 --- a/src/render/Framebuffer.cpp +++ b/src/render/Framebuffer.cpp @@ -43,7 +43,7 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { #endif auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Framebuffer incomplete, couldn't create! (FB status: {})", status); + RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Framebuffer incomplete, couldn't create! (FB status: {}, GL Error: 0x{:x})", status, (int)glGetError()); Debug::log(LOG, "Framebuffer created, status {}", status); } From 64964c4e3beaf890fc9d12eb0e1804373f0fabe6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 14:28:15 +0100 Subject: [PATCH 0120/2772] renderer: render back layer for workspace-less passes --- src/render/Renderer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index e738de9b..b43f3a2d 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -762,6 +762,13 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPAC if (!pWorkspace) { // allow rendering without a workspace. In this case, just render layers. + g_pHyprOpenGL->blend(false); + if (!canSkipBackBufferClear(pMonitor)) { + if (*PRENDERTEX /* inverted cfg flag */) + g_pHyprOpenGL->clear(CColor(*PBACKGROUNDCOLOR)); + else + g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" + } g_pHyprOpenGL->blend(true); for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { From 91061a2084f4b3b2f64c955b4d02b8f5c94541be Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 15:08:29 +0100 Subject: [PATCH 0121/2772] opengl: fix modif in blur --- src/render/OpenGL.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f9b44a80..c2401cef 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1549,10 +1549,8 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo // render our great blurred FB static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); setMonitorTransformEnabled(true); - setRenderModifEnabled(false); renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false); setMonitorTransformEnabled(false); - setRenderModifEnabled(true); // render the window, but clear stencil glClearStencil(0); From 93915502d2677b70382b7cba09620b445f6b832e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 17:08:11 +0100 Subject: [PATCH 0122/2772] blur: block modif only on no new optimize --- src/render/OpenGL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index c2401cef..8be8e54e 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1549,7 +1549,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo // render our great blurred FB static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); setMonitorTransformEnabled(true); + if (!USENEWOPTIMIZE) + setRenderModifEnabled(false); renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false); + if (!USENEWOPTIMIZE) + setRenderModifEnabled(true); setMonitorTransformEnabled(false); // render the window, but clear stencil From d88d5898807bf6f2462cecfb977b7624dafbf52e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 19:20:47 +0100 Subject: [PATCH 0123/2772] swipe: add events --- src/managers/input/Swipe.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 47a6f5bd..ba91394e 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -7,6 +7,8 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) { static auto PSWIPEFINGERS = CConfigValue("gestures:workspace_swipe_fingers"); static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); + EMIT_HOOK_EVENT_CANCELLABLE("swipeBegin", e); + if (e->fingers != *PSWIPEFINGERS || *PSWIPE == 0 || g_pSessionLockManager->isSessionLocked()) return; @@ -42,6 +44,8 @@ void CInputManager::beginWorkspaceSwipe() { } void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { + EMIT_HOOK_EVENT_CANCELLABLE("swipeEnd", e); + if (!m_sActiveSwipe.pWorkspaceBegin) return; // no valid swipe endWorkspaceSwipe(); @@ -195,6 +199,8 @@ void CInputManager::endWorkspaceSwipe() { } void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { + EMIT_HOOK_EVENT_CANCELLABLE("swipeUpdate", e); + if (!m_sActiveSwipe.pWorkspaceBegin) return; static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); From 10146f5ec50caeae2d835f5f6296137e2ac6f243 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 20:42:38 +0100 Subject: [PATCH 0124/2772] core: fix some crash conditions around workspace ptrs in CWindow ref #5402, supersedes #5409 --- src/Compositor.cpp | 2 +- src/render/Renderer.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3b7b5d9b..033af696 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1241,7 +1241,7 @@ CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { } bool CCompositor::isWorkspaceVisible(PHLWORKSPACE w) { - return w->m_bVisible; + return valid(w) && w->m_bVisible; } PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b43f3a2d..af6b7aae 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -220,6 +220,9 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { if (!pWindow->m_pWorkspace && !pWindow->m_bFadingOut) return false; + if (!pWindow->m_pWorkspace && pWindow->m_bFadingOut) + return pWindow->workspaceID() == pMonitor->activeWorkspaceID(); + if (pWindow->m_bPinned) return true; @@ -1760,7 +1763,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow, bool forceFull) { windowBox.translate(pWindow->m_vFloatingOffset); for (auto& m : g_pCompositor->m_vMonitors) { - if (g_pHyprRenderer->shouldRenderWindow(pWindow, m.get()) || forceFull) { // only damage if window is rendered on monitor + if (forceFull || g_pHyprRenderer->shouldRenderWindow(pWindow, m.get())) { // only damage if window is rendered on monitor CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height}; fixedDamageBox.scale(m->scale); m->addDamage(&fixedDamageBox); From d605e475118fd66e625a5a23c687cd01a34b302c Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 21:35:16 +0100 Subject: [PATCH 0125/2772] renderer: block screen shader on screencopy --- src/protocols/Screencopy.cpp | 2 ++ src/protocols/ToplevelExport.cpp | 2 ++ src/render/OpenGL.cpp | 3 ++- src/render/OpenGL.hpp | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 9807cc55..476df0b8 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -504,6 +504,7 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec* return false; } + g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprRenderer->endRender(); g_pHyprRenderer->makeEGLCurrent(); @@ -551,6 +552,7 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) { g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); + g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprRenderer->endRender(); wlr_texture_destroy(sourceTex); diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index e3273f7a..e2006afb 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -402,6 +402,7 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times return false; } + g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprRenderer->endRender(); g_pHyprRenderer->makeEGLCurrent(); @@ -441,6 +442,7 @@ bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, ti if (frame->overlayCursor) g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.value()); + g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprRenderer->endRender(); return true; } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 8be8e54e..9e3fb47b 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -365,7 +365,7 @@ void CHyprOpenGLImpl::end() { } m_bEndFrame = true; - m_bApplyFinalShader = true; + m_bApplyFinalShader = !m_RenderData.blockScreenShader; if (m_RenderData.mouseZoomUseMouse) m_RenderData.useNearestNeighbor = true; @@ -388,6 +388,7 @@ void CHyprOpenGLImpl::end() { m_RenderData.mouseZoomFactor = 1.f; m_RenderData.mouseZoomUseMouse = true; m_RenderData.forceIntrospection = false; + m_RenderData.blockScreenShader = false; m_RenderData.currentFB = nullptr; m_RenderData.mainFB = nullptr; m_RenderData.outFB = nullptr; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 6af2a00f..08a1583d 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -112,6 +112,7 @@ struct SCurrentRenderData { bool mouseZoomUseMouse = true; // true by default bool useNearestNeighbor = false; bool forceIntrospection = false; // cleaned in ::end() + bool blockScreenShader = false; Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1); Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); From 949eb426136aef2690c31acc6389016aa8755ac8 Mon Sep 17 00:00:00 2001 From: Micovec <30734146+Micovec@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:41:10 +0200 Subject: [PATCH 0126/2772] hyprctl: improve help pages (#5385) --- hyprctl/Strings.hpp | 158 ++++++++++++++++++++++++++++++++++++++++++++ hyprctl/main.cpp | 76 ++++++++------------- 2 files changed, 185 insertions(+), 49 deletions(-) create mode 100644 hyprctl/Strings.hpp diff --git a/hyprctl/Strings.hpp b/hyprctl/Strings.hpp new file mode 100644 index 00000000..951c6a7f --- /dev/null +++ b/hyprctl/Strings.hpp @@ -0,0 +1,158 @@ +#pragma once + +const std::string_view USAGE = R"#(usage: hyprctl [flags] [args...|--help] + +commands: + activewindow → Gets the active window name and its properties + activeworkspace → Gets the active workspace and its properties + animations → Gets the current config'd info about animations + and beziers + binds → Lists all registered binds + clients → Lists all windows with their properties + configerrors → Lists all current config parsing errors + cursorpos → Gets the current cursor position in global layout + coordinates + decorations → Lists all decorations and their info + devices → Lists all connected keyboards and mice + dismissnotify [amount] → Dismisses all or up to AMOUNT notifications + dispatch [args] → Issue a dispatch to call a keybind + dispatcher with arguments + getoption