----
- config.def.h | 8 +++++++-
- dwm.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 51 insertions(+), 4 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..5cd7efa 100644
---- a/config.def.h
-+++ b/config.def.h
-_AT_@ -59,6 +59,10 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
- static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
- static const char *termcmd[] = { "st", NULL };
-
-+/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */
-+static char *statuscmds[] = { "notify-send Mouse$BUTTON" };
-+static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL };
-+
- static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
-_AT_@ -103,7 +107,9 @@ static Button buttons[] = {
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
-- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
-+ { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } },
-+ { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } },
-+ { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
-diff --git a/dwm.c b/dwm.c
-index 4465af1..d35d173 100644
---- a/dwm.c
-+++ b/dwm.c
-_AT_@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
- static void configure(Client *c);
- static void configurenotify(XEvent *e);
- static void configurerequest(XEvent *e);
-+static void copyvalidchars(char *text, char *rawtext);
- static Monitor *createmon(void);
- static void destroynotify(XEvent *e);
- static void detach(Client *c);
-_AT_@ -237,6 +238,9 @@ static void zoom(const Arg *arg);
- /* variables */
- static const char broken[] = "broken";
- static char stext[256];
-+static char rawstext[256];
-+static int statuscmdn;
-+static char lastbutton[] = "-";
- static int screen;
- static int sw, sh; /* X display screen geometry width, height */
- static int bh, blw = 0; /* bar geometry */
-_AT_@ -421,6 +425,7 @@ buttonpress(XEvent *e)
- Client *c;
- Monitor *m;
- XButtonPressedEvent *ev = &e->xbutton;
-+ *lastbutton = '0' + ev->button;
-
- click = ClkRootWin;
- /* focus monitor if necessary */
-_AT_@ -439,9 +444,26 @@ buttonpress(XEvent *e)
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
-- else if (ev->x > selmon->ww - TEXTW(stext))
-+ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
- click = ClkStatusText;
-- else
-+
-+ char *text = rawstext;
-+ int i = -1;
-+ char ch;
-+ statuscmdn = 0;
-+ while (text[++i]) {
-+ if ((unsigned char)text[i] < ' ') {
-+ ch = text[i];
-+ text[i] = '-+ x += TEXTW(text) - lrpad;
-+ text[i] = ch;
-+ text += i+1;
-+ i = -1;
-+ if (x >= ev->x) break;
-+ if (ch <= LENGTH(statuscmds)) statuscmdn = ch - 1;
-+ }
-+ }
-+ } else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
- focus(c);
-_AT_@ -627,6 +649,19 @@ configurerequest(XEvent *e)
- XSync(dpy, False);
- }
-
-+void
-+copyvalidchars(char *text, char *rawtext)
-+{
-+ int i = -1, j = 0;
-+
-+ while(rawtext[++i]) {
-+ if ((unsigned char)rawtext[i] >= ' ') {
-+ text[j++] = rawtext[i];
-+ }
-+ }
-+ text[j] = '-+}
-+
- Monitor *
- createmon(void)
- {
-_AT_@ -1641,6 +1676,10 @@ spawn(const Arg *arg)
- {
- if (arg->v == dmenucmd)
- dmenumon[0] = '0' + selmon->num;
-+ else if (arg->v == statuscmd) {
-+ statuscmd[2] = statuscmds[statuscmdn];
-+ setenv("BUTTON", lastbutton, 1);
-+ }
- if (fork() == 0) {
- if (dpy)
- close(ConnectionNumber(dpy));
-_AT_@ -1987,8 +2026,10 @@ updatesizehints(Client *c)
- void
- updatestatus(void)
- {
-- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
-+ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
- strcpy(stext, "dwm-"VERSION);
-+ else
-+ copyvalidchars(stext, rawstext);
- drawbar(selmon);
- }
-
---
-2.26.1
-
diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-20210402-67d76bd.diff b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-20210402-67d76bd.diff
new file mode 100644
index 00000000..1dc5c538
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-20210402-67d76bd.diff
_AT_@ -0,0 +1,167 @@
+From 02c4a28dd7f3a88eef3a4e533ace35f79cf09d57 Mon Sep 17 00:00:00 2001
+From: Daniel Bylinka <daniel.bylinka_AT_gmail.com>
+Date: Fri, 2 Apr 2021 19:34:38 +0200
+Subject: [PATCH] [statuscmd] Run shell commands based on mouse location and
+ button
+
+---
+ config.def.h | 10 ++++++-
+ dwm.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 81 insertions(+), 5 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..8f88366 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -59,6 +59,12 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
++/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */
++static const StatusCmd statuscmds[] = {
++ { "notify-send Mouse$BUTTON", 1 },
++};
++static const char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL };
++
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+_AT_@ -103,7 +109,9 @@ static Button buttons[] = {
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
++ { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } },
++ { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } },
++ { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
+diff --git a/dwm.c b/dwm.c
+index b0b3466..eb478a5 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -141,6 +141,11 @@ typedef struct {
+ int monitor;
+ } Rule;
+
++typedef struct {
++ const char *cmd;
++ int id;
++} StatusCmd;
++
+ /* function declarations */
+ static void applyrules(Client *c);
+ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
+_AT_@ -238,6 +243,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
++static int statusw;
++static int statuscmdn;
++static char lastbutton[] = "-";
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh, blw = 0; /* bar geometry */
+_AT_@ -440,8 +448,27 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - statusw) {
++ char *text, *s, ch;
++ *lastbutton = '0' + ev->button;
++
++ x = selmon->ww - statusw;
+ click = ClkStatusText;
++
++ statuscmdn = 0;
++ for (text = s = stext; *s && x <= ev->x; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ x += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ if (x >= ev->x)
++ break;
++ statuscmdn = ch;
++ }
++ }
++ }
+ else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+_AT_@ -704,9 +731,24 @@ drawbar(Monitor *m)
+
+ /* draw status first so it can be overdrawn by tags later */
+ if (m == selmon) { /* status is only drawn on selected monitor */
++ char *text, *s, ch;
+ drw_setscheme(drw, scheme[SchemeNorm]);
+- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
++
++ x = 0;
++ for (text = s = stext; *s; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ tw = TEXTW(text) - lrpad;
++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
++ x += tw;
++ *s = ch;
++ text = s + 1;
++ }
++ }
++ tw = TEXTW(text) - lrpad + 2;
++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
++ tw = statusw;
+ }
+
+ for (c = m->clients; c; c = c->next) {
+_AT_@ -1645,6 +1687,17 @@ spawn(const Arg *arg)
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
++ if (arg->v == statuscmd) {
++ for (int i = 0; i < LENGTH(statuscmds); i++) {
++ if (statuscmdn == statuscmds[i].id) {
++ statuscmd[2] = statuscmds[i].cmd;
++ setenv("BUTTON", lastbutton, 1);
++ break;
++ }
++ }
++ if (!statuscmd[2])
++ exit(EXIT_SUCCESS);
++ }
+ setsid();
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
+_AT_@ -1990,8 +2043,23 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) {
+ strcpy(stext, "dwm-"VERSION);
++ statusw = TEXTW(stext) - lrpad + 2;
++ } else {
++ char *text, *s, ch;
++ statusw = 0;
++ for (text = s = stext; *s; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ statusw += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ }
++ }
++ statusw += TEXTW(text) - lrpad + 2;
++ }
+ drawbar(selmon);
+ }
+
+--
+2.31.0
+
diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff
new file mode 100644
index 00000000..75a7bc0a
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff
_AT_@ -0,0 +1,171 @@
+From df16de3b4457fd6537e6efaa1785183770056ed6 Mon Sep 17 00:00:00 2001
+From: Daniel Bylinka <daniel.bylinka_AT_gmail.com>
+Date: Fri, 2 Apr 2021 19:33:35 +0200
+Subject: [PATCH] [statuscmd] status2d compatibility for statuscmd-nosignal
+
+---
+ config.def.h | 10 +++++++-
+ dwm.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 72 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..8f88366 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -59,6 +59,12 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
++/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */
++static const StatusCmd statuscmds[] = {
++ { "notify-send Mouse$BUTTON", 1 },
++};
++static const char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL };
++
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+_AT_@ -103,7 +109,9 @@ static Button buttons[] = {
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
++ { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } },
++ { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } },
++ { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
+diff --git a/dwm.c b/dwm.c
+index acbe6c9..851b0ed 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -141,6 +141,11 @@ typedef struct {
+ int monitor;
+ } Rule;
+
++typedef struct {
++ const char *cmd;
++ int id;
++} StatusCmd;
++
+ /* function declarations */
+ static void applyrules(Client *c);
+ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
+_AT_@ -239,6 +244,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[1024];
++static int statusw;
++static int statuscmdn;
++static char lastbutton[] = "-";
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh, blw = 0; /* bar geometry */
+_AT_@ -441,8 +449,27 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - statusw) {
++ char *text, *s, ch;
++ *lastbutton = '0' + ev->button;
++
++ x = selmon->ww - statusw;
+ click = ClkStatusText;
++
++ statuscmdn = 0;
++ for (text = s = stext; *s && x <= ev->x; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ x += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ if (x >= ev->x)
++ break;
++ statuscmdn = ch;
++ }
++ }
++ }
+ else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+_AT_@ -696,7 +723,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;
+_AT_@ -705,7 +732,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] = '+
+ /* compute width of the status text */
+ w = 0;
+_AT_@ -813,7 +845,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) {
+_AT_@ -1753,6 +1785,17 @@ spawn(const Arg *arg)
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
++ if (arg->v == statuscmd) {
++ for (int i = 0; i < LENGTH(statuscmds); i++) {
++ if (statuscmdn == statuscmds[i].id) {
++ statuscmd[2] = statuscmds[i].cmd;
++ setenv("BUTTON", lastbutton, 1);
++ break;
++ }
++ }
++ if (!statuscmd[2])
++ exit(EXIT_SUCCESS);
++ }
+ setsid();
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
+_AT_@ -2098,8 +2141,23 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) {
+ strcpy(stext, "dwm-"VERSION);
++ statusw = TEXTW(stext) - lrpad + 2;
++ } else {
++ char *text, *s, ch;
++ statusw = 0;
++ for (text = s = stext; *s; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ statusw += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ }
++ }
++ statusw += TEXTW(text) - lrpad + 2;
++ }
+ drawbar(selmon);
+ }
+
+--
+2.31.0
+
diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff
deleted file mode 100644
index 97fda1bb..00000000
--- a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff
+++ /dev/null
_AT_@ -1,157 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..b67825e 100644
---- a/config.def.h
-+++ b/config.def.h
-_AT_@ -103,7 +103,9 @@ static Button buttons[] = {
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
-- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
-+ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
-+ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
-+ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
-diff --git a/dwm.c b/dwm.c
-index 4465af1..c600131 100644
---- a/dwm.c
-+++ b/dwm.c
-_AT_@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
- static void configure(Client *c);
- static void configurenotify(XEvent *e);
- static void configurerequest(XEvent *e);
-+static void copyvalidchars(char *text, char *rawtext);
- static Monitor *createmon(void);
- static void destroynotify(XEvent *e);
- static void detach(Client *c);
-_AT_@ -169,6 +170,7 @@ static void focus(Client *c);
- static void focusin(XEvent *e);
- static void focusmon(const Arg *arg);
- static void focusstack(const Arg *arg);
-+static int getdwmblockspid();
- static int getrootptr(int *x, int *y);
- static long getstate(Window w);
- static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
-_AT_@ -205,6 +207,7 @@ static void setup(void);
- static void seturgent(Client *c, int urg);
- static void showhide(Client *c);
- static void sigchld(int unused);
-+static void sigdwmblocks(const Arg *arg);
- static void spawn(const Arg *arg);
- static void tag(const Arg *arg);
- static void tagmon(const Arg *arg);
-_AT_@ -237,6 +240,9 @@ static void zoom(const Arg *arg);
- /* variables */
- static const char broken[] = "broken";
- static char stext[256];
-+static char rawstext[256];
-+static int dwmblockssig;
-+pid_t dwmblockspid = 0;
- static int screen;
- static int sw, sh; /* X display screen geometry width, height */
- static int bh, blw = 0; /* bar geometry */
-_AT_@ -439,9 +445,26 @@ buttonpress(XEvent *e)
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
-- else if (ev->x > selmon->ww - TEXTW(stext))
-+ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
- click = ClkStatusText;
-- else
-+
-+ char *text = rawstext;
-+ int i = -1;
-+ char ch;
-+ dwmblockssig = 0;
-+ while (text[++i]) {
-+ if ((unsigned char)text[i] < ' ') {
-+ ch = text[i];
-+ text[i] = '-+ x += TEXTW(text) - lrpad;
-+ text[i] = ch;
-+ text += i+1;
-+ i = -1;
-+ if (x >= ev->x) break;
-+ dwmblockssig = ch;
-+ }
-+ }
-+ } else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
- focus(c);
-_AT_@ -627,6 +650,19 @@ configurerequest(XEvent *e)
- XSync(dpy, False);
- }
-
-+void
-+copyvalidchars(char *text, char *rawtext)
-+{
-+ int i = -1, j = 0;
-+
-+ while(rawtext[++i]) {
-+ if ((unsigned char)rawtext[i] >= ' ') {
-+ text[j++] = rawtext[i];
-+ }
-+ }
-+ text[j] = '-+}
-+
- Monitor *
- createmon(void)
- {
-_AT_@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop)
- return atom;
- }
-
-+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;
-+}
-+
- int
- getrootptr(int *x, int *y)
- {
-_AT_@ -1636,6 +1684,23 @@ sigchld(int unused)
- while (0 < waitpid(-1, NULL, WNOHANG));
- }
-
-+void
-+sigdwmblocks(const Arg *arg)
-+{
-+ union sigval sv;
-+ sv.sival_int = (dwmblockssig << 8) | arg->i;
-+ if (!dwmblockspid)
-+ if (getdwmblockspid() == -1)
-+ return;
-+
-+ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) {
-+ if (errno == ESRCH) {
-+ if (!getdwmblockspid())
-+ sigqueue(dwmblockspid, SIGUSR1, sv);
-+ }
-+ }
-+}
-+
- void
- spawn(const Arg *arg)
- {
-_AT_@ -1987,8 +2052,10 @@ updatesizehints(Client *c)
- void
- updatestatus(void)
- {
-- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
-+ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
- strcpy(stext, "dwm-"VERSION);
-+ else
-+ copyvalidchars(stext, rawstext);
- drawbar(selmon);
- }
-
diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-status2d-20210402-60bb3df.diff b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-status2d-20210402-60bb3df.diff
new file mode 100644
index 00000000..6160f52a
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-status2d-20210402-60bb3df.diff
_AT_@ -0,0 +1,187 @@
+From 9e7935657bdea456db3eb858ac44bb0a671c2b7a Mon Sep 17 00:00:00 2001
+From: Daniel Bylinka <daniel.bylinka_AT_gmail.com>
+Date: Fri, 2 Apr 2021 19:04:58 +0200
+Subject: [PATCH] [statuscmd] status2d compatibility
+
+---
+ config.def.h | 6 +++-
+ dwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 82 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..154a59b 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -54,6 +54,8 @@ static const Layout layouts[] = {
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
++#define STATUSBAR "dwmblocks"
++
+ /* commands */
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+_AT_@ -103,7 +105,9 @@ static Button buttons[] = {
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
++ { ClkStatusText, 0, Button1, sigstatusbar, {.i = 1} },
++ { ClkStatusText, 0, Button2, sigstatusbar, {.i = 2} },
++ { ClkStatusText, 0, Button3, sigstatusbar, {.i = 3} },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
+diff --git a/dwm.c b/dwm.c
+index acbe6c9..da746a1 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -173,6 +173,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);
+_AT_@ -207,6 +208,7 @@ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
++static void sigstatusbar(const Arg *arg);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+_AT_@ -239,6 +241,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[1024];
++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, blw = 0; /* bar geometry */
+_AT_@ -441,9 +446,34 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - statusw) {
++ x = selmon->ww - statusw;
+ click = ClkStatusText;
+- else
++
++ char *text, *s, ch;
++ statussig = 0;
++ for (text = s = stext; *s && x <= ev->x; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '++ x += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ if (x >= ev->x)
++ break;
++ statussig = ch;
++ } else if (*s == '^') {
++ *s = '++ x += TEXTW(text) - lrpad;
++ *s = '^';
++ if (*(++s) == 'f')
++ x += atoi(++s);
++ while (*(s++) != '^');
++ text = s;
++ s--;
++ }
++ }
++ } else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+ focus(c);
+_AT_@ -696,7 +726,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;
+_AT_@ -705,7 +735,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] = '+
+ /* compute width of the status text */
+ w = 0;
+_AT_@ -813,7 +848,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) {
+_AT_@ -979,6 +1014,29 @@ getatomprop(Client *c, Atom prop)
+ return atom;
+ }
+
++pid_t
++getstatusbarpid()
++{
++ 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;
++ fgets(buf, sizeof(buf), fp);
++ return pclose(fp) == 0 ? strtoul(buf, NULL, 10) : -1;
++}
++
+ int
+ getrootptr(int *x, int *y)
+ {
+_AT_@ -1745,6 +1803,20 @@ sigchld(int unused)
+ while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+
++void
++sigstatusbar(const Arg *arg)
++{
++ union sigval sv;
++
++ if (!statussig)
++ return;
++ sv.sival_int = arg->i;
++ if ((statuspid = getstatusbarpid()) <= 0)
++ return;
++
++ sigqueue(statuspid, SIGRTMIN+statussig, sv);
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+--
+2.31.0
+
diff --git a/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd-20210402-96cbb45.diff b/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd-20210402-96cbb45.diff
new file mode 100644
index 00000000..bb2cbb65
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd-20210402-96cbb45.diff
_AT_@ -0,0 +1,127 @@
+From 1669878c08607f481e3f879d6914fc4d3c9d7206 Mon Sep 17 00:00:00 2001
+From: Daniel Bylinka <daniel.bylinka_AT_gmail.com>
+Date: Fri, 2 Apr 2021 19:20:17 +0200
+Subject: [PATCH] [statuscmd] Format status text and handle button signals
+
+---
+ dwmblocks.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 41 insertions(+), 7 deletions(-)
+
+diff --git a/dwmblocks.c b/dwmblocks.c
+index ded717c..78fdeb5 100644
+--- a/dwmblocks.c
++++ b/dwmblocks.c
+_AT_@ -3,6 +3,7 @@
+ #include<string.h>
+ #include<unistd.h>
+ #include<signal.h>
++#include<sys/wait.h>
+ #ifndef NO_X
+ #include<X11/Xlib.h>
+ #endif
+_AT_@ -27,14 +28,14 @@ typedef struct {
+ #ifndef __OpenBSD__
+ void dummysighandler(int num);
+ #endif
+-void sighandler(int num);
+ void getcmds(int time);
+ void getsigcmds(unsigned int signal);
+ void setupsignals();
+-void sighandler(int signum);
++void sighandler(int signum, siginfo_t *si, void *ucontext);
+ int getstatus(char *str, char *last);
+ void statusloop();
+ void termhandler();
++void chldhandler();
+ void pstdout();
+ #ifndef NO_X
+ void setroot();
+_AT_@ -58,6 +59,8 @@ static int returnStatus = 0;
+ //opens process *cmd and stores output in *output
+ void getcmd(const Block *block, char *output)
+ {
++ if (block->signal)
++ *output++ = block->signal;
+ strcpy(output, block->icon);
+ FILE *cmdf = popen(block->command, "r");
+ if (!cmdf)
+_AT_@ -102,15 +105,18 @@ void getsigcmds(unsigned int signal)
+
+ void setupsignals()
+ {
++ struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO };
+ #ifndef __OpenBSD__
+ /* initialize all real time signals with dummy handler */
+- for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
++ for (int i = SIGRTMIN; i <= SIGRTMAX; i++) {
+ signal(i, dummysighandler);
++ sigaddset(&sa.sa_mask, i);
++ }
+ #endif
+
+ for (unsigned int i = 0; i < LENGTH(blocks); i++) {
+ if (blocks[i].signal > 0)
+- signal(SIGMINUS+blocks[i].signal, sighandler);
++ sigaction(SIGMINUS+blocks[i].signal, &sa, NULL);
+ }
+
+ }
+_AT_@ -178,10 +184,32 @@ void dummysighandler(int signum)
+ }
+ #endif
+
+-void sighandler(int signum)
++void sighandler(int signum, siginfo_t *si, void *ucontext)
+ {
+- getsigcmds(signum-SIGPLUS);
+- writestatus();
++ if (si->si_value.sival_int) {
++ pid_t parent = getpid();
++ if (fork() == 0) {
++#ifndef NO_X
++ if (dpy)
++ close(ConnectionNumber(dpy));
++#endif
++ int i;
++ for (i = 0; i < LENGTH(blocks) && blocks[i].signal != signum-SIGRTMIN; i++);
++
++ char shcmd[1024];
++ sprintf(shcmd, "%s; kill -%d %d", blocks[i].command, SIGRTMIN+blocks[i].signal, parent);
++ char *cmd[] = { "/bin/sh", "-c", shcmd, NULL };
++ char button[2] = { '0' + si->si_value.sival_int, '++ setenv("BUTTON", button, 1);
++ setsid();
++ execvp(cmd[0], cmd);
++ perror(cmd[0]);
++ exit(EXIT_SUCCESS);
++ }
++ } else {
++ getsigcmds(signum-SIGPLUS);
++ writestatus();
++ }
+ }
+
+ void termhandler()
+_AT_@ -189,6 +217,11 @@ void termhandler()
+ statusContinue = 0;
+ }
+
++void chldhandler()
++{
++ while (0 < waitpid(-1, NULL, WNOHANG));
++}
++
+ int main(int argc, char** argv)
+ {
+ for (int i = 0; i < argc; i++) {//Handle command line arguments
+_AT_@ -205,6 +238,7 @@ int main(int argc, char** argv)
+ delim[delimLen++] = '+ signal(SIGTERM, termhandler);
+ signal(SIGINT, termhandler);
++ signal(SIGCHLD, chldhandler);
+ statusloop();
+ #ifndef NO_X
+ XCloseDisplay(dpy);
+--
+2.31.0
+
diff --git a/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff b/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff
deleted file mode 100644
index 961f22a4..00000000
--- a/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff
+++ /dev/null
_AT_@ -1,80 +0,0 @@
-diff --git a/dwmblocks.c b/dwmblocks.c
-index 2f3b774..ba7dbb5 100644
---- a/dwmblocks.c
-+++ b/dwmblocks.c
-_AT_@ -14,6 +14,7 @@ typedef struct {
- unsigned int signal;
- } Block;
- void sighandler(int num);
-+void buttonhandler(int sig, siginfo_t *si, void *ucontext);
- void getcmds(int time);
- #ifndef __OpenBSD__
- void getsigcmds(int signal);
-_AT_@ -33,15 +34,32 @@ static int screen;
- static Window root;
- static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
- static char statusstr[2][256];
-+static char button[] = "- static int statusContinue = 1;
- static void (*writestatus) () = setroot;
-
- //opens process *cmd and stores output in *output
- void getcmd(const Block *block, char *output)
- {
-+ if (block->signal)
-+ {
-+ output[0] = block->signal;
-+ output++;
-+ }
- strcpy(output, block->icon);
- char *cmd = block->command;
-- FILE *cmdf = popen(cmd,"r");
-+ FILE *cmdf;
-+ if (*button)
-+ {
-+ setenv("BUTTON", button, 1);
-+ cmdf = popen(cmd,"r");
-+ *button = '-+ unsetenv("BUTTON");
-+ }
-+ else
-+ {
-+ cmdf = popen(cmd,"r");
-+ }
- if (!cmdf)
- return;
- char c;
-_AT_@ -79,12 +97,18 @@ void getsigcmds(int signal)
-
- void setupsignals()
- {
-+ struct sigaction sa;
- for(int i = 0; i < LENGTH(blocks); i++)
- {
- if (blocks[i].signal > 0)
-+ {
- signal(SIGRTMIN+blocks[i].signal, sighandler);
-+ sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); // ignore signal when handling SIGUSR1
-+ }
- }
--
-+ sa.sa_sigaction = buttonhandler;
-+ sa.sa_flags = SA_SIGINFO;
-+ sigaction(SIGUSR1, &sa, NULL);
- }
- #endif
-
-_AT_@ -143,6 +167,13 @@ void sighandler(int signum)
- getsigcmds(signum-SIGRTMIN);
- writestatus();
- }
-+
-+void buttonhandler(int sig, siginfo_t *si, void *ucontext)
-+{
-+ *button = '0' + si->si_value.sival_int & 0xff;
-+ getsigcmds(si->si_value.sival_int >> 8);
-+ writestatus();
-+}
- #endif
-
- void termhandler(int signum)
diff --git a/dwm.suckless.org/patches/statuscmd/index.md b/dwm.suckless.org/patches/statuscmd/index.md
index c320d3ce..c4e5d2b4 100644
--- a/dwm.suckless.org/patches/statuscmd/index.md
+++ b/dwm.suckless.org/patches/statuscmd/index.md
_AT_@ -3,67 +3,101 @@ statuscmd
Description
-----------
-This patch adds the ability to execute shell commands based on the mouse
-button and position when clicking the status bar.
+This patch adds the ability to signal a status monitor program such as
+[dwmblocks](https://github.com/torrinfail/dwmblocks) the location and button
+when clicking on the status bar. Alternatively, there is a version that
+executes shell commands defined in config.h instead of using signals.
Usage
-----
-Fill 'statuscmds' with commands. Choose which command to run by prefixing
-the status text with a raw byte of the command's index in 'statuscmds',
-offset by +1 since '-if there is no index to the left of the mouse position. The mouse button
-clicked is exported as $BUTTON.
+Both the nosignal version and the dwmblocks version will run their respective
+shell commands/scripts with the environment variable BUTTON set to the button
+that was pressed.
-Example
--------
-With these commands:
+### With signals
+Apply the statuscmd patch and set the `STATUSBAR` macro in config.h
+to the name of the status monitor.
+
+Apply the corresponding statuscmd patch to your status monitor if there is
+one, or extend the program on your own. Feel free to add patches for other
+status monitors.
+
+#### Patching status monitors
+* Assosiate each section with a signal number in the range of 1-31.
+* When setting the status text, print each section's respective signal number
+ as a raw byte before its text.
+* Create a signal handler:
+
+ void sighandler(int signum, siginfo_t *si, void *ucontext)
+ {
+ int signal = signum - SIGRTMIN;
+ int button = si->si_value.sival_int; /* if button is zero, the signal is not from a button press */
+ ... /* do whatever you want */
+ }
+
+* Register the signal handler for each section in the following way, with
+ 'signal' being the same signal from the first step:
+
+ struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO };
+ sigaction(SIGRTMIN+signal, &sa, NULL);
+
+### Without signals
+Apply the statuscmd-nosignal patch and fill the `statuscmds` array in config.h
+with `StatusCmd` structs, which take a shell command string and an integer
+identifier.
- static const char *statuscmds[] = { "volume", "cpu", "battery" };
+When setting the status, print the integer identifier as a raw byte before its
+respective text.
+
+For example, with `statuscmds` defined as such:
+
+ static const StatusCmd statuscmds[] = {
+ { "volume", 1 },
+ { "cpu", 2 },
+ { "battery", 3 },
+ };
And root name set like this:
- xsetroot -name "$(echo -e 'volume |\x02 cpu |\x03 battery')"
+ xsetroot -name "$(printf '\x01Volume |\x02 CPU |\x03 Battery')"
-Clicking on 'volume |' would run `volume`, clicking on ' cpu |'
-would run `cpu` and clicking on ' battery' would run `battery`.
+Clicking on 'Volume |' would run `volume`, clicking on ' CPU |'
+would run `cpu` and clicking on ' Battery' would run `battery`.
-The `cpu` script could look like this:
+Example
+-------
+A script run from dwm or dwmblocks with this patch might look like this:
#!/bin/sh
case $BUTTON in
- 1) notify-send "CPU usage" "$(ps axch -o cmd,%cpu --sort=-%cpu | head)";;
- 3) st -e htop;;
+ 1) notify-send "CPU usage" "$(ps axch -o cmd,%cpu --sort=-%cpu | head)" ;;
+ 3) st -e htop ;;
esac
Notes
-----
-If you have 10 or more commands, make sure to be careful when adding or
-removing newline characters since '
' is equal to '\x0a'. The problem
-where having certain unprintable characters such as '
' in the status
-string can make dwm laggy is "fixed", since they are not copied to the
-string that is actually drawn.
-
-dwmblocks integration
----------------------
-A program that sets the status for dwm such as
-[dwmblocks](https://github.com/torrinfail/dwmblocks) can be patched to manage
-the commands while dwm only finds the location clicked in the status bar.
-This way, no changes are needed in dwm when adding or reordering modules.
-
-Instead of running a command from within dwm using the control character
-as an index, the dwm-statuscmd-signal patch sends a SIGUSR1 signal to
-dwmblocks with the button and control character encoded into the signal value.
-
-The dwmblocks-statuscmd patch makes dwmblocks put each block's signal in
-front of its output text and handles the SIGUSR1 signal by running the
-block's command with $BUTTON exported.
+The signal version is not compatible with OpenBSD since it relies on `sigqueue`.
+
+Be careful with newline characters in the status text since '
' is equal to
+'\x0a', which is a valid signal number. The problem where having certain
+undrawable characters in the status bar can make dwm laggy is fixed since dwm
+will not attempt to draw them with this patch.
Download
--------
-* [dwm-statuscmd-6.2.diff](dwm-statuscmd-6.2.diff)
-* [dwm-statuscmd-signal-6.2.diff](dwm-statuscmd-signal-6.2.diff)
-* [dwmblocks-statuscmd.diff](dwmblocks-statuscmd.diff)
+### dwm patches
+* [dwm-statuscmd-20210402-67d76bd.diff](dwm-statuscmd-20210402-67d76bd.diff)
+* [dwm-statuscmd-nosignal-20210402-67d76bd.diff](dwm-statuscmd-nosignal-20210402-67d76bd.diff)
+
+If using [status2d](https://dwm.suckless.org/patches/status2d/), use these patches instead of the
+above ones on top of a build already patched with status2d:
+
+* [dwm-statuscmd-status2d-20210402-60bb3df.diff](dwm-statuscmd-status2d-20210402-60bb3df.diff)
+* [dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff](dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff)
+
+### Status monitor patches
+* [dwmblocks-statuscmd-20210402-96cbb45.diff](dwmblocks-statuscmd-20210402-96cbb45.diff)
Author
------
Received on Fri Apr 02 2021 - 20:21:26 CEST
This archive was generated by hypermail 2.3.0 : Fri Apr 02 2021 - 20:24:35 CEST