Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-awesomebarwithhover-20230431-6.4.diff - sites - public wiki contents of suc…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-awesomebarwithhover-20230431-6.4.diff (15829B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 061ad66..82a3ed2 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -16,6 +16,8 @@ static const char *colors[][3] = {
6 /* fg bg border */
7 [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
8 [SchemeSel] = { col_gray4, col_cyan, col_cyan },
9 + [SchemeHov] = { col_gray4, col_cyan, col_cyan },
10 + [SchemeHid] = { col_cyan, col_gray1, col_cyan },
11 };
12
13 /* tagging */
14 @@ -64,8 +66,10 @@ static const Key keys[] = {
15 { MODKEY, XK_p, spawn, {.v …
16 { MODKEY|ShiftMask, XK_Return, spawn, {.v …
17 { MODKEY, XK_b, togglebar, {0} …
18 - { MODKEY, XK_j, focusstack, {.i …
19 - { MODKEY, XK_k, focusstack, {.i …
20 + { MODKEY, XK_j, focusstackvis, {.i …
21 + { MODKEY, XK_k, focusstackvis, {.i …
22 + { MODKEY|ShiftMask, XK_j, focusstackhid, {.i …
23 + { MODKEY|ShiftMask, XK_k, focusstackhid, {.i …
24 { MODKEY, XK_i, incnmaster, {.i …
25 { MODKEY, XK_d, incnmaster, {.i …
26 { MODKEY, XK_h, setmfact, {.f …
27 @@ -84,6 +88,9 @@ static const Key keys[] = {
28 { MODKEY, XK_period, focusmon, {.i …
29 { MODKEY|ShiftMask, XK_comma, tagmon, {.i …
30 { MODKEY|ShiftMask, XK_period, tagmon, {.i …
31 + { MODKEY, XK_s, show, {0} …
32 + { MODKEY|ShiftMask, XK_s, showall, {0} …
33 + { MODKEY, XK_h, hide, {0} …
34 TAGKEYS( XK_1, 0)
35 TAGKEYS( XK_2, 1)
36 TAGKEYS( XK_3, 2)
37 @@ -102,6 +109,7 @@ static const Button buttons[] = {
38 /* click event mask button functio…
39 { ClkLtSymbol, 0, Button1, setlayo…
40 { ClkLtSymbol, 0, Button3, setlayo…
41 + { ClkWinTitle, 0, Button1, togglew…
42 { ClkWinTitle, 0, Button2, zoom, …
43 { ClkStatusText, 0, Button2, spawn, …
44 { ClkClientWin, MODKEY, Button1, movemou…
45 diff --git a/dwm.c b/dwm.c
46 index e5efb6a..8cb5171 100644
47 --- a/dwm.c
48 +++ b/dwm.c
49 @@ -50,6 +50,7 @@
50 #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - …
51 * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - …
52 #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->selt…
53 +#define HIDDEN(C) ((getstate(C->win) == IconicState))
54 #define LENGTH(X) (sizeof X / sizeof X[0])
55 #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
56 #define WIDTH(X) ((X)->w + 2 * (X)->bw)
57 @@ -59,7 +60,7 @@
58
59 /* enums */
60 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
61 -enum { SchemeNorm, SchemeSel }; /* color schemes */
62 +enum { SchemeNorm, SchemeSel, SchemeHov, SchemeHid }; /* color schemes …
63 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
64 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
65 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
66 @@ -117,6 +118,8 @@ struct Monitor {
67 int nmaster;
68 int num;
69 int by; /* bar geometry */
70 + int btw; /* width of tasks portion of bar */
71 + int bt; /* number of tasks */
72 int mx, my, mw, mh; /* screen size */
73 int wx, wy, ww, wh; /* window area */
74 unsigned int seltags;
75 @@ -124,8 +127,10 @@ struct Monitor {
76 unsigned int tagset[2];
77 int showbar;
78 int topbar;
79 + int hidsel;
80 Client *clients;
81 Client *sel;
82 + Client *hov;
83 Client *stack;
84 Monitor *next;
85 Window barwin;
86 @@ -168,13 +173,17 @@ static void expose(XEvent *e);
87 static void focus(Client *c);
88 static void focusin(XEvent *e);
89 static void focusmon(const Arg *arg);
90 -static void focusstack(const Arg *arg);
91 +static void focusstackvis(const Arg *arg);
92 +static void focusstackhid(const Arg *arg);
93 +static void focusstack(int inc, int vis);
94 static Atom getatomprop(Client *c, Atom prop);
95 static int getrootptr(int *x, int *y);
96 static long getstate(Window w);
97 static int gettextprop(Window w, Atom atom, char *text, unsigned int si…
98 static void grabbuttons(Client *c, int focused);
99 static void grabkeys(void);
100 +static void hide(const Arg *arg);
101 +static void hidewin(Client *c);
102 static void incnmaster(const Arg *arg);
103 static void keypress(XEvent *e);
104 static void killclient(const Arg *arg);
105 @@ -204,6 +213,9 @@ static void setlayout(const Arg *arg);
106 static void setmfact(const Arg *arg);
107 static void setup(void);
108 static void seturgent(Client *c, int urg);
109 +static void show(const Arg *arg);
110 +static void showall(const Arg *arg);
111 +static void showwin(Client *c);
112 static void showhide(Client *c);
113 static void sigchld(int unused);
114 static void spawn(const Arg *arg);
115 @@ -214,6 +226,7 @@ static void togglebar(const Arg *arg);
116 static void togglefloating(const Arg *arg);
117 static void toggletag(const Arg *arg);
118 static void toggleview(const Arg *arg);
119 +static void togglewin(const Arg *arg);
120 static void unfocus(Client *c, int setfocus);
121 static void unmanage(Client *c, int destroyed);
122 static void unmapnotify(XEvent *e);
123 @@ -442,10 +455,25 @@ buttonpress(XEvent *e)
124 arg.ui = 1 << i;
125 } else if (ev->x < x + TEXTW(selmon->ltsymbol))
126 click = ClkLtSymbol;
127 - else if (ev->x > selmon->ww - (int)TEXTW(stext))
128 + /* 2px right padding */
129 + else if (ev->x > selmon->ww - TEXTW(stext) + lrpad - 2)
130 click = ClkStatusText;
131 - else
132 - click = ClkWinTitle;
133 + else {
134 + x += TEXTW(selmon->ltsymbol);
135 + c = m->clients;
136 +
137 + if (c) {
138 + do {
139 + if (!ISVISIBLE(c))
140 + continue;
141 + else
142 + x +=(1.0 / (double)m->b…
143 + } while (ev->x > x && (c = c->next));
144 +
145 + click = ClkWinTitle;
146 + arg.v = c;
147 + }
148 + }
149 } else if ((c = wintoclient(ev->window))) {
150 focus(c);
151 restack(selmon);
152 @@ -455,7 +483,7 @@ buttonpress(XEvent *e)
153 for (i = 0; i < LENGTH(buttons); i++)
154 if (click == buttons[i].click && buttons[i].func && but…
155 && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
156 - buttons[i].func(click == ClkTagBar && buttons[i…
157 + buttons[i].func((click == ClkTagBar || click ==…
158 }
159
160 void
161 @@ -699,7 +727,7 @@ dirtomon(int dir)
162 void
163 drawbar(Monitor *m)
164 {
165 - int x, w, tw = 0;
166 + int x, w, tw = 0, n = 0, scm;
167 int boxs = drw->fonts->h / 9;
168 int boxw = drw->fonts->h / 6 + 2;
169 unsigned int i, occ = 0, urg = 0;
170 @@ -716,6 +744,8 @@ drawbar(Monitor *m)
171 }
172
173 for (c = m->clients; c; c = c->next) {
174 + if (ISVISIBLE(c))
175 + n++;
176 occ |= c->tags;
177 if (c->isurgent)
178 urg |= c->tags;
179 @@ -736,16 +766,38 @@ drawbar(Monitor *m)
180 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
181
182 if ((w = m->ww - tw - x) > bh) {
183 - if (m->sel) {
184 - drw_setscheme(drw, scheme[m == selmon ? SchemeS…
185 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->n…
186 - if (m->sel->isfloating)
187 - drw_rect(drw, x + boxs, boxs, boxw, box…
188 + if (n > 0) {
189 + int remainder = w % n;
190 + int tabw = (1.0 / (double)n) * w + 1;
191 + for (c = m->clients; c; c = c->next) {
192 + if (!ISVISIBLE(c))
193 + continue;
194 + if (m->hov == c)
195 + scm = SchemeHov;
196 + else if (m->sel == c)
197 + scm = SchemeSel;
198 + else if (HIDDEN(c))
199 + scm = SchemeHid;
200 + else
201 + scm = SchemeNorm;
202 + drw_setscheme(drw, scheme[scm]);
203 +
204 + if (remainder >= 0) {
205 + if (remainder == 0) {
206 + tabw--;
207 + }
208 + remainder--;
209 + }
210 + drw_text(drw, x, 0, tabw, bh, lrpad / 2…
211 + x += tabw;
212 + }
213 } else {
214 drw_setscheme(drw, scheme[SchemeNorm]);
215 drw_rect(drw, x, 0, w, bh, 1, 1);
216 }
217 }
218 + m->bt = n;
219 + m->btw = w;
220 drw_map(drw, m->barwin, 0, 0, m->ww, bh);
221 }
222
223 @@ -791,9 +843,17 @@ void
224 focus(Client *c)
225 {
226 if (!c || !ISVISIBLE(c))
227 - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snex…
228 - if (selmon->sel && selmon->sel != c)
229 + for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c…
230 + if (selmon->sel && selmon->sel != c) {
231 unfocus(selmon->sel, 0);
232 +
233 + if (selmon->hidsel) {
234 + hidewin(selmon->sel);
235 + if (c)
236 + arrange(c->mon);
237 + selmon->hidsel = 0;
238 + }
239 + }
240 if (c) {
241 if (c->mon != selmon)
242 selmon = c->mon;
243 @@ -837,28 +897,52 @@ focusmon(const Arg *arg)
244 }
245
246 void
247 -focusstack(const Arg *arg)
248 +focusstackvis(const Arg *arg) {
249 + focusstack(arg->i, 0);
250 +}
251 +
252 +void
253 +focusstackhid(const Arg *arg) {
254 + focusstack(arg->i, 1);
255 +}
256 +
257 +void
258 +focusstack(int inc, int hid)
259 {
260 Client *c = NULL, *i;
261 -
262 - if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscree…
263 + // if no client selected AND exclude hidden client; if client s…
264 + if ((!selmon->sel && !hid) || (selmon->sel && selmon->sel->isfu…
265 + return;
266 + if (!selmon->clients)
267 return;
268 - if (arg->i > 0) {
269 - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->…
270 + if (inc > 0) {
271 + if (selmon->sel)
272 + for (c = selmon->sel->next;
273 + c && (!ISVISIBLE(c) || (!hid &&…
274 + c = c->next);
275 if (!c)
276 - for (c = selmon->clients; c && !ISVISIBLE(c); c…
277 + for (c = selmon->clients;
278 + c && (!ISVISIBLE(c) || (!hid &&…
279 + c = c->next);
280 } else {
281 - for (i = selmon->clients; i != selmon->sel; i = i->next)
282 - if (ISVISIBLE(i))
283 - c = i;
284 + if (selmon->sel) {
285 + for (i = selmon->clients; i != selmon->sel; i =…
286 + if (ISVISIBLE(i) && !(!hid && HIDDEN(i)…
287 + c = i;
288 + } else
289 + c = selmon->clients;
290 if (!c)
291 for (; i; i = i->next)
292 - if (ISVISIBLE(i))
293 + if (ISVISIBLE(i) && !(!hid && HIDDEN(i)…
294 c = i;
295 }
296 if (c) {
297 focus(c);
298 restack(selmon);
299 + if (HIDDEN(c)) {
300 + showwin(c);
301 + c->mon->hidsel = 1;
302 + }
303 }
304 }
305
306 @@ -968,6 +1052,36 @@ grabkeys(void)
307 }
308 }
309
310 +void
311 +hide(const Arg *arg)
312 +{
313 + hidewin(selmon->sel);
314 + focus(NULL);
315 + arrange(selmon);
316 +}
317 +
318 +void
319 +hidewin(Client *c) {
320 + if (!c || HIDDEN(c))
321 + return;
322 +
323 + Window w = c->win;
324 + static XWindowAttributes ra, ca;
325 +
326 + // more or less taken directly from blackbox's hide() function
327 + XGrabServer(dpy);
328 + XGetWindowAttributes(dpy, root, &ra);
329 + XGetWindowAttributes(dpy, w, &ca);
330 + // prevent UnmapNotify events
331 + XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotif…
332 + XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
333 + XUnmapWindow(dpy, w);
334 + setclientstate(c, IconicState);
335 + XSelectInput(dpy, root, ra.your_event_mask);
336 + XSelectInput(dpy, w, ca.your_event_mask);
337 + XUngrabServer(dpy);
338 +}
339 +
340 void
341 incnmaster(const Arg *arg)
342 {
343 @@ -1070,12 +1184,14 @@ manage(Window w, XWindowAttributes *wa)
344 XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 3…
345 (unsigned char *) &(c->win), 1);
346 XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h)…
347 - setclientstate(c, NormalState);
348 + if (!HIDDEN(c))
349 + setclientstate(c, NormalState);
350 if (c->mon == selmon)
351 unfocus(selmon->sel, 0);
352 c->mon->sel = c;
353 arrange(c->mon);
354 - XMapWindow(dpy, c->win);
355 + if (!HIDDEN(c))
356 + XMapWindow(dpy, c->win);
357 focus(NULL);
358 }
359
360 @@ -1119,18 +1235,76 @@ monocle(Monitor *m)
361 void
362 motionnotify(XEvent *e)
363 {
364 + int x, i;
365 static Monitor *mon = NULL;
366 + Client *c;
367 Monitor *m;
368 XMotionEvent *ev = &e->xmotion;
369
370 - if (ev->window != root)
371 + if (ev->window != selmon->barwin) {
372 + if (selmon->hov) {
373 + if (selmon->hov != selmon->sel)
374 + XSetWindowBorder(dpy, selmon->hov->win,…
375 + else
376 + XSetWindowBorder(dpy, selmon->hov->win,…
377 +
378 + selmon->hov = NULL;
379 + c = wintoclient(ev->window);
380 + m = c ? c->mon : wintomon(ev->window);
381 + drawbar(m);
382 + }
383 +
384 + if (ev->window == root) {
385 + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1…
386 + unfocus(selmon->sel, 1);
387 + selmon = m;
388 + focus(NULL);
389 + }
390 + mon = m;
391 + }
392 +
393 return;
394 - if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon…
395 - unfocus(selmon->sel, 1);
396 - selmon = m;
397 - focus(NULL);
398 }
399 - mon = m;
400 +
401 + c = wintoclient(ev->window);
402 + m = c ? c->mon : wintomon(ev->window);
403 + c = m->clients;
404 +
405 + x = 0, i = 0;
406 + do
407 + x += TEXTW(tags[i]);
408 + while (ev->x >= x && ++i < LENGTH(tags));
409 + if (i < LENGTH(tags) || ev->x < x + TEXTW(selmon->ltsymbol) || …
410 + if (selmon->hov) {
411 + if (selmon->hov != selmon->sel)
412 + XSetWindowBorder(dpy, selmon->hov->win,…
413 + else
414 + XSetWindowBorder(dpy, selmon->hov->win,…
415 + selmon->hov = NULL;
416 + drawbar(m);
417 + }
418 + } else {
419 + x += TEXTW(selmon->ltsymbol);
420 + if (c) {
421 + do {
422 + if (!ISVISIBLE(c))
423 + continue;
424 + else
425 + x +=(1.0 / (double)m->bt) * m->…
426 + } while (ev->x > x && (c = c->next));
427 + if (c) {
428 + if (selmon->hov) {
429 + if (selmon->hov != selmon->sel)
430 + XSetWindowBorder(dpy, s…
431 + else
432 + XSetWindowBorder(dpy, s…
433 + }
434 + selmon->hov = c;
435 + XSetWindowBorder(dpy, c->win, scheme[Sc…
436 + }
437 + }
438 + drawbar(m);
439 + }
440 }
441
442 void
443 @@ -1196,7 +1370,7 @@ movemouse(const Arg *arg)
444 Client *
445 nexttiled(Client *c)
446 {
447 - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
448 + for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = …
449 return c;
450 }
451
452 @@ -1249,6 +1423,16 @@ propertynotify(XEvent *e)
453 void
454 quit(const Arg *arg)
455 {
456 + // fix: reloading dwm keeps all the hidden clients hidden
457 + Monitor *m;
458 + Client *c;
459 + for (m = mons; m; m = m->next) {
460 + if (m) {
461 + for (c = m->stack; c; c = c->next)
462 + if (c && HIDDEN(c)) showwin(c);
463 + }
464 + }
465 +
466 running = 0;
467 }
468
469 @@ -1610,6 +1794,42 @@ seturgent(Client *c, int urg)
470 XFree(wmh);
471 }
472
473 +void
474 +show(const Arg *arg)
475 +{
476 + if (selmon->hidsel)
477 + selmon->hidsel = 0;
478 + showwin(selmon->sel);
479 +}
480 +
481 +void
482 +showall(const Arg *arg)
483 +{
484 + Client *c = NULL;
485 + selmon->hidsel = 0;
486 + for (c = selmon->clients; c; c = c->next) {
487 + if (ISVISIBLE(c))
488 + showwin(c);
489 + }
490 + if (!selmon->sel) {
491 + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->ne…
492 + if (c)
493 + focus(c);
494 + }
495 + restack(selmon);
496 +}
497 +
498 +void
499 +showwin(Client *c)
500 +{
501 + if (!c || !HIDDEN(c))
502 + return;
503 +
504 + XMapWindow(dpy, c->win);
505 + setclientstate(c, NormalState);
506 + arrange(c->mon);
507 +}
508 +
509 void
510 showhide(Client *c)
511 {
512 @@ -1744,6 +1964,23 @@ toggleview(const Arg *arg)
513 }
514 }
515
516 +void
517 +togglewin(const Arg *arg)
518 +{
519 + Client *c = (Client*)arg->v;
520 +
521 + if (c == selmon->sel) {
522 + hidewin(c);
523 + focus(NULL);
524 + arrange(c->mon);
525 + } else {
526 + if (HIDDEN(c))
527 + showwin(c);
528 + focus(c);
529 + restack(selmon);
530 + }
531 +}
532 +
533 void
534 unfocus(Client *c, int setfocus)
535 {
536 @@ -1815,6 +2052,7 @@ updatebars(void)
537 CWOverrideRedirect|CWBackPixmap|CWEvent…
538 XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor…
539 XMapRaised(dpy, m->barwin);
540 + XSelectInput(dpy, m->barwin, ButtonPressMask|PointerMot…
541 XSetClassHint(dpy, m->barwin, &ch);
542 }
543 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.