diff options
author | Luke Chen <[email protected]> | 2024-09-29 09:47:59 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2024-09-29 14:47:59 +0100 |
commit | 4b00cba319dc44294567d06df7c378cf5e4e5338 (patch) | |
tree | 8753e88471e110964e14805fc39a3c034b2e0f40 | |
parent | 9e418671e12549156d0735a6b23732f66d5647c7 (diff) | |
download | Hyprland-4b00cba319dc44294567d06df7c378cf5e4e5338.tar.gz Hyprland-4b00cba319dc44294567d06df7c378cf5e4e5338.zip |
dwindle: add movetoroot method to layout messages (#7903)
-rw-r--r-- | src/layout/DwindleLayout.cpp | 42 | ||||
-rw-r--r-- | src/layout/DwindleLayout.hpp | 1 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 69b044b4..ed47fa44 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -998,6 +998,10 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str toggleSplit(header.pWindow); } else if (ARGS[0] == "swapsplit") { swapSplit(header.pWindow); + } else if (ARGS[0] == "movetoroot") { + const auto WINDOW = ARGS[1].empty() ? header.pWindow : g_pCompositor->getWindowByRegex(ARGS[1]); + const auto STABLE = ARGS[2].empty() || ARGS[2] != "unstable"; + moveToRoot(WINDOW, STABLE); } else if (ARGS[0] == "preselect") { std::string direction = ARGS[1]; @@ -1065,6 +1069,44 @@ void CHyprDwindleLayout::swapSplit(PHLWINDOW pWindow) { PNODE->pParent->recalcSizePosRecursive(); } +// goal: maximize the chosen window within current dwindle layout +// impl: swap the selected window with the other sub-tree below root +void CHyprDwindleLayout::moveToRoot(PHLWINDOW pWindow, bool stable) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE || !PNODE->pParent) + return; + + if (pWindow->isFullscreen()) + return; + + // already at root + if (!PNODE->pParent->pParent) + return; + + auto& pNode = PNODE->pParent->children[0] == PNODE ? PNODE->pParent->children[0] : PNODE->pParent->children[1]; + + // instead of [getMasterNodeOnWorkspace], we walk back to root since we need + // to know which children of root is our ancestor + auto pAncestor = PNODE, pRoot = PNODE->pParent; + while (pRoot->pParent) { + pAncestor = pRoot; + pRoot = pRoot->pParent; + } + + auto& pSwap = pRoot->children[0] == pAncestor ? pRoot->children[1] : pRoot->children[0]; + std::swap(pNode, pSwap); + std::swap(pNode->pParent, pSwap->pParent); + + // [stable] in that the focused window occupies same side of screen + if (stable) + std::swap(pRoot->children[0], pRoot->children[1]); + + // if the workspace is visible, recalculate layout + if (g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) + pRoot->recalcSizePosRecursive(); +} + void CHyprDwindleLayout::replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) { const auto PNODE = getNodeFromWindow(from); diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index bbd511c2..953ba3a2 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -87,6 +87,7 @@ class CHyprDwindleLayout : public IHyprLayout { void toggleSplit(PHLWINDOW); void swapSplit(PHLWINDOW); + void moveToRoot(PHLWINDOW, bool stable = true); eDirection overrideDirection = DIRECTION_DEFAULT; |