Skip to content

Commit

Permalink
dwindle: add movetoroot method to layout messages (#7903)
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeXuan committed Sep 29, 2024
1 parent 9e41867 commit 4b00cba
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/layout/DwindleLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/layout/DwindleLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class CHyprDwindleLayout : public IHyprLayout {

void toggleSplit(PHLWINDOW);
void swapSplit(PHLWINDOW);
void moveToRoot(PHLWINDOW, bool stable = true);

eDirection overrideDirection = DIRECTION_DEFAULT;

Expand Down

0 comments on commit 4b00cba

Please sign in to comment.