feat: dwindle movetoroot dispatch

This commit is contained in:
Ernesto Cruz 2026-05-26 13:25:35 +00:00
parent 887a50a54e
commit 35ccafb9d2
7 changed files with 75 additions and 2 deletions

View file

@ -147,9 +147,10 @@ bindr=Super,Super_L,spawn,rofi -show run
| `scroller_stack` | `left/right/up/down` | Move window inside/outside scroller stack by direction. | | `scroller_stack` | `left/right/up/down` | Move window inside/outside scroller stack by direction. |
| `incgaps` | `+/-value` | Adjust gap size. | | `incgaps` | `+/-value` | Adjust gap size. |
| `togglegaps` | - | Toggle gaps. | | `togglegaps` | - | Toggle gaps. |
| `dwindle_toggle_split_direction` | - | Toggle split direction in dwindle layout. | | `dwindle_toggle_split_direction` | - | Toggle split direction in dwindle layout. |
| `dwindle_split_horizontal` | - | Set split window direction to horizontal in dwindle layout. | | `dwindle_split_horizontal` | - | Set split window direction to horizontal in dwindle layout. |
| `dwindle_split_vertical` | - | Set split window direction to vertical in dwindle layout. | | `dwindle_split_vertical` | - | Set split window direction to vertical in dwindle layout. |
| `movetoroot` | `[active/id] [,unstable]` | Move selected window to the root of its dwindle tree. Add `unstable` to swap subtrees instead of default stable maximization. |
### System ### System

View file

@ -76,3 +76,4 @@ mmsg dispatch exchange_client,left client,375
# operate current client # operate current client
mmsg dispatch exchange_client,left mmsg dispatch exchange_client,left
```` ````

View file

@ -1256,10 +1256,21 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
func = dwindle_split_horizontal; func = dwindle_split_horizontal;
} else if (strcmp(func_name, "dwindle_split_vertical") == 0) { } else if (strcmp(func_name, "dwindle_split_vertical") == 0) {
func = dwindle_split_vertical; func = dwindle_split_vertical;
} else if (strcmp(func_name, "movetoroot") == 0) {
func = movetoroot;
bool unstable = false;
if (arg_value && strcmp(arg_value, "unstable") == 0) {
unstable = true;
}
if (arg_value2 && strcmp(arg_value2, "unstable") == 0) {
unstable = true;
}
(*arg).i = unstable ? 1 : 0;
} else { } else {
return NULL; return NULL;
} }
return func; return func;
} }
void set_env() { void set_env() {

View file

@ -75,3 +75,5 @@ int32_t dwindle_toggle_split_direction(const Arg *arg);
int32_t dwindle_split_horizontal(const Arg *arg); int32_t dwindle_split_horizontal(const Arg *arg);
int32_t dwindle_split_vertical(const Arg *arg); int32_t dwindle_split_vertical(const Arg *arg);
int32_t focusid(const Arg *arg); int32_t focusid(const Arg *arg);
int32_t movetoroot(const Arg *arg);

View file

@ -2003,3 +2003,20 @@ int32_t focusid(const Arg *arg) {
focusclient(c, 1); focusclient(c, 1);
return 0; return 0;
} }
int32_t movetoroot(const Arg *arg) {
if (!selmon)
return 0;
Client *c = arg->tc ? arg->tc : selmon->sel;
if (!c || c->isfloating)
return 0;
if (c->mon && c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == DWINDLE) {
uint32_t tag = c->mon->pertag->curtag;
bool stable = (arg->i == 0);
dwindle_movetoroot(&c->mon->pertag->dwindle_root[tag], c, stable);
arrange(c->mon, false, false);
}
return 0;
}

View file

@ -622,6 +622,45 @@ void dwindle(Monitor *m) {
gap_iv); gap_iv);
} }
static void dwindle_movetoroot(DwindleNode **root, Client *c, bool stable) {
if (!root || !*root || !c)
return;
DwindleNode *x = dwindle_find_leaf(*root, c);
if (!x || !x->parent)
return;
if (!x->parent->parent)
return;
DwindleNode **pNode =
(x->parent->first == x) ? &(x->parent->first) : &(x->parent->second);
DwindleNode *pAncestor = x;
DwindleNode *pRoot = x->parent;
while (pRoot->parent) {
pAncestor = pRoot;
pRoot = pRoot->parent;
}
DwindleNode **pSwap =
(pRoot->first == pAncestor) ? &(pRoot->second) : &(pRoot->first);
DwindleNode *temp = *pNode;
*pNode = *pSwap;
*pSwap = temp;
DwindleNode *parent_temp = (*pNode)->parent;
(*pNode)->parent = (*pSwap)->parent;
(*pSwap)->parent = parent_temp;
if (stable) {
DwindleNode *temp_root_child = pRoot->first;
pRoot->first = pRoot->second;
pRoot->second = temp_root_child;
}
}
void cleanup_monitor_dwindle(Monitor *m) { void cleanup_monitor_dwindle(Monitor *m) {
for (uint32_t t = 0; t < LENGTH(tags) + 1; t++) for (uint32_t t = 0; t < LENGTH(tags) + 1; t++)
dwindle_free_tree(m->pertag->dwindle_root[t]); dwindle_free_tree(m->pertag->dwindle_root[t]);

View file

@ -855,7 +855,9 @@ static void client_pending_maximized_state(Client *c, int32_t ismaximized);
static void client_pending_minimized_state(Client *c, int32_t isminimized); static void client_pending_minimized_state(Client *c, int32_t isminimized);
static void scroller_insert_stack(Client *c, Client *target_client, static void scroller_insert_stack(Client *c, Client *target_client,
bool insert_before); bool insert_before);
static void dwindle_movetoroot(DwindleNode **root, Client *c, bool stable);
static void dwindle_move_client(DwindleNode **root, Client *c, Client *target, static void dwindle_move_client(DwindleNode **root, Client *c, Client *target,
float ratio, int32_t dir); float ratio, int32_t dir);
static void dwindle_resize_client_step(Monitor *m, Client *c, int32_t dx, static void dwindle_resize_client_step(Monitor *m, Client *c, int32_t dx,
int32_t dy); int32_t dy);