dwm-awesomebar-statuscmd-6.2.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
dwm-awesomebar-statuscmd-6.2.diff (12122B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 1c0b587..0b92823 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -16,6 +16,7 @@ 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 + [SchemeHid] = { col_cyan, col_gray1, col_cyan },
10 };
11
12 /* tagging */
13 @@ -59,6 +60,10 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
14 static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
15 static const char *termcmd[] = { "st", NULL };
16
17 +/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */
18 +static char *statuscmds[] = { "notify-send Mouse$BUTTON" };
19 +static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL };
20 +
21 static Key keys[] = {
22 /* modifier key function argument */
23 { MODKEY, XK_p, spawn, {.v = dmenucmd } },
24 @@ -102,8 +107,11 @@ static Button buttons[] = {
25 /* click event mask button function argument */
26 { ClkLtSymbol, 0, Button1, setlayout, {0} },
27 { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
28 + { ClkWinTitle, 0, Button1, togglewin, {0} },
29 { ClkWinTitle, 0, Button2, zoom, {0} },
30 - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
31 + { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } },
32 + { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } },
33 + { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } },
34 { ClkClientWin, MODKEY, Button1, movemouse, {0} },
35 { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
36 { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
37 diff --git a/dwm.c b/dwm.c
38 index 4465af1..d841477 100644
39 --- a/dwm.c
40 +++ b/dwm.c
41 @@ -50,6 +50,7 @@
42 #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
43 * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
44 #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
45 +#define HIDDEN(C) ((getstate(C->win) == IconicState))
46 #define LENGTH(X) (sizeof X / sizeof X[0])
47 #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
48 #define WIDTH(X) ((X)->w + 2 * (X)->bw)
49 @@ -59,7 +60,7 @@
50
51 /* enums */
52 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
53 -enum { SchemeNorm, SchemeSel }; /* color schemes */
54 +enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */
55 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
56 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
57 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
58 @@ -117,6 +118,8 @@ struct Monitor {
59 int nmaster;
60 int num;
61 int by; /* bar geometry */
62 + int btw; /* width of tasks portion of bar */
63 + int bt; /* number of tasks */
64 int mx, my, mw, mh; /* screen size */
65 int wx, wy, ww, wh; /* window area */
66 unsigned int seltags;
67 @@ -156,6 +159,7 @@ static void clientmessage(XEvent *e);
68 static void configure(Client *c);
69 static void configurenotify(XEvent *e);
70 static void configurerequest(XEvent *e);
71 +static void copyvalidchars(char *text, char *rawtext);
72 static Monitor *createmon(void);
73 static void destroynotify(XEvent *e);
74 static void detach(Client *c);
75 @@ -174,6 +178,7 @@ static long getstate(Window w);
76 static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
77 static void grabbuttons(Client *c, int focused);
78 static void grabkeys(void);
79 +static void hide(Client *c);
80 static void incnmaster(const Arg *arg);
81 static void keypress(XEvent *e);
82 static void killclient(const Arg *arg);
83 @@ -203,6 +208,7 @@ static void setlayout(const Arg *arg);
84 static void setmfact(const Arg *arg);
85 static void setup(void);
86 static void seturgent(Client *c, int urg);
87 +static void show(Client *c);
88 static void showhide(Client *c);
89 static void sigchld(int unused);
90 static void spawn(const Arg *arg);
91 @@ -213,6 +219,7 @@ static void togglebar(const Arg *arg);
92 static void togglefloating(const Arg *arg);
93 static void toggletag(const Arg *arg);
94 static void toggleview(const Arg *arg);
95 +static void togglewin(const Arg *arg);
96 static void unfocus(Client *c, int setfocus);
97 static void unmanage(Client *c, int destroyed);
98 static void unmapnotify(XEvent *e);
99 @@ -237,6 +244,9 @@ static void zoom(const Arg *arg);
100 /* variables */
101 static const char broken[] = "broken";
102 static char stext[256];
103 +static char rawstext[256];
104 +static int statuscmdn;
105 +static char lastbutton[] = "-";
106 static int screen;
107 static int sw, sh; /* X display screen geometry width, height */
108 static int bh, blw = 0; /* bar geometry */
109 @@ -421,6 +431,7 @@ buttonpress(XEvent *e)
110 Client *c;
111 Monitor *m;
112 XButtonPressedEvent *ev = &e->xbutton;
113 + *lastbutton = '0' + ev->button;
114
115 click = ClkRootWin;
116 /* focus monitor if necessary */
117 @@ -439,10 +450,43 @@ buttonpress(XEvent *e)
118 arg.ui = 1 << i;
119 } else if (ev->x < x + blw)
120 click = ClkLtSymbol;
121 - else if (ev->x > selmon->ww - TEXTW(stext))
122 + /* 2px right padding */
123 + else if (ev->x > (selmon->ww - TEXTW(stext) + lrpad) - 2) {
124 + x = selmon->ww - TEXTW(stext) + lrpad - 2;
125 click = ClkStatusText;
126 - else
127 - click = ClkWinTitle;
128 +
129 + char *text = rawstext;
130 + int i = -1;
131 + char ch;
132 + statuscmdn = 0;
133 + while (text[++i]) {
134 + if ((unsigned char)text[i] < ' ') {
135 + ch = text[i];
136 + text[i] = '\0';
137 + x += TEXTW(text) - lrpad;
138 + text[i] = ch;
139 + text += i+1;
140 + i = -1;
141 + if (x >= ev->x) break;
142 + if (ch <= LENGTH(statuscmds)) statuscmdn = ch - 1;
143 + }
144 + }
145 + } else {
146 + x += blw;
147 + c = m->clients;
148 +
149 + if (c) {
150 + do {
151 + if (!ISVISIBLE(c))
152 + continue;
153 + else
154 + x += (1.0 / (double)m->bt) * m->btw;
155 + } while (ev->x > x && (c = c->next));
156 +
157 + click = ClkWinTitle;
158 + arg.v = c;
159 + }
160 + }
161 } else if ((c = wintoclient(ev->window))) {
162 focus(c);
163 restack(selmon);
164 @@ -452,7 +496,7 @@ buttonpress(XEvent *e)
165 for (i = 0; i < LENGTH(buttons); i++)
166 if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
167 && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
168 - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
169 + buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
170 }
171
172 void
173 @@ -627,6 +671,19 @@ configurerequest(XEvent *e)
174 XSync(dpy, False);
175 }
176
177 +void
178 +copyvalidchars(char *text, char *rawtext)
179 +{
180 + int i = -1, j = 0;
181 +
182 + while(rawtext[++i]) {
183 + if ((unsigned char)rawtext[i] >= ' ') {
184 + text[j++] = rawtext[i];
185 + }
186 + }
187 + text[j] = '\0';
188 +}
189 +
190 Monitor *
191 createmon(void)
192 {
193 @@ -695,7 +752,7 @@ dirtomon(int dir)
194 void
195 drawbar(Monitor *m)
196 {
197 - int x, w, sw = 0;
198 + int x, w, sw = 0, n = 0, scm;
199 int boxs = drw->fonts->h / 9;
200 int boxw = drw->fonts->h / 6 + 2;
201 unsigned int i, occ = 0, urg = 0;
202 @@ -709,6 +766,8 @@ drawbar(Monitor *m)
203 }
204
205 for (c = m->clients; c; c = c->next) {
206 + if (ISVISIBLE(c))
207 + n++;
208 occ |= c->tags;
209 if (c->isurgent)
210 urg |= c->tags;
211 @@ -729,16 +788,37 @@ drawbar(Monitor *m)
212 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
213
214 if ((w = m->ww - sw - x) > bh) {
215 - if (m->sel) {
216 - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
217 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
218 - if (m->sel->isfloating)
219 - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
220 + if (n > 0) {
221 + int remainder = w % n;
222 + int tabw = (1.0 / (double)n) * w + 1;
223 + for (c = m->clients; c; c = c->next) {
224 + if (!ISVISIBLE(c))
225 + continue;
226 + if (m->sel == c)
227 + scm = SchemeSel;
228 + else if (HIDDEN(c))
229 + scm = SchemeHid;
230 + else
231 + scm = SchemeNorm;
232 + drw_setscheme(drw, scheme[scm]);
233 +
234 + if (remainder >= 0) {
235 + if (remainder == 0) {
236 + tabw--;
237 + }
238 + remainder--;
239 + }
240 + drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0);
241 + x += tabw;
242 + }
243 } else {
244 drw_setscheme(drw, scheme[SchemeNorm]);
245 drw_rect(drw, x, 0, w, bh, 1, 1);
246 }
247 }
248 +
249 + m->bt = n;
250 + m->btw = w;
251 drw_map(drw, m->barwin, 0, 0, m->ww, bh);
252 }
253
254 @@ -783,8 +863,8 @@ expose(XEvent *e)
255 void
256 focus(Client *c)
257 {
258 - if (!c || !ISVISIBLE(c))
259 - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
260 + if (!c || !ISVISIBLE(c) || HIDDEN(c))
261 + for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext);
262 if (selmon->sel && selmon->sel != c)
263 unfocus(selmon->sel, 0);
264 if (c) {
265 @@ -963,6 +1043,31 @@ grabkeys(void)
266 }
267 }
268
269 +void
270 +hide(Client *c) {
271 + if (!c || HIDDEN(c))
272 + return;
273 +
274 + Window w = c->win;
275 + static XWindowAttributes ra, ca;
276 +
277 + // more or less taken directly from blackbox's hide() function
278 + XGrabServer(dpy);
279 + XGetWindowAttributes(dpy, root, &ra);
280 + XGetWindowAttributes(dpy, w, &ca);
281 + // prevent UnmapNotify events
282 + XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
283 + XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
284 + XUnmapWindow(dpy, w);
285 + setclientstate(c, IconicState);
286 + XSelectInput(dpy, root, ra.your_event_mask);
287 + XSelectInput(dpy, w, ca.your_event_mask);
288 + XUngrabServer(dpy);
289 +
290 + focus(c->snext);
291 + arrange(c->mon);
292 +}
293 +
294 void
295 incnmaster(const Arg *arg)
296 {
297 @@ -1067,12 +1172,14 @@ manage(Window w, XWindowAttributes *wa)
298 XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
299 (unsigned char *) &(c->win), 1);
300 XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
301 - setclientstate(c, NormalState);
302 + if (!HIDDEN(c))
303 + setclientstate(c, NormalState);
304 if (c->mon == selmon)
305 unfocus(selmon->sel, 0);
306 c->mon->sel = c;
307 arrange(c->mon);
308 - XMapWindow(dpy, c->win);
309 + if (!HIDDEN(c))
310 + XMapWindow(dpy, c->win);
311 focus(NULL);
312 }
313
314 @@ -1195,7 +1302,7 @@ movemouse(const Arg *arg)
315 Client *
316 nexttiled(Client *c)
317 {
318 - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
319 + for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = c->next);
320 return c;
321 }
322
323 @@ -1248,6 +1355,16 @@ propertynotify(XEvent *e)
324 void
325 quit(const Arg *arg)
326 {
327 + // fix: reloading dwm keeps all the hidden clients hidden
328 + Monitor *m;
329 + Client *c;
330 + for (m = mons; m; m = m->next) {
331 + if (m) {
332 + for (c = m->stack; c; c = c->next)
333 + if (c && HIDDEN(c)) show(c);
334 + }
335 + }
336 +
337 running = 0;
338 }
339
340 @@ -1610,6 +1727,17 @@ seturgent(Client *c, int urg)
341 XFree(wmh);
342 }
343
344 +void
345 +show(Client *c)
346 +{
347 + if (!c || !HIDDEN(c))
348 + return;
349 +
350 + XMapWindow(dpy, c->win);
351 + setclientstate(c, NormalState);
352 + arrange(c->mon);
353 +}
354 +
355 void
356 showhide(Client *c)
357 {
358 @@ -1641,6 +1769,10 @@ spawn(const Arg *arg)
359 {
360 if (arg->v == dmenucmd)
361 dmenumon[0] = '0' + selmon->num;
362 + else if (arg->v == statuscmd) {
363 + statuscmd[2] = statuscmds[statuscmdn];
364 + setenv("BUTTON", lastbutton, 1);
365 + }
366 if (fork() == 0) {
367 if (dpy)
368 close(ConnectionNumber(dpy));
369 @@ -1746,6 +1878,20 @@ toggleview(const Arg *arg)
370 }
371 }
372
373 +void
374 +togglewin(const Arg *arg)
375 +{
376 + Client *c = (Client*)arg->v;
377 + if (c == selmon->sel)
378 + hide(c);
379 + else {
380 + if (HIDDEN(c))
381 + show(c);
382 + focus(c);
383 + restack(selmon);
384 + }
385 +}
386 +
387 void
388 unfocus(Client *c, int setfocus)
389 {
390 @@ -1987,8 +2133,10 @@ updatesizehints(Client *c)
391 void
392 updatestatus(void)
393 {
394 - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
395 + if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
396 strcpy(stext, "dwm-"VERSION);
397 + else
398 + copyvalidchars(stext, rawstext);
399 drawbar(selmon);
400 }
401