Adds stack bounded stack navigation functions

This commit is contained in:
Jon H 2026-03-18 06:17:07 -07:00
parent ccefa572e1
commit fd8382a82c
3 changed files with 58 additions and 2 deletions

View file

@ -938,7 +938,10 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
if (strcmp(func_name, "focusstack") == 0) {
func = focusstack;
(*arg).i = parse_circle_direction(arg_value);
} else if (strcmp(func_name, "focusdir") == 0) {
} else if (strcmp(func_name, "focusstack_bounded") == 0) {
func = focusstack_bounded;
(*arg).i = parse_circle_direction(arg_value);
} else if (strcmp(func_name, "focusdir") == 0) {
func = focusdir;
(*arg).i = parse_direction(arg_value);
} else if (strcmp(func_name, "incnmaster") == 0) {
@ -955,7 +958,10 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
} else if (strcmp(func_name, "exchange_stack_client") == 0) {
func = exchange_stack_client;
(*arg).i = parse_circle_direction(arg_value);
} else if (strcmp(func_name, "toggleglobal") == 0) {
} else if (strcmp(func_name, "exchange_stack_client_bounded") == 0) {
func = exchange_stack_client_bounded;
(*arg).i = parse_circle_direction(arg_value);
} else if (strcmp(func_name, "toggleglobal") == 0) {
func = toggleglobal;
} else if (strcmp(func_name, "toggleoverview") == 0) {
func = toggleoverview;

View file

@ -32,11 +32,13 @@ int32_t quit(const Arg *arg);
int32_t moveresize(const Arg *arg);
int32_t exchange_client(const Arg *arg);
int32_t exchange_stack_client(const Arg *arg);
int32_t exchange_stack_client_bounded(const Arg *arg);
int32_t killclient(const Arg *arg);
int32_t toggleglobal(const Arg *arg);
int32_t incnmaster(const Arg *arg);
int32_t focusmon(const Arg *arg);
int32_t focusstack(const Arg *arg);
int32_t focusstack_bounded(const Arg *arg);
int32_t chvt(const Arg *arg);
int32_t reload_config(const Arg *arg);
int32_t smartmovewin(const Arg *arg);

View file

@ -134,6 +134,27 @@ int32_t exchange_stack_client(const Arg *arg) {
return 0;
}
int32_t exchange_stack_client_bounded(const Arg *arg) {
if (!selmon)
return 0;
Client *c = selmon->sel;
Client *tc = NULL;
if (!c || c->isfloating || c->isfullscreen || c->ismaximizescreen)
return 0;
/* again, lazy we just search once more if we found master */
if (arg->i == NEXT) {
tc = get_next_stack_client(c, false);
if (tc && tc->ismaster) tc = get_next_stack_client(tc, false);
} else {
tc = get_next_stack_client(c, true);
if (tc && tc->ismaster) tc = get_next_stack_client(tc, true);
}
if (tc)
exchange_two_client(c, tc);
return 0;
}
int32_t focusdir(const Arg *arg) {
Client *c = NULL;
c = direction_select(arg);
@ -263,6 +284,33 @@ int32_t focusstack(const Arg *arg) {
return 0;
}
int32_t focusstack_bounded(const Arg *arg) {
/* Focus the next or previous client (in tiling order) on selmon */
/* but skipping past master */
Client *sel = focustop(selmon);
Client *tc = NULL;
if (!sel)
return 0;
/* lazy fix we just search twice, don't make new deeper functions */
if (arg->i == NEXT) {
tc = get_next_stack_client(sel, false);
if (tc && tc->ismaster) tc = get_next_stack_client(tc, false);
} else {
tc = get_next_stack_client(sel, true);
if (tc && tc->ismaster) tc = get_next_stack_client(tc, true);
}
/* If only one client is visible on selmon, then c == sel */
if (!tc)
return 0;
focusclient(tc, 1);
if (config.warpcursor)
warp_cursor(tc);
return 0;
}
int32_t incnmaster(const Arg *arg) {
if (!arg || !selmon)
return 0;