dwm-holdbar-modkey-pertag-nobar-6.2.diff (8824B)
1 diff --git a/config.def.h b/config.def.h 2 index 1c0b587..f3d9b45 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -50,6 +50,7 @@ static const Layout layouts[] = { 6 { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 7 { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 8 { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 9 +#define HOLDKEY 0xffe9 // 0 - disable; 0xffe9 - Mod1Mask; 0xffeb - Mod4Mask 10 11 /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 12 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 13 @@ -94,6 +95,7 @@ static Key keys[] = { 14 TAGKEYS( XK_8, 7) 15 TAGKEYS( XK_9, 8) 16 { MODKEY|ShiftMask, XK_q, quit, {0} }, 17 + { 0, HOLDKEY, holdbar, {0} }, 18 }; 19 20 /* button definitions */ 21 diff --git a/dwm.c b/dwm.c 22 index 4465af1..4e5afa8 100644 23 --- a/dwm.c 24 +++ b/dwm.c 25 @@ -111,6 +111,7 @@ typedef struct { 26 void (*arrange)(Monitor *); 27 } Layout; 28 29 +typedef struct Pertag Pertag; 30 struct Monitor { 31 char ltsymbol[16]; 32 float mfact; 33 @@ -130,6 +131,7 @@ struct Monitor { 34 Monitor *next; 35 Window barwin; 36 const Layout *lt[2]; 37 + Pertag *pertag; 38 }; 39 40 typedef struct { 41 @@ -176,6 +178,7 @@ static void grabbuttons(Client *c, int focused); 42 static void grabkeys(void); 43 static void incnmaster(const Arg *arg); 44 static void keypress(XEvent *e); 45 +static void keyrelease(XEvent *e); 46 static void killclient(const Arg *arg); 47 static void manage(Window w, XWindowAttributes *wa); 48 static void mappingnotify(XEvent *e); 49 @@ -210,6 +213,7 @@ static void tag(const Arg *arg); 50 static void tagmon(const Arg *arg); 51 static void tile(Monitor *); 52 static void togglebar(const Arg *arg); 53 +static void holdbar(const Arg *arg); 54 static void togglefloating(const Arg *arg); 55 static void toggletag(const Arg *arg); 56 static void toggleview(const Arg *arg); 57 @@ -217,6 +221,7 @@ static void unfocus(Client *c, int setfocus); 58 static void unmanage(Client *c, int destroyed); 59 static void unmapnotify(XEvent *e); 60 static void updatebarpos(Monitor *m); 61 +static void updateholdbarpos(Monitor *m); 62 static void updatebars(void); 63 static void updateclientlist(void); 64 static int updategeom(void); 65 @@ -245,6 +250,7 @@ static int (*xerrorxlib)(Display *, XErrorEvent *); 66 static unsigned int numlockmask = 0; 67 static void (*handler[LASTEvent]) (XEvent *) = { 68 [ButtonPress] = buttonpress, 69 + [ButtonRelease] = keyrelease, 70 [ClientMessage] = clientmessage, 71 [ConfigureRequest] = configurerequest, 72 [ConfigureNotify] = configurenotify, 73 @@ -252,6 +258,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { 74 [EnterNotify] = enternotify, 75 [Expose] = expose, 76 [FocusIn] = focusin, 77 + [KeyRelease] = keyrelease, 78 [KeyPress] = keypress, 79 [MappingNotify] = mappingnotify, 80 [MapRequest] = maprequest, 81 @@ -271,10 +278,62 @@ static Window root, wmcheckwin; 82 /* configuration, allows nested code to access above variables */ 83 #include "config.h" 84 85 +struct Pertag { 86 + unsigned int curtag, prevtag; /* current and previous tag */ 87 + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ 88 + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ 89 + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ 90 + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ 91 +}; 92 + 93 /* compile-time check if all tags fit into an unsigned int bit array. */ 94 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 95 96 /* function implementations */ 97 +void 98 +holdbar(const Arg *arg) 99 +{ 100 + if (selmon->showbar) 101 + return; 102 + selmon->showbar = 2; 103 + updateholdbarpos(selmon); 104 + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 105 +} 106 + 107 +void 108 +keyrelease(XEvent *e) 109 +{ 110 + if (XEventsQueued(dpy, QueuedAfterReading)) { 111 + XEvent ne; 112 + XPeekEvent(dpy, &ne); 113 + 114 + if (ne.type == KeyPress && ne.xkey.time == e->xkey.time && 115 + ne.xkey.keycode == e->xkey.keycode) { 116 + XNextEvent(dpy, &ne); 117 + return; 118 + } 119 + } 120 + if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) { 121 + selmon->showbar = 0; 122 + updateholdbarpos(selmon); 123 + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 124 + arrange(selmon); 125 + } 126 +} 127 + 128 +void 129 +updateholdbarpos(Monitor *m) 130 +{ 131 + m->wy = m->my; 132 + m->wh = m->mh; 133 + if (m->showbar) { 134 + m->by = m->topbar ? m->wy : m->wy + m->wh - bh; 135 + m->wy = m->topbar ? m->wy - bh + bh : m->wy; 136 + } else { 137 + m->by = -bh; 138 + } 139 +} 140 + 141 void 142 applyrules(Client *c) 143 { 144 @@ -631,6 +690,7 @@ Monitor * 145 createmon(void) 146 { 147 Monitor *m; 148 + unsigned int i; 149 150 m = ecalloc(1, sizeof(Monitor)); 151 m->tagset[0] = m->tagset[1] = 1; 152 @@ -641,6 +701,17 @@ createmon(void) 153 m->lt[0] = &layouts[0]; 154 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 155 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 156 + m->pertag = ecalloc(1, sizeof(Pertag)); 157 + m->pertag->curtag = m->pertag->prevtag = 1; 158 + 159 + for (i = 0; i <= LENGTH(tags); i++) { 160 + m->pertag->nmasters[i] = m->nmaster; 161 + m->pertag->mfacts[i] = m->mfact; 162 + 163 + m->pertag->ltidxs[i][0] = m->lt[0]; 164 + m->pertag->ltidxs[i][1] = m->lt[1]; 165 + m->pertag->sellts[i] = m->sellt; 166 + } 167 return m; 168 } 169 170 @@ -966,7 +1037,7 @@ grabkeys(void) 171 void 172 incnmaster(const Arg *arg) 173 { 174 - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 175 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); 176 arrange(selmon); 177 } 178 179 @@ -1501,9 +1572,9 @@ void 180 setlayout(const Arg *arg) 181 { 182 if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 183 - selmon->sellt ^= 1; 184 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; 185 if (arg && arg->v) 186 - selmon->lt[selmon->sellt] = (Layout *)arg->v; 187 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; 188 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 189 if (selmon->sel) 190 arrange(selmon); 191 @@ -1522,7 +1593,7 @@ setmfact(const Arg *arg) 192 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 193 if (f < 0.1 || f > 0.9) 194 return; 195 - selmon->mfact = f; 196 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; 197 arrange(selmon); 198 } 199 200 @@ -1699,7 +1770,7 @@ tile(Monitor *m) 201 void 202 togglebar(const Arg *arg) 203 { 204 - selmon->showbar = !selmon->showbar; 205 + selmon->showbar = (selmon->showbar == 2 ? 1 : !selmon->showbar); 206 updatebarpos(selmon); 207 XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 208 arrange(selmon); 209 @@ -1738,9 +1809,30 @@ void 210 toggleview(const Arg *arg) 211 { 212 unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 213 + int i; 214 215 if (newtagset) { 216 selmon->tagset[selmon->seltags] = newtagset; 217 + 218 + if (newtagset == ~0) { 219 + selmon->pertag->prevtag = selmon->pertag->curtag; 220 + selmon->pertag->curtag = 0; 221 + } 222 + 223 + /* test if the user did not select the same tag */ 224 + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { 225 + selmon->pertag->prevtag = selmon->pertag->curtag; 226 + for (i = 0; !(newtagset & 1 << i); i++) ; 227 + selmon->pertag->curtag = i + 1; 228 + } 229 + 230 + /* apply settings for this view */ 231 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 232 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 233 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 234 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 235 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 236 + 237 focus(NULL); 238 arrange(selmon); 239 } 240 @@ -2035,11 +2127,34 @@ updatewmhints(Client *c) 241 void 242 view(const Arg *arg) 243 { 244 + int i; 245 + unsigned int tmptag; 246 + 247 if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 248 return; 249 selmon->seltags ^= 1; /* toggle sel tagset */ 250 - if (arg->ui & TAGMASK) 251 + if (arg->ui & TAGMASK) { 252 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 253 + selmon->pertag->prevtag = selmon->pertag->curtag; 254 + 255 + if (arg->ui == ~0) 256 + selmon->pertag->curtag = 0; 257 + else { 258 + for (i = 0; !(arg->ui & 1 << i); i++) ; 259 + selmon->pertag->curtag = i + 1; 260 + } 261 + } else { 262 + tmptag = selmon->pertag->prevtag; 263 + selmon->pertag->prevtag = selmon->pertag->curtag; 264 + selmon->pertag->curtag = tmptag; 265 + } 266 + 267 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 268 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 269 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 270 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 271 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 272 + 273 focus(NULL); 274 arrange(selmon); 275 }