From d48468d59c5a561c3e0af906f32c808e983a3ffd Mon Sep 17 00:00:00 2001 From: Tom Benham Date: Thu, 11 Apr 2024 12:05:31 +0200 Subject: [PATCH 1/3] Added `toggleswallow` dispatcher --- src/desktop/Window.hpp | 3 ++- src/managers/KeybindManager.cpp | 23 +++++++++++++++++++++++ src/managers/KeybindManager.hpp | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 8a368ea6d85..530501d35af 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -340,7 +340,8 @@ class CWindow { CAnimatedVariable m_fDimPercent; // swallowing - CWindow* m_pSwallowed = nullptr; + CWindow* m_pSwallowed = nullptr; + CWindow* m_pPreviouslySwallowed = nullptr; // focus stuff bool m_bStayFocused = false; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 63c0c95f093..347e2c77f59 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -59,6 +59,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["cyclenext"] = circleNext; m_mDispatchers["focuswindowbyclass"] = focusWindow; m_mDispatchers["focuswindow"] = focusWindow; + m_mDispatchers["toggleswallow"] = toggleSwallow; m_mDispatchers["submap"] = setSubmap; m_mDispatchers["pass"] = pass; m_mDispatchers["layoutmsg"] = layoutmsg; @@ -1820,6 +1821,28 @@ void CKeybindManager::focusWindow(std::string regexp) { g_pCompositor->warpCursorTo(PWINDOW->middle()); } +void CKeybindManager::toggleSwallow(std::string args) { + CWindow* pWindow = g_pCompositor->m_pLastWindow; + if (pWindow->m_pSwallowed && g_pCompositor->windowExists(pWindow->m_pSwallowed)) { + pWindow->m_pPreviouslySwallowed = pWindow->m_pSwallowed; + + pWindow->m_pSwallowed->setHidden(false); + + g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow->m_pSwallowed); + + pWindow->m_pSwallowed = nullptr; + + } else if (pWindow->m_pPreviouslySwallowed && g_pCompositor->windowExists(pWindow->m_pPreviouslySwallowed)) { + pWindow->m_pSwallowed = pWindow->m_pPreviouslySwallowed; + + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_pPreviouslySwallowed); + + pWindow->m_pPreviouslySwallowed->setHidden(true); + + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pWindow->m_iMonitorID); + } +} + void CKeybindManager::setSubmap(std::string submap) { if (submap == "reset" || submap == "") { m_szCurrentSelectedSubmap = ""; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index aec9e02d937..110186d1222 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -151,6 +151,7 @@ class CKeybindManager { static void forceRendererReload(std::string); static void resizeActive(std::string); static void moveActive(std::string); + static void toggleSwallow(std::string); static void moveWindow(std::string); static void resizeWindow(std::string); static void circleNext(std::string); From 5a520914ace7a52845f7ec707581b4d01b1b94fb Mon Sep 17 00:00:00 2001 From: Tom Benham Date: Fri, 12 Apr 2024 10:46:56 +0200 Subject: [PATCH 2/3] Added m_pSwallowedBy symmetric reference to avoid dangling m_pSwallowed pointer --- src/desktop/Window.hpp | 1 + src/events/Windows.cpp | 13 ++++++++++--- src/managers/KeybindManager.cpp | 10 ++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 530501d35af..7e70019916c 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -342,6 +342,7 @@ class CWindow { // swallowing CWindow* m_pSwallowed = nullptr; CWindow* m_pPreviouslySwallowed = nullptr; + CWindow* m_pSwallowedBy = nullptr; // focus stuff bool m_bStayFocused = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index b1db528681e..2ac198e7bd8 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -583,7 +583,8 @@ void Events::listener_mapWindow(void* owner, void* data) { // check if it's the window we want & not exempt from getting swallowed if (valid) { // swallow - PWINDOW->m_pSwallowed = finalFound; + PWINDOW->m_pSwallowed = finalFound; + finalFound->m_pSwallowedBy = PWINDOW; g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound); @@ -687,10 +688,16 @@ void Events::listener_unmapWindow(void* owner, void* data) { g_pHyprOpenGL->makeWindowSnapshot(PWINDOW); // swallowing - if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) { + if (PWINDOW->m_pSwallowed) { PWINDOW->m_pSwallowed->setHidden(false); g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed); - PWINDOW->m_pSwallowed = nullptr; + PWINDOW->m_pSwallowed->m_pSwallowedBy = nullptr; + PWINDOW->m_pSwallowed = nullptr; + } + // swallowed + if (PWINDOW->m_pSwallowedBy) { + PWINDOW->m_pSwallowedBy->m_pSwallowed = nullptr; + PWINDOW->m_pSwallowedBy = nullptr; } bool wasLastWindow = false; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 347e2c77f59..a703664f2c3 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1823,17 +1823,19 @@ void CKeybindManager::focusWindow(std::string regexp) { void CKeybindManager::toggleSwallow(std::string args) { CWindow* pWindow = g_pCompositor->m_pLastWindow; - if (pWindow->m_pSwallowed && g_pCompositor->windowExists(pWindow->m_pSwallowed)) { + if (pWindow->m_pSwallowed) { pWindow->m_pPreviouslySwallowed = pWindow->m_pSwallowed; pWindow->m_pSwallowed->setHidden(false); g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow->m_pSwallowed); - pWindow->m_pSwallowed = nullptr; + pWindow->m_pSwallowed->m_pSwallowedBy = nullptr; + pWindow->m_pSwallowed = nullptr; - } else if (pWindow->m_pPreviouslySwallowed && g_pCompositor->windowExists(pWindow->m_pPreviouslySwallowed)) { - pWindow->m_pSwallowed = pWindow->m_pPreviouslySwallowed; + } else if (pWindow->m_pPreviouslySwallowed) { + pWindow->m_pSwallowed = pWindow->m_pPreviouslySwallowed; + pWindow->m_pSwallowed->m_pSwallowedBy = pWindow; g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_pPreviouslySwallowed); From 07848e7f599ee02962042e95bcdc07c3e8d2308e Mon Sep 17 00:00:00 2001 From: Tom Benham Date: Fri, 12 Apr 2024 16:26:01 +0200 Subject: [PATCH 3/3] Replaced m_pPreviouslySwallowed with a boolean --- src/debug/HyprCtl.cpp | 4 ++-- src/desktop/Window.hpp | 2 +- src/events/Windows.cpp | 5 +++-- src/managers/KeybindManager.cpp | 25 ++++++++++++------------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 00bea61ea84..574b2d9bd3c 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -208,7 +208,7 @@ static std::string getWindowData(CWindow* w, eHyprCtlOutputFormat format) { 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)); + w->m_bFakeFullscreenState ? "true" : "false", getGroupedData(w, format), w->m_bCurrentlySwallowing ? (uintptr_t)w->m_pSwallowed : 0, 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: " @@ -219,7 +219,7 @@ static std::string getWindowData(CWindow* w, eHyprCtlOutputFormat format) { (!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)); + w->m_bCurrentlySwallowing ? (uintptr_t)w->m_pSwallowed : 0, getFocusHistoryID(w)); } } diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 7e70019916c..19a40c62062 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -341,8 +341,8 @@ class CWindow { // swallowing CWindow* m_pSwallowed = nullptr; - CWindow* m_pPreviouslySwallowed = nullptr; CWindow* m_pSwallowedBy = nullptr; + bool m_bCurrentlySwallowing = false; // focus stuff bool m_bStayFocused = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 2ac198e7bd8..00d87078eaf 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -583,8 +583,9 @@ void Events::listener_mapWindow(void* owner, void* data) { // check if it's the window we want & not exempt from getting swallowed if (valid) { // swallow - PWINDOW->m_pSwallowed = finalFound; - finalFound->m_pSwallowedBy = PWINDOW; + PWINDOW->m_pSwallowed = finalFound; + finalFound->m_pSwallowedBy = PWINDOW; + PWINDOW->m_bCurrentlySwallowing = true; g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a703664f2c3..2aa5e0e5baa 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1823,25 +1823,24 @@ void CKeybindManager::focusWindow(std::string regexp) { void CKeybindManager::toggleSwallow(std::string args) { CWindow* pWindow = g_pCompositor->m_pLastWindow; - if (pWindow->m_pSwallowed) { - pWindow->m_pPreviouslySwallowed = pWindow->m_pSwallowed; - pWindow->m_pSwallowed->setHidden(false); + if (!pWindow->m_pSwallowed) + return; + if (pWindow->m_bCurrentlySwallowing) { + // Unswallow + pWindow->m_pSwallowed->setHidden(false); g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow->m_pSwallowed); - pWindow->m_pSwallowed->m_pSwallowedBy = nullptr; - pWindow->m_pSwallowed = nullptr; - - } else if (pWindow->m_pPreviouslySwallowed) { - pWindow->m_pSwallowed = pWindow->m_pPreviouslySwallowed; - pWindow->m_pSwallowed->m_pSwallowedBy = pWindow; - - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_pPreviouslySwallowed); - - pWindow->m_pPreviouslySwallowed->setHidden(true); + pWindow->m_bCurrentlySwallowing = false; + } else { + // Reswallow + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_pSwallowed); + pWindow->m_pSwallowed->setHidden(true); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pWindow->m_iMonitorID); + + pWindow->m_bCurrentlySwallowing = true; } }