diff --git a/docs/bindings/keys.md b/docs/bindings/keys.md index b3a4ab64..b756082f 100644 --- a/docs/bindings/keys.md +++ b/docs/bindings/keys.md @@ -145,6 +145,8 @@ bindr=Super,Super_L,spawn,rofi -show run | `set_proportion` | `float` | Set scroller window proportion (0.0–1.0). | | `switch_proportion_preset` | - | Cycle proportion presets of scroller window. | | `scroller_stack` | `left/right/up/down` | Move window inside/outside scroller stack by direction. | +| `scroller_stack_consume` | - | Add the adjacent neighbor into the current stack. | +| `scroller_stack_expel` | - | Remove the last window from the current stack. | | `incgaps` | `+/-value` | Adjust gap size. | | `togglegaps` | - | Toggle gaps. | diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 006968f0..01bb9baf 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1221,6 +1221,10 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "scroller_stack") == 0) { func = scroller_stack; (*arg).i = parse_direction(arg_value); + } else if (strcmp(func_name, "scroller_stack_consume") == 0) { + func = scroller_stack_consume; + } else if (strcmp(func_name, "scroller_stack_expel") == 0) { + func = scroller_stack_expel; } else if (strcmp(func_name, "toggle_all_floating") == 0) { func = toggle_all_floating; } else { diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index dbeebd33..7fac6522 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -70,4 +70,6 @@ int32_t disable_monitor(const Arg *arg); int32_t enable_monitor(const Arg *arg); int32_t toggle_monitor(const Arg *arg); int32_t scroller_stack(const Arg *arg); +int32_t scroller_stack_consume(const Arg *arg); +int32_t scroller_stack_expel(const Arg *arg); int32_t toggle_all_floating(const Arg *arg); \ No newline at end of file diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 3c1d2154..4ee8f35a 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1866,6 +1866,55 @@ int32_t scroller_stack(const Arg *arg) { return scroller_apply_stack(c, target_client, arg->i); } +int32_t scroller_stack_consume(const Arg *arg) { + if (!selmon) + return 0; + Client *c = selmon->sel; + if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon)) + return 0; + + bool is_horizontal_layout = + c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER; + int32_t consume_dir = is_horizontal_layout ? RIGHT : DOWN; + + Client *target_client = find_client_by_direction(c, &(Arg){.i = consume_dir}, false, true); + + if (target_client) { + Client *stack_tail = get_scroll_stack_head(c); + while (stack_tail->next_in_stack) { + stack_tail = stack_tail->next_in_stack; + } + + if (target_client != stack_tail) { + scroller_insert_stack(target_client, stack_tail, false); + } + } + return 0; +} + +int32_t scroller_stack_expel(const Arg *arg) { + if (!selmon) + return 0; + Client *c = selmon->sel; + if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon)) + return 0; + + Client *stack_head = get_scroll_stack_head(c); + Client *stack_tail = stack_head; + + while (stack_tail->next_in_stack) { + stack_tail = stack_tail->next_in_stack; + } + + if (stack_tail != stack_head) { + exit_scroller_stack(stack_tail); + wl_list_remove(&stack_tail->link); + wl_list_insert(&stack_head->link, &stack_tail->link); + arrange(selmon, false, false); + } + return 0; +} + int32_t toggle_all_floating(const Arg *arg) { if (!selmon || !selmon->sel) return 0;