Author: Eric Pruitt, https://github.com/jameseric/ Description: Switch focus between the currently focused window and a previously focused window. This is a rewrite of the swapfocus patch at http://dwm.suckless.org/patches/swapfocus, but attempts (given the nature of tags in dwm, it is not trivial to implement focus history for every combination of previously selected set of tags) to keep focus history on a per tag basis. --- a/dwm.c 2012-11-25 10:18:52.000000000 -0600 +++ b/dwm.c 2012-11-25 14:30:57.000000000 -0600 @@ -143,6 +143,7 @@ Monitor *next; Window barwin; const Layout *lt[2]; + Client *prevclient[32]; }; typedef struct { @@ -224,6 +225,7 @@ static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); +static void swapfocus(); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static int textnw(const char *text, unsigned int len); @@ -657,6 +659,7 @@ m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + for(int i = 0; i < 31; i++, m->prevclient[i] = NULL); return m; } @@ -844,6 +847,12 @@ focus(Client *c) { if(!c || !ISVISIBLE(c)) for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); + else { + int n = 0, i; + for (i = c->tags & c->mon->tagset[c->mon->seltags]; i; i >>= 1, n++); + if (selmon->sel != selmon->prevclient[n - 1]) + selmon->prevclient[n - 1] = selmon->sel; + } /* was if(selmon->sel) */ if(selmon->sel && selmon->sel != c) unfocus(selmon->sel, False); @@ -1675,6 +1684,14 @@ } void +swapfocus() { + Client *c = selmon->sel; + int n = 0, i; + for (i = c->tags & c->mon->tagset[c->mon->seltags]; i; i >>= 1, n++); + if(n) focus(selmon->prevclient[n - 1]); +} + +void tag(const Arg *arg) { if(selmon->sel && arg->ui & TAGMASK) { selmon->sel->tags = arg->ui & TAGMASK;