Here a patch which adjusts dwm to my personal taste, but maybe others find it useful as well.
First, I missed a function in dwm which allows me to quickly go back in the list of windows in the order in which they were focused. Dwm already records the focus history, but there was no way to access it explicitly. The attached patch introduces a function cycleglobal() which goes back and forth in the recent focus history. Pressing Mod-Ctrl-j a couple of times now takes you back through your recently focused windows. If you went to far type Mod-Ctrl-k to go forward again. The second function cycletiled() is mostly useful in tiled layout. Essentially Mod-Shift-j now rotates the positions of all windows in tiled mode clockwise, but leaves the focus in the same spot on the screen. So if you start with a layout with four windows A B C D as follows (C has focus) ------------------------------------- | | | | | B | | |----------------| | | | | A | C* | | |----------------| | | | | | D | |------------------|----------------| the result of pressing Mod-Shift-j is ------------------------------------- | | | | | C | | |----------------| | | | | B | D* | | |----------------| | | | | | A | |------------------|----------------| Now D has focus. Mod-Shift-k does the opposite. Andreas
# HG changeset patch # Parent dfd36140a7bcac030bf22a2e81892c0bf3bb52a6 cycle through focus stack diff --git a/config.def.h b/config.def.h --- a/config.def.h +++ b/config.def.h @@ -60,6 +60,10 @@ { MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY|ShiftMask, XK_j, cycletiled, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, cycletiled, {.i = -1 } }, + { MODKEY|ControlMask, XK_j, cycleglobal, {.i = +1 } }, + { MODKEY|ControlMask, XK_k, cycleglobal, {.i = -1 } }, { MODKEY, XK_i, incnmaster, {.i = +1 } }, { MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, diff --git a/dwm.c b/dwm.c --- a/dwm.c +++ b/dwm.c @@ -173,6 +173,8 @@ static void configurenotify(XEvent *e); static void configurerequest(XEvent *e); static Monitor *createmon(void); +static void cycleglobal(const Arg *arg); +static void cycletiled(const Arg *arg); static void destroynotify(XEvent *e); static void detach(Client *c); static void detachstack(Client *c); @@ -644,6 +646,61 @@ XSync(dpy, False); } +void +cycleglobal(const Arg *arg) +{ + Client *c = selmon->stack, *cn; + + if(!c) + return; + + if (c->snext) { + unfocus(selmon->sel,False); + + for(cn = c; cn->snext; cn = cn->snext); + + if (arg->i > 0) { + if (selmon->sel) { + cn->snext = selmon->stack; + c = selmon->stack = selmon->stack->snext; + cn->snext->snext = NULL; + } + } else { + c = cn; + } + } + + if(!ISVISIBLE(c)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; + } + focus(c); + arrange(c->mon); +} + +void +cycletiled(const Arg *arg) +{ + Client *c = nexttiled(selmon->clients),*cn; + if(!selmon->lt[selmon->sellt]->arrange || !c || !(cn=nexttiled(c->next))) + return; + + if (arg->i > 0) { + detach(c); + for(; cn->next; cn = cn->next); + cn->next = c; + c->next = NULL; + c = nexttiled(selmon->clients); + + } else { + for(c=cn; (cn=nexttiled(cn->next)) != NULL; c=cn); + detach(c); + attach(c); + } + focusstack(arg); + arrange(c->mon); +} + Monitor * createmon(void) { Monitor *m;