From 5d984affdafe9e7f46855ebe53761aebd6b8c8b9 Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Sat, 31 Jan 2026 15:02:47 -0700 Subject: Applied dwm-statuscmd-status2d diff patch w/ manual intervation. The patch fixes the offset clickable buttons in dwmblocks. The off set is re-drawn correctly to the block itself whilst allowing the ability to render the blocks in different colors using status2d. --- config.h | 11 +++-- dwm.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 120 insertions(+), 45 deletions(-) diff --git a/config.h b/config.h index 7589830..1bb45cc 100644 --- a/config.h +++ b/config.h @@ -3,7 +3,9 @@ /* Constants */ #define TERMINAL "st" #define TERMCLASS "St" -#define BROWSER "firefox" +/*#define BROWSER "firefox"*/ +#define BROWSER "qutebrowser" +#define STATUSBAR "dwmblocks" /* appearance */ static unsigned int borderpx = 3; /* border pixel of windows */ @@ -18,14 +20,17 @@ static int showbar = 1; /* 0 means no bar */ static int topbar = 1; /* 0 means bottom bar */ /* static char *fonts[] = { "monospace:size=10", "NotoColorEmoji:pixelsize=10:antialias=true:autohint=true" }; */ /*static char *fonts[] = { "CaskaydiaCove Nerd Font Mono:style=SemiLight:size=10", "NotoColorEmoji:pixelsize=10:antialias=true:autohint=true" };*/ -static char *fonts[] = { "CaskaydiaCove Nerd Font Mono:style=SemiLight:size=10", "Symbols Nerd Font:pixelsize=10:antialias=true:autohint=true"/*, "NotoColorEmoji:pixelsize=10:antialias=true:autohint=true"*/ }; +static char *fonts[] = { "CaskaydiaCove Nerd Font Mono:style=SemiLight:size=10", "Symbols Nerd Font Mono:size=10:antialias=true:autohint=true" /*, "NotoColorEmoji:pixelsize=10:antialias=true:autohint=true" */ }; static char normbgcolor[] = "#222222"; static char normbordercolor[] = "#444444"; static char normfgcolor[] = "#bbbbbb"; static char selfgcolor[] = "#eeeeee"; /* static char selbordercolor[] = "#770000";*/ static char selbordercolor[] = "#ae8c8c"; -static char selbgcolor[] = "#005577"; +/*static char selbgcolor[] = "#005577";*/ +/*static char selbgcolor[] = "#26704c";*/ +/*static char selbgcolor[] = "#113825";*/ +static char selbgcolor[] = "#474948"; static char *colors[][3] = { /* fg bg border */ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, diff --git a/dwm.c b/dwm.c index 1722089..6f26857 100644 --- a/dwm.c +++ b/dwm.c @@ -209,6 +209,7 @@ static void focusstack(const Arg *arg); static Atom getatomprop(Client *c, Atom prop); static int getrootptr(int *x, int *y); static long getstate(Window w); +static pid_t getstatusbarpid(); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, int focused); static void grabkeys(void); @@ -247,7 +248,6 @@ static void seturgent(Client *c, int urg); static void showhide(Client *c); static void sigchld(int unused); #ifndef __OpenBSD__ -static int getdwmblockspid(); static void sigdwmblocks(const Arg *arg); #endif static void sighup(int unused); @@ -298,8 +298,9 @@ static pid_t winpid(Window w); static const char broken[] = "broken"; static char stext[1024]; static char rawstext[256]; -static int dwmblockssig; -pid_t dwmblockspid = 0; +static int statussig; +static int statusw; +static pid_t statuspid = -1; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh; /* bar height */ @@ -546,6 +547,48 @@ unswallow(Client *c) arrange(c->mon); } + +static int +status2d_width(const char *str) +{ + int i, w = 0; + short isCode = 0; + char *text, *p; + + if (!str) + return 0; + + /* make a writable copy because we insert '\0' */ + if (!(text = strdup(str))) + die("strdup"); + p = text; + + i = -1; + while (text[++i]) { + if (text[i] == '^') { + if (!isCode) { + isCode = 1; + text[i] = '\0'; + w += TEXTW(text) - lrpad; + text[i] = '^'; + + if (text[++i] == 'f') + w += atoi(text + ++i); + } else { + isCode = 0; + text = text + i + 1; + i = -1; + } + } + } + + if (!isCode) + w += TEXTW(text) - lrpad; + + free(p); + return w; +} + void buttonpress(XEvent *e) { @@ -556,7 +599,6 @@ buttonpress(XEvent *e) XButtonPressedEvent *ev = &e->xbutton; click = ClkRootWin; - /* focus monitor if necessary */ if ((m = wintomon(ev->window)) && m != selmon) { unfocus(selmon->sel, 1); selmon = m; @@ -567,7 +609,6 @@ buttonpress(XEvent *e) for (c = m->clients; c; c = c->next) occ |= c->tags == 255 ? 0 : c->tags; do { - /* do not reserve space for vacant tags */ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue; x += TEXTW(tags[i]); @@ -577,23 +618,26 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + TEXTW(selmon->ltsymbol)) click = ClkLtSymbol; - else if (ev->x > (x = selmon->ww - (int)TEXTW(stext) + lrpad)) { + else if (ev->x > selmon->ww - statusw) { + x = selmon->ww - statusw; click = ClkStatusText; + char *text, *s, ch; + statussig = 0; + + for (text = s = rawstext; *s && x <= ev->x; s++) { + if ((unsigned char)(*s) < ' ') { + ch = *s; + *s = '\0'; - char *text = rawstext; - int i = -1; - char ch; - dwmblockssig = 0; - while (text[++i]) { - if ((unsigned char)text[i] < ' ') { - ch = text[i]; - text[i] = '\0'; - x += TEXTW(text) - lrpad; - text[i] = ch; - text += i+1; - i = -1; - if (x >= ev->x) break; - dwmblockssig = ch; + x += status2d_width(text); + + *s = ch; + text = s + 1; + + if (x >= ev->x) + break; + + statussig = ch; } } } else @@ -870,7 +914,7 @@ dirtomon(int dir) int drawstatusbar(Monitor *m, int bh, char* stext) { - int ret, i, w, x, len; + int ret, i, j, w, x, len; short isCode = 0; char *text; char *p; @@ -879,7 +923,12 @@ drawstatusbar(Monitor *m, int bh, char* stext) { if (!(text = (char*) malloc(sizeof(char)*len))) die("malloc"); p = text; - memcpy(text, stext, len); + + i = -1, j = 0; + while (stext[++i]) + if ((unsigned char)stext[i] >= ' ') + text[j++] = stext[i]; + text[j] = '\0'; /* compute width of the status text */ w = 0; @@ -990,7 +1039,7 @@ drawbar(Monitor *m) /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ - tw = m->ww - drawstatusbar(m, bh, stext); + tw = statusw = m->ww - drawstatusbar(m, bh, stext); } for (c = m->clients; c; c = c->next) { @@ -1150,17 +1199,35 @@ getatomprop(Client *c, Atom prop) return atom; } + #ifndef __OpenBSD__ -int -getdwmblockspid() -{ - char buf[16]; - FILE *fp = popen("pidof -s dwmblocks", "r"); - fgets(buf, sizeof(buf), fp); - pid_t pid = strtoul(buf, NULL, 10); - pclose(fp); - dwmblockspid = pid; - return pid != 0 ? 0 : -1; +pid_t +getstatusbarpid(void) +{ + char buf[32], *str = buf, *c; + FILE *fp; + + if (statuspid > 0) { + snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid); + if ((fp = fopen(buf, "r"))) { + fgets(buf, sizeof(buf), fp); + while ((c = strchr(str, '/'))) + str = c + 1; + fclose(fp); + if (!strcmp(str, STATUSBAR)) + return statuspid; + } + } + if (!(fp = popen("pidof -s " STATUSBAR, "r"))) + return -1; + if (!fgets(buf, sizeof(buf), fp)) { + pclose(fp); + return -1; + } + pclose(fp); + + statuspid = strtoul(buf, NULL, 10); + return statuspid ? statuspid : -1; } #endif @@ -2041,16 +2108,19 @@ void sigdwmblocks(const Arg *arg) { union sigval sv; - sv.sival_int = 0 | (dwmblockssig << 8) | arg->i; - if (!dwmblockspid) - if (getdwmblockspid() == -1) - return; + pid_t pid; - if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) { - if (errno == ESRCH) { - if (!getdwmblockspid()) - sigqueue(dwmblockspid, SIGUSR1, sv); - } + sv.sival_int = 0 | (statussig << 8) | arg->i; + + pid = getstatusbarpid(); + if (pid == -1) + return; + + if (sigqueue(pid, SIGUSR1, sv) == -1 && errno == ESRCH) { + statuspid = -1; /* cached pid is stale */ + pid = getstatusbarpid(); + if (pid != -1) + sigqueue(pid, SIGUSR1, sv); } } #endif -- cgit v1.2.3