dwm-swapfocus-6.2.diff (6051B)
1 diff -up a/config.def.h b/config.def.h 2 --- a/config.def.h 2020-01-29 00:06:12.415681126 +0100 3 +++ b/config.def.h 2020-01-29 13:25:14.167910093 +0100 4 @@ -66,6 +66,7 @@ static Key keys[] = { 5 { MODKEY, XK_b, togglebar, {0} }, 6 { MODKEY, XK_j, focusstack, {.i = +1 } }, 7 { MODKEY, XK_k, focusstack, {.i = -1 } }, 8 + { MODKEY, XK_s, swapfocus, {.i = -1 } }, 9 { MODKEY, XK_i, incnmaster, {.i = +1 } }, 10 { MODKEY, XK_d, incnmaster, {.i = -1 } }, 11 { MODKEY, XK_h, setmfact, {.f = -0.05} }, 12 diff -up a/dwm.c b/dwm.c 13 --- a/dwm.c 2020-01-29 00:06:12.419014466 +0100 14 +++ b/dwm.c 2020-01-29 13:27:20.012744075 +0100 15 @@ -111,6 +111,7 @@ typedef struct { 16 void (*arrange)(Monitor *); 17 } Layout; 18 19 +typedef struct Pertag Pertag; 20 struct Monitor { 21 char ltsymbol[16]; 22 float mfact; 23 @@ -130,6 +131,7 @@ struct Monitor { 24 Monitor *next; 25 Window barwin; 26 const Layout *lt[2]; 27 + Pertag *pertag; 28 }; 29 30 typedef struct { 31 @@ -206,6 +208,7 @@ static void seturgent(Client *c, int urg 32 static void showhide(Client *c); 33 static void sigchld(int unused); 34 static void spawn(const Arg *arg); 35 +static void swapfocus(const Arg *arg); 36 static void tag(const Arg *arg); 37 static void tagmon(const Arg *arg); 38 static void tile(Monitor *); 39 @@ -271,6 +274,11 @@ static Window root, wmcheckwin; 40 /* configuration, allows nested code to access above variables */ 41 #include "config.h" 42 43 +struct Pertag { 44 + unsigned int curtag, prevtag; /* current and previous tag */ 45 + Client *prevclient[LENGTH(tags) + 1]; 46 +}; 47 + 48 /* compile-time check if all tags fit into an unsigned int bit array. */ 49 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 50 51 @@ -641,6 +649,8 @@ createmon(void) 52 m->lt[0] = &layouts[0]; 53 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 54 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 55 + m->pertag = ecalloc(1, sizeof(Pertag)); 56 + m->pertag->curtag = m->pertag->prevtag = 1; 57 return m; 58 } 59 60 @@ -1012,6 +1022,7 @@ killclient(const Arg *arg) 61 XSetErrorHandler(xerror); 62 XUngrabServer(dpy); 63 } 64 + selmon->pertag->prevclient[selmon->pertag->curtag] = NULL; 65 } 66 67 void 68 @@ -1653,11 +1664,41 @@ spawn(const Arg *arg) 69 } 70 71 void 72 +swapfocus(const Arg *arg) 73 +{ 74 + if (!selmon->sel) 75 + return; 76 + if(selmon->pertag->prevclient[selmon->pertag->curtag] != NULL 77 + && ISVISIBLE(selmon->pertag->prevclient[selmon->pertag->curtag])){ 78 + focus(selmon->pertag->prevclient[selmon->pertag->curtag]); 79 + restack(selmon->pertag->prevclient[selmon->pertag->curtag]->mon); 80 + } 81 + else{ 82 + Client *c = NULL; 83 + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); 84 + if (!c) 85 + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); 86 + if (c) { 87 + focus(c); 88 + restack(selmon); 89 + } 90 + } 91 +} 92 + 93 +void 94 tag(const Arg *arg) 95 { 96 + unsigned int tagmask, tagindex; 97 + 98 if (selmon->sel && arg->ui & TAGMASK) { 99 selmon->sel->tags = arg->ui & TAGMASK; 100 focus(NULL); 101 + 102 + selmon->pertag->prevclient[selmon->pertag->curtag] = NULL; 103 + for(tagmask = arg->ui & TAGMASK, tagindex = 1; tagmask!=0; tagmask >>= 1, tagindex++) 104 + if(tagmask & 1) 105 + selmon->pertag->prevclient[tagindex] = NULL; 106 + 107 arrange(selmon); 108 } 109 } 110 @@ -1722,7 +1763,7 @@ togglefloating(const Arg *arg) 111 void 112 toggletag(const Arg *arg) 113 { 114 - unsigned int newtags; 115 + unsigned int newtags, tagmask, tagindex; 116 117 if (!selmon->sel) 118 return; 119 @@ -1730,6 +1771,11 @@ toggletag(const Arg *arg) 120 if (newtags) { 121 selmon->sel->tags = newtags; 122 focus(NULL); 123 + 124 + for(tagmask = arg->ui & TAGMASK, tagindex = 1; tagmask!=0; tagmask >>= 1, tagindex++) 125 + if(tagmask & 1) 126 + selmon->pertag->prevclient[tagindex] = NULL; 127 + 128 arrange(selmon); 129 } 130 } 131 @@ -1738,9 +1784,22 @@ void 132 toggleview(const Arg *arg) 133 { 134 unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 135 + int i; 136 137 if (newtagset) { 138 selmon->tagset[selmon->seltags] = newtagset; 139 + 140 + if (newtagset == ~0) { 141 + selmon->pertag->prevtag = selmon->pertag->curtag; 142 + selmon->pertag->curtag = 0; 143 + } 144 + 145 + /* test if the user did not select the same tag */ 146 + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { 147 + selmon->pertag->prevtag = selmon->pertag->curtag; 148 + for (i = 0; !(newtagset & 1 << i); i++) ; 149 + selmon->pertag->curtag = i + 1; 150 + } 151 focus(NULL); 152 arrange(selmon); 153 } 154 @@ -1751,6 +1810,7 @@ unfocus(Client *c, int setfocus) 155 { 156 if (!c) 157 return; 158 + selmon->pertag->prevclient[selmon->pertag->curtag] = c; 159 grabbuttons(c, 0); 160 XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); 161 if (setfocus) { 162 @@ -2035,12 +2095,30 @@ updatewmhints(Client *c) 163 void 164 view(const Arg *arg) 165 { 166 + int i; 167 + unsigned int tmptag; 168 + 169 if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 170 return; 171 selmon->seltags ^= 1; /* toggle sel tagset */ 172 - if (arg->ui & TAGMASK) 173 + if (arg->ui & TAGMASK){ 174 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 175 + selmon->pertag->prevtag = selmon->pertag->curtag; 176 + 177 + if (arg->ui == ~0) 178 + selmon->pertag->curtag = 0; 179 + else { 180 + for (i = 0; !(arg->ui & 1 << i); i++) ; 181 + selmon->pertag->curtag = i + 1; 182 + } 183 + } else { 184 + tmptag = selmon->pertag->prevtag; 185 + selmon->pertag->prevtag = selmon->pertag->curtag; 186 + selmon->pertag->curtag = tmptag; 187 + } 188 + Client *unmodified = selmon->pertag->prevclient[selmon->pertag->curtag]; 189 focus(NULL); 190 + selmon->pertag->prevclient[selmon->pertag->curtag] = unmodified; 191 arrange(selmon); 192 } 193 194 @@ -2114,12 +2192,13 @@ void 195 zoom(const Arg *arg) 196 { 197 Client *c = selmon->sel; 198 + selmon->pertag->prevclient[selmon->pertag->curtag] = nexttiled(selmon->clients); 199 200 if (!selmon->lt[selmon->sellt]->arrange 201 || (selmon->sel && selmon->sel->isfloating)) 202 return; 203 if (c == nexttiled(selmon->clients)) 204 - if (!c || !(c = nexttiled(c->next))) 205 + if (!c || !(c = selmon->pertag->prevclient[selmon->pertag->curtag] = nexttiled(c->next))) 206 return; 207 pop(c); 208 }