From d5950f7719d3c9ec5305208265366df5ce81b6c3 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 14 Feb 2024 18:58:28 +0100 Subject: [PATCH] dwindle: add swapsplit dispatcher (#4702) This is distinct from `swapwindow` in that it allows swapping the entire tree node with its neighbour. Fixes: https://github.com/hyprwm/Hyprland/issues/4701 --- src/layout/DwindleLayout.cpp | 16 ++++++++++++++++ src/layout/DwindleLayout.hpp | 1 + src/managers/KeybindManager.cpp | 16 ++++++++++++++++ src/managers/KeybindManager.hpp | 1 + 4 files changed, 34 insertions(+) diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 11be13ae..9db011d1 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -996,6 +996,8 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str const auto ARGS = CVarList(message, 0, ' '); if (ARGS[0] == "togglesplit") { toggleSplit(header.pWindow); + } else if (ARGS[0] == "swapsplit") { + swapSplit(header.pWindow); } else if (ARGS[0] == "preselect") { std::string direction = ARGS[1]; @@ -1049,6 +1051,20 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) { PNODE->pParent->recalcSizePosRecursive(); } +void CHyprDwindleLayout::swapSplit(CWindow* pWindow) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE || !PNODE->pParent) + return; + + if (pWindow->m_bIsFullscreen) + return; + + std::swap(PNODE->pParent->children[0], PNODE->pParent->children[1]); + + PNODE->pParent->recalcSizePosRecursive(); +} + void CHyprDwindleLayout::replaceWindowDataWith(CWindow* from, CWindow* to) { const auto PNODE = getNodeFromWindow(from); diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index 780dd121..f5501b28 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -83,6 +83,7 @@ class CHyprDwindleLayout : public IHyprLayout { SDwindleNodeData* getMasterNodeOnWorkspace(const int&); void toggleSplit(CWindow*); + void swapSplit(CWindow*); eDirection overrideDirection = DIRECTION_DEFAULT; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index db6bbbbc..8e7418fb 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -39,6 +39,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["changegroupactive"] = changeGroupActive; m_mDispatchers["movegroupwindow"] = moveGroupWindow; m_mDispatchers["togglesplit"] = toggleSplit; + m_mDispatchers["swapsplit"] = swapSplit; m_mDispatchers["splitratio"] = alterSplitRatio; m_mDispatchers["focusmonitor"] = focusMonitor; m_mDispatchers["movecursortocorner"] = moveCursorToCorner; @@ -1286,6 +1287,21 @@ void CKeybindManager::toggleSplit(std::string args) { g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "togglesplit"); } +void CKeybindManager::swapSplit(std::string args) { + SLayoutMessageHeader header; + header.pWindow = g_pCompositor->m_pLastWindow; + + if (!header.pWindow) + return; + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + + if (PWORKSPACE->m_bHasFullscreenWindow) + return; + + g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "swapsplit"); +} + void CKeybindManager::alterSplitRatio(std::string args) { std::optional splitResult; bool exact = false; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 7ca43ec1..7022593a 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -127,6 +127,7 @@ class CKeybindManager { static void alterSplitRatio(std::string); static void focusMonitor(std::string); static void toggleSplit(std::string); + static void swapSplit(std::string); static void moveCursorToCorner(std::string); static void moveCursor(std::string); static void workspaceOpt(std::string);