aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorLuke Chen <[email protected]>2024-09-29 09:47:59 -0400
committerGitHub <[email protected]>2024-09-29 14:47:59 +0100
commit4b00cba319dc44294567d06df7c378cf5e4e5338 (patch)
tree8753e88471e110964e14805fc39a3c034b2e0f40 /src
parent9e418671e12549156d0735a6b23732f66d5647c7 (diff)
downloadHyprland-4b00cba319dc44294567d06df7c378cf5e4e5338.tar.gz
Hyprland-4b00cba319dc44294567d06df7c378cf5e4e5338.zip
dwindle: add movetoroot method to layout messages (#7903)
Diffstat (limited to 'src')
-rw-r--r--src/layout/DwindleLayout.cpp42
-rw-r--r--src/layout/DwindleLayout.hpp1
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;