Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-integrated-status-text-6.3.diff - sites - public wiki contents of suckless.…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-integrated-status-text-6.3.diff (16210B)
---
1 From 02f1f07ee4460787c971bd28e934cb5fc319253d Mon Sep 17 00:00:00 2001
2 From: explosion-mental <[email protected]>
3 Date: Thu, 26 May 2022 22:34:14 -0500
4 Subject: [PATCH] [PATCH] Allows dwm to handle the text by itself. You can
5 think of it like a dwmblocks integration into dwm itself. This is extra…
6 from my dwm build[0] in which you can find even more information.
7
8 Example:
9 ```
10 /* fg command interval signal */
11 { "#000000", "echo 'dwm block!", 10, 3},
12 ```
13
14 - fg: the foreground color of the individual block, for the background it
15 uses the bg of SchemeStatus.
16
17 - command: it uses the output of the commands for the status text
18 interval: in seconds, how much does it have to pass before updating the
19 block.
20
21 - interval: in seconds, how many seconds until the block it's updated
22
23 - signal: have to be less than 30. This lets you update the block with
24 `kill` by adding 35 to this value.
25 For the block above it would be 34 + 3 = 37 -> `kill -37 $(pidof dwm)`.
26 These signals are linux dependant.
27
28 You can change `$(pidof dwm)` with `$STATUSBAR` to 'fix' signaling
29 multiple instances of dwm, since this patch also wraps the PID of dwm
30 into the `$STATUSBAR` enviromental variable.
31
32 Last thing, mouse actions. For this you need to handle the env variable
33 `$BLOCK_BUTTON` in a script, this is so you can easily reuse the scripts
34 used in dwmblocks. And remember that mouse actions update the block.
35
36 [0] https://github.com/explosion-mental/Dwm or
37 https://codeberg.org/explosion-mental/Dwm
38 ---
39 config.def.h | 39 ++++++-
40 dwm.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++----
41 2 files changed, 318 insertions(+), 19 deletions(-)
42
43 diff --git a/config.def.h b/config.def.h
44 index a2ac963..cad178c 100644
45 --- a/config.def.h
46 +++ b/config.def.h
47 @@ -16,8 +16,38 @@ static const char *colors[][3] = {
48 /* fg bg border */
49 [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
50 [SchemeSel] = { col_gray4, col_cyan, col_cyan },
51 + [SchemeStatus]={ col_cyan, col_gray1, NULL },
52 };
53
54 +
55 +/* status bar */
56 +static const Block blocks[] = {
57 + /* fg command interval …
58 + { col_gray3, "sb-clock", 20, …
59 + { col_gray1, "sb-disk", 9000, …
60 + { col_gray2, "sb-battery", 10, …
61 + { col_gray3, "sb-internet", 10, …
62 + { col_cyan, "sb-mailbox", 0, …
63 + { "#000001", "sb-moonphase", 0, …
64 + { "#1F0077", "sb-forecast", 0, …
65 + { "#000077", "sb-volume", 0, …
66 + { "#F77000", "sb-pacpackages", 0, …
67 + { "#177000", "sb-sync", 0, …
68 +// { col_gray1, "sb-mpc", 0, …
69 + { col_gray2, "sb-music", 0, …
70 +// { col_gray3, "sb-tasks", 10, …
71 + { col_gray4, "sb-notes", 0, …
72 + { col_cyan, "echo '';cat /tmp/recordingicon", 0, …
73 +};
74 +
75 +/* inverse the order of the blocks, comment to disable */
76 +#define INVERSED 1
77 +/* delimeter between blocks commands. NULL character ('\0') means no de…
78 +static char delimiter[] = " ";
79 +/* max number of character that one block command can output */
80 +#define CMDLENGTH 50
81 +
82 +
83 /* tagging */
84 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "…
85
86 @@ -104,7 +134,14 @@ static Button buttons[] = {
87 { ClkLtSymbol, 0, Button1, setlayo…
88 { ClkLtSymbol, 0, Button3, setlayo…
89 { ClkWinTitle, 0, Button2, zoom, …
90 - { ClkStatusText, 0, Button2, spawn, …
91 +
92 + { ClkStatusText, 0, Button1, sendsta…
93 + { ClkStatusText, 0, Button2, sendsta…
94 + { ClkStatusText, 0, Button3, sendsta…
95 + { ClkStatusText, 0, Button4, sendsta…
96 + { ClkStatusText, 0, Button5, sendsta…
97 + { ClkStatusText, ShiftMask, Button1, sendsta…
98 +
99 { ClkClientWin, MODKEY, Button1, movemou…
100 { ClkClientWin, MODKEY, Button2, togglef…
101 { ClkClientWin, MODKEY, Button3, resizem…
102 diff --git a/dwm.c b/dwm.c
103 index a96f33c..5789f72 100644
104 --- a/dwm.c
105 +++ b/dwm.c
106 @@ -28,6 +28,7 @@
107 #include <stdlib.h>
108 #include <string.h>
109 #include <unistd.h>
110 +#include <poll.h>
111 #include <sys/types.h>
112 #include <sys/wait.h>
113 #include <X11/cursorfont.h>
114 @@ -59,7 +60,7 @@
115
116 /* enums */
117 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
118 -enum { SchemeNorm, SchemeSel }; /* color schemes */
119 +enum { SchemeNorm, SchemeSel, SchemeStatus }; /* color schemes */
120 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
121 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
122 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
123 @@ -141,6 +142,13 @@ typedef struct {
124 int monitor;
125 } Rule;
126
127 +typedef struct {
128 + const char *color;
129 + const char *command;
130 + const unsigned int interval;
131 + const unsigned int signal;
132 +} Block;
133 +
134 /* function declarations */
135 static void applyrules(Client *c);
136 static int applysizehints(Client *c, int *x, int *y, int *w, int *h, in…
137 @@ -172,6 +180,11 @@ static void focusstack(const Arg *arg);
138 static Atom getatomprop(Client *c, Atom prop);
139 static int getrootptr(int *x, int *y);
140 static long getstate(Window w);
141 +static void getcmd(int i, char *button);
142 +static void getcmds(int time);
143 +static void getsigcmds(int signal);
144 +static int gcd(int a, int b);
145 +static int getstatus(int width);
146 static int gettextprop(Window w, Atom atom, char *text, unsigned int si…
147 static void grabbuttons(Client *c, int focused);
148 static void grabkeys(void);
149 @@ -197,14 +210,17 @@ static void run(void);
150 static void scan(void);
151 static int sendevent(Client *c, Atom proto);
152 static void sendmon(Client *c, Monitor *m);
153 +static void sendstatusbar(const Arg *arg);
154 static void setclientstate(Client *c, long state);
155 static void setfocus(Client *c);
156 static void setfullscreen(Client *c, int fullscreen);
157 static void setlayout(const Arg *arg);
158 static void setmfact(const Arg *arg);
159 static void setup(void);
160 +static void setsignal(int sig, void (*handler)(int sig));
161 static void seturgent(Client *c, int urg);
162 static void showhide(Client *c);
163 +static void sigalrm(int unused);
164 static void sigchld(int unused);
165 static void spawn(const Arg *arg);
166 static void tag(const Arg *arg);
167 @@ -237,13 +253,16 @@ static void zoom(const Arg *arg);
168
169 /* variables */
170 static const char broken[] = "broken";
171 -static char stext[256];
172 static int screen;
173 static int sw, sh; /* X display screen geometry width, height…
174 static int bh, blw = 0; /* bar geometry */
175 static int lrpad; /* sum of left and right padding for text …
176 static int (*xerrorxlib)(Display *, XErrorEvent *);
177 +static unsigned int blocknum; /* blocks idx in mouse click */
178 +static unsigned int stsw = 0; /* status width */
179 static unsigned int numlockmask = 0;
180 +static unsigned int sleepinterval = 0, maxinterval = 0, count = 0;
181 +static unsigned int execlock = 0; /* ensure only one child process exis…
182 static void (*handler[LASTEvent]) (XEvent *) = {
183 [ButtonPress] = buttonpress,
184 [ClientMessage] = clientmessage,
185 @@ -272,6 +291,9 @@ static Window root, wmcheckwin;
186 /* configuration, allows nested code to access above variables */
187 #include "config.h"
188
189 +static char blockoutput[LENGTH(blocks)][CMDLENGTH + 1] = {0};
190 +static int pipes[LENGTH(blocks)][2];
191 +
192 /* compile-time check if all tags fit into an unsigned int bit array. */
193 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
194
195 @@ -440,9 +462,26 @@ buttonpress(XEvent *e)
196 arg.ui = 1 << i;
197 } else if (ev->x < x + blw)
198 click = ClkLtSymbol;
199 - else if (ev->x > selmon->ww - (int)TEXTW(stext))
200 + else if (ev->x > (x = selmon->ww - stsw)) {
201 click = ClkStatusText;
202 - else
203 + int len, i;
204 +
205 + #if INVERSED
206 + for (i = LENGTH(blocks) - 1; i >= 0; i--)
207 + #else
208 + for (i = 0; i < LENGTH(blocks); i++)
209 + #endif /* INVERSED */
210 + {
211 + if (*blockoutput[i] == '\0') /* ignore …
212 + continue;
213 + len = TEXTW(blockoutput[i]) - lrpad + T…
214 + x += len;
215 + if (ev->x <= x && ev->x >= x - len) { /…
216 + blocknum = i; /* store what blo…
217 + break;
218 + }
219 + }
220 + } else
221 click = ClkWinTitle;
222 } else if ((c = wintoclient(ev->window))) {
223 focus(c);
224 @@ -706,11 +745,8 @@ drawbar(Monitor *m)
225 return;
226
227 /* draw status first so it can be overdrawn by tags later */
228 - if (m == selmon) { /* status is only drawn on selected monitor …
229 - drw_setscheme(drw, scheme[SchemeNorm]);
230 - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
231 - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
232 - }
233 + if (m == selmon) /* status is only drawn on selected monitor */
234 + tw = getstatus(m->ww);
235
236 for (c = m->clients; c; c = c->next) {
237 occ |= c->tags;
238 @@ -903,6 +939,106 @@ getstate(Window w)
239 return result;
240 }
241
242 +void
243 +getcmd(int i, char *button)
244 +{
245 + if (!selmon->showbar)
246 + return;
247 +
248 + if (execlock & 1 << i) { /* block is already running */
249 + //fprintf(stderr, "dwm: ignoring block %d, command %s\n…
250 + return;
251 + }
252 +
253 + /* lock execution of block until current instance finishes exec…
254 + execlock |= 1 << i;
255 +
256 + if (fork() == 0) {
257 + if (dpy)
258 + close(ConnectionNumber(dpy));
259 + dup2(pipes[i][1], STDOUT_FILENO);
260 + close(pipes[i][0]);
261 + close(pipes[i][1]);
262 +
263 + if (button)
264 + setenv("BLOCK_BUTTON", button, 1);
265 + execlp("/bin/sh", "sh", "-c", blocks[i].command, (char …
266 + fprintf(stderr, "dwm: block %d, execlp %s", i, blocks[i…
267 + perror(" failed");
268 + exit(EXIT_SUCCESS);
269 + }
270 +}
271 +
272 +void
273 +getcmds(int time)
274 +{
275 + int i;
276 + for (i = 0; i < LENGTH(blocks); i++)
277 + if ((blocks[i].interval != 0 && time % blocks[i].interv…
278 + getcmd(i, NULL);
279 +}
280 +
281 +void
282 +getsigcmds(int signal)
283 +{
284 + int i;
285 + unsigned int sig = signal - SIGRTMIN;
286 + for (i = 0; i < LENGTH(blocks); i++)
287 + if (blocks[i].signal == sig)
288 + getcmd(i, NULL);
289 +}
290 +
291 +int
292 +getstatus(int width)
293 +{
294 + int i, len, all = width, delimlen = TEXTW(delimiter) - lrpad;
295 + char fgcol[8];
296 + /* fg bg */
297 + const char *cols[8] = { fgcol, colors[SchemeStatus][Col…
298 + //uncomment to inverse the colors
299 + //const char *cols[8] = { colors[SchemeStatus][ColBg], …
300 +
301 + #if INVERSED
302 + for (i = 0; i < LENGTH(blocks); i++)
303 + #else
304 + for (i = LENGTH(blocks) - 1; i >= 0; i--)
305 + #endif /* INVERSED */
306 + {
307 + if (*blockoutput[i] == '\0') /* ignore command that out…
308 + continue;
309 + strncpy(fgcol, blocks[i].color, 8);
310 + /* re-load the scheme with the new colors */
311 + scheme[SchemeStatus] = drw_scm_create(drw, cols, 3);
312 + drw_setscheme(drw, scheme[SchemeStatus]); /* 're-set' t…
313 + len = TEXTW(blockoutput[i]) - lrpad;
314 + all -= len;
315 + drw_text(drw, all, 0, len, bh, 0, blockoutput[i], 0);
316 + /* draw delimiter */
317 + if (*delimiter == '\0') /* ignore no delimiter */
318 + continue;
319 + drw_setscheme(drw, scheme[SchemeNorm]);
320 + all -= delimlen;
321 + drw_text(drw, all, 0, delimlen, bh, 0, delimiter, 0);
322 + }
323 +
324 + return stsw = width - all;
325 +}
326 +
327 +int
328 +gcd(int a, int b)
329 +{
330 + int temp;
331 +
332 + while (b > 0) {
333 + temp = a % b;
334 + a = b;
335 + b = temp;
336 + }
337 +
338 + return a;
339 +}
340 +
341 +
342 int
343 gettextprop(Window w, Atom atom, char *text, unsigned int size)
344 {
345 @@ -1376,12 +1512,99 @@ restack(Monitor *m)
346 void
347 run(void)
348 {
349 + int i;
350 XEvent ev;
351 + struct pollfd fds[LENGTH(blocks) + 1] = {0};
352 +
353 + fds[0].fd = ConnectionNumber(dpy);
354 + fds[0].events = POLLIN;
355 +
356 + #if INVERSED
357 + for (i = LENGTH(blocks) - 1; i >= 0; i--)
358 + #else
359 + for (i = 0; i < LENGTH(blocks); i++)
360 + #endif /* INVERSED */
361 + {
362 + pipe(pipes[i]);
363 + fds[i + 1].fd = pipes[i][0];
364 + fds[i + 1].events = POLLIN;
365 + getcmd(i, NULL);
366 + if (blocks[i].interval) {
367 + maxinterval = MAX(blocks[i].interval, maxinterv…
368 + sleepinterval = gcd(blocks[i].interval, sleepin…
369 + }
370 + }
371 +
372 + alarm(sleepinterval);
373 /* main event loop */
374 XSync(dpy, False);
375 - while (running && !XNextEvent(dpy, &ev))
376 - if (handler[ev.type])
377 - handler[ev.type](&ev); /* call handler */
378 + while (running) {
379 +
380 + /* bar hidden, then skip poll */
381 + if (!selmon->showbar) {
382 + XNextEvent(dpy, &ev);
383 + if (handler[ev.type])
384 + handler[ev.type](&ev); /* call handler …
385 + continue;
386 + }
387 +
388 + if ((poll(fds, LENGTH(blocks) + 1, -1)) == -1) {
389 + /* FIXME other than SIGALRM and the real time s…
390 + * there seems to be a signal being que if using
391 + * 'xsetroot -name' sutff */
392 + if (errno == EINTR) /* signal caught */
393 + continue;
394 + fprintf(stderr, "dwm: poll ");
395 + perror("failed");
396 + exit(EXIT_FAILURE);
397 + }
398 +
399 + /* handle display fd */
400 + if (fds[0].revents & POLLIN) {
401 + while (running && XPending(dpy)) {
402 + XNextEvent(dpy, &ev);
403 + if (handler[ev.type])
404 + handler[ev.type](&ev); /* call …
405 + }
406 + } else if (fds[0].revents & POLLHUP) {
407 + fprintf(stderr, "dwm: main event loop, hang up"…
408 + perror(" failed");
409 + exit(EXIT_FAILURE);
410 + }
411 +
412 + /* handle blocks */
413 + for (i = 0; i < LENGTH(blocks); i++) {
414 + if (fds[i + 1].revents & POLLIN) {
415 + /* empty buffer with CMDLENGTH + 1 byte…
416 + int bt = read(fds[i + 1].fd, blockoutpu…
417 + /* remove lock for the current block */
418 + execlock &= ~(1 << i);
419 +
420 + if (bt == -1) { /* if read failed */
421 + fprintf(stderr, "dwm: read fail…
422 + perror(" failed");
423 + continue;
424 + }
425 +
426 + if (blockoutput[i][bt - 1] == '\n') /* …
427 + blockoutput[i][bt - 1] = '\0';
428 + else /* NULL terminate the string */
429 + blockoutput[i][bt++] = '\0';
430 +
431 + drawbar(selmon);
432 + } else if (fds[i + 1].revents & POLLHUP) {
433 + fprintf(stderr, "dwm: block %d hangup",…
434 + perror(" failed");
435 + exit(EXIT_FAILURE);
436 + }
437 + }
438 + }
439 +
440 + /* close the pipes after running */
441 + for (i = 0; i < LENGTH(blocks); i++) {
442 + close(pipes[i][0]);
443 + close(pipes[i][1]);
444 + }
445 }
446
447 void
448 @@ -1427,6 +1650,13 @@ sendmon(Client *c, Monitor *m)
449 arrange(NULL);
450 }
451
452 +void
453 +sendstatusbar(const Arg *arg)
454 +{
455 + char button[2] = { '0' + arg->i & 0xff, '\0' };
456 + getcmd(blocknum, button);
457 +}
458 +
459 void
460 setclientstate(Client *c, long state)
461 {
462 @@ -1537,8 +1767,20 @@ setup(void)
463 XSetWindowAttributes wa;
464 Atom utf8string;
465
466 - /* clean up any zombies immediately */
467 - sigchld(0);
468 + setsignal(SIGCHLD, sigchld); /* zombies */
469 + setsignal(SIGALRM, sigalrm); /* timer */
470 +
471 + #ifdef __linux__
472 + /* handle defined real time signals (linux only) */
473 + for (i = 0; i < LENGTH(blocks); i++)
474 + if (blocks[i].signal)
475 + setsignal(SIGRTMIN + blocks[i].signal, getsigcm…
476 + #endif /* __linux__ */
477 +
478 + /* pid as an enviromental variable */
479 + char envpid[16];
480 + snprintf(envpid, LENGTH(envpid), "%d", getpid());
481 + setenv("STATUSBAR", envpid, 1);
482
483 /* init screen */
484 screen = DefaultScreen(dpy);
485 @@ -1600,6 +1842,21 @@ setup(void)
486 focus(NULL);
487 }
488
489 +void
490 +setsignal(int sig, void (*handler)(int unused))
491 +{
492 + struct sigaction sa;
493 +
494 + sa.sa_handler = handler;
495 + sigemptyset(&sa.sa_mask);
496 + sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
497 +
498 + if (sigaction(sig, &sa, 0) == -1) {
499 + fprintf(stderr, "signal %d ", sig);
500 + perror("failed to setup");
501 + exit(EXIT_FAILURE);
502 + }
503 +}
504
505 void
506 seturgent(Client *c, int urg)
507 @@ -1632,11 +1889,18 @@ showhide(Client *c)
508 }
509 }
510
511 +
512 +void
513 +sigalrm(int unused)
514 +{
515 + getcmds(count);
516 + alarm(sleepinterval);
517 + count = (count + sleepinterval - 1) % maxinterval + 1;
518 +}
519 +
520 void
521 sigchld(int unused)
522 {
523 - if (signal(SIGCHLD, sigchld) == SIG_ERR)
524 - die("can't install SIGCHLD handler:");
525 while (0 < waitpid(-1, NULL, WNOHANG));
526 }
527
528 @@ -1993,8 +2257,6 @@ updatesizehints(Client *c)
529 void
530 updatestatus(void)
531 {
532 - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
533 - strcpy(stext, "dwm-"VERSION);
534 drawbar(selmon);
535 }
536
537 --
538 2.36.1
539
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.