# HG changeset patch # User Atarwn Gard # Date 1760448013 -18000 # Node ID 9a4656899644bb27f961bfdd8c18304628b5673b # Parent 7d783901ff7d061b56dc5f3ca15b680a4ca590a9 add backward window cycling with Win+Shift+Tab diff -r 7d783901ff7d -r 9a4656899644 default.config.h --- a/default.config.h Tue Oct 14 18:10:20 2025 +0500 +++ b/default.config.h Tue Oct 14 18:20:13 2025 +0500 @@ -52,6 +52,7 @@ { MOD, XK_q, killclient, {0} }, { MOD, XK_f, toggle_fullscreen, {0} }, { MOD, XK_Tab, cycle_focus, {0} }, + { MOD|ShiftMask, XK_Tab, cycle_focus_backward, {0} }, { MOD|ShiftMask, XK_q, quit, {0} }, // Workspaces diff -r 7d783901ff7d -r 9a4656899644 gbwm.c --- a/gbwm.c Tue Oct 14 18:10:20 2025 +0500 +++ b/gbwm.c Tue Oct 14 18:20:13 2025 +0500 @@ -72,6 +72,7 @@ static void hide_overlay(void); static void quit(const Arg *arg); static void cycle_focus(const Arg *arg); +static void cycle_focus_backward(const Arg *arg); static void grabkeys(void); static void setfullscreen(Client *c, int fullscreen); static int sendevent(Client *c, Atom proto); @@ -703,6 +704,37 @@ focus(next, 1); } +static void cycle_focus_backward(const Arg *arg) { + if (!workspaces[current_ws]) return; + + if (!focused) { + // If there is no focus, focus on the last window + Client *last = workspaces[current_ws]; + while (last && last->next) + last = last->next; + focus(last, 1); + return; + } + + // Find the previous window + Client *prev = NULL; + for (Client *c = workspaces[current_ws]; c; c = c->next) { + if (c->next == focused) { + prev = c; + break; + } + } + + // If focused is the first, then prev = the last + if (!prev) { + prev = workspaces[current_ws]; + while (prev && prev->next) + prev = prev->next; + } + + focus(prev, 1); +} + static void grabkeys(void) { XUngrabKey(dpy, AnyKey, AnyModifier, root); for (unsigned int i = 0; i < sizeof(keys) / sizeof(Key); i++) {