From caa8b05f38df37429518f54bafde4546f6826525 Mon Sep 17 00:00:00 2001 From: Eslam Mohamed Abdelghany Date: Mon, 2 Mar 2026 15:01:57 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20split=20switch?= =?UTF-8?q?=5Flayout=20into=20next=5Flayout=20and=20previous=5Flayout=20fu?= =?UTF-8?q?nctions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add next_layout() to cycle forward through layouts - Add previous_layout() to cycle backward through layouts - Keep switch_layout() as backward-compatible alias to next_layout() - Update config.conf with example keybinds for both new functions --- assets/config.conf | 3 ++- src/config/parse_config.h | 4 ++++ src/dispatch/bind_declare.h | 2 ++ src/dispatch/bind_define.h | 42 +++++++++++++++++++++++++++++-------- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/assets/config.conf b/assets/config.conf index 15b654c1..dd08c281 100644 --- a/assets/config.conf +++ b/assets/config.conf @@ -183,7 +183,8 @@ bind=ALT,e,set_proportion,1.0 bind=ALT,x,switch_proportion_preset, # switch layout -bind=SUPER,n,switch_layout +bind=SUPER,n,next_layout +bind=SUPER+SHIFT,n,previous_layout # tag switch bind=SUPER,Left,viewtoleft,0 diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b4fb37e9..5dd5f483 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1021,6 +1021,10 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "setlayout") == 0) { func = setlayout; (*arg).v = strdup(arg_value); + } else if (strcmp(func_name, "next_layout") == 0) { + func = next_layout; + } else if (strcmp(func_name, "previous_layout") == 0) { + func = previous_layout; } else if (strcmp(func_name, "switch_layout") == 0) { func = switch_layout; } else if (strcmp(func_name, "togglefloating") == 0) { diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index 22ef6123..6d084472 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -26,6 +26,8 @@ int32_t spawn_on_empty(const Arg *arg); int32_t setkeymode(const Arg *arg); int32_t switch_keyboard_layout(const Arg *arg); int32_t setlayout(const Arg *arg); +int32_t next_layout(const Arg *arg); +int32_t previous_layout(const Arg *arg); int32_t switch_layout(const Arg *arg); int32_t setmfact(const Arg *arg); int32_t quit(const Arg *arg); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 5cf41d6c..ab352061 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -973,8 +973,8 @@ int32_t switch_keyboard_layout(const Arg *arg) { return 0; } -int32_t switch_layout(const Arg *arg) { - +// Internal helper: direction > 0 means next, direction < 0 means previous +static int32_t _switch_layout_dir(int direction) { int32_t jk, ji; char *target_layout_name = NULL; uint32_t len; @@ -984,7 +984,6 @@ int32_t switch_layout(const Arg *arg) { if (config.circle_layout_count != 0) { for (jk = 0; jk < config.circle_layout_count; jk++) { - len = MAX( strlen(config.circle_layout[jk]), strlen(selmon->pertag->ltidxs[selmon->pertag->curtag]->name)); @@ -992,9 +991,19 @@ int32_t switch_layout(const Arg *arg) { if (strncmp(config.circle_layout[jk], selmon->pertag->ltidxs[selmon->pertag->curtag]->name, len) == 0) { - target_layout_name = jk == config.circle_layout_count - 1 - ? config.circle_layout[0] - : config.circle_layout[jk + 1]; + if (direction > 0) { + // next: wrap forward + target_layout_name = (jk == config.circle_layout_count - 1) + ? config.circle_layout[0] + : config.circle_layout[jk + 1]; + } else { + // previous: wrap backward + target_layout_name = + (jk == 0) + ? config + .circle_layout[config.circle_layout_count - 1] + : config.circle_layout[jk - 1]; + } break; } } @@ -1007,7 +1016,6 @@ int32_t switch_layout(const Arg *arg) { len = MAX(strlen(layouts[ji].name), strlen(target_layout_name)); if (strncmp(layouts[ji].name, target_layout_name, len) == 0) { selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[ji]; - break; } } @@ -1017,11 +1025,21 @@ int32_t switch_layout(const Arg *arg) { return 0; } + // Fallback: iterate through global layouts[] for (jk = 0; jk < LENGTH(layouts); jk++) { if (strcmp(layouts[jk].name, selmon->pertag->ltidxs[selmon->pertag->curtag]->name) == 0) { - selmon->pertag->ltidxs[selmon->pertag->curtag] = - jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; + if (direction > 0) { + // next: wrap forward + selmon->pertag->ltidxs[selmon->pertag->curtag] = + (jk == LENGTH(layouts) - 1) ? &layouts[0] + : &layouts[jk + 1]; + } else { + // previous: wrap backward + selmon->pertag->ltidxs[selmon->pertag->curtag] = + (jk == 0) ? &layouts[LENGTH(layouts) - 1] + : &layouts[jk - 1]; + } clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false, false); printstatus(); @@ -1031,6 +1049,12 @@ int32_t switch_layout(const Arg *arg) { return 0; } +int32_t next_layout(const Arg *arg) { return _switch_layout_dir(1); } + +int32_t previous_layout(const Arg *arg) { return _switch_layout_dir(-1); } + +int32_t switch_layout(const Arg *arg) { return next_layout(arg); } + int32_t switch_proportion_preset(const Arg *arg) { float target_proportion = 0; if (!selmon)