dwm-statuscmd-nosignal-status2d-20210402-60bb3df.diff (5550B)
1 From df16de3b4457fd6537e6efaa1785183770056ed6 Mon Sep 17 00:00:00 2001 2 From: Daniel Bylinka <daniel.bylinka@gmail.com> 3 Date: Fri, 2 Apr 2021 19:33:35 +0200 4 Subject: [PATCH] [statuscmd] status2d compatibility for statuscmd-nosignal 5 6 --- 7 config.def.h | 10 +++++++- 8 dwm.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++---- 9 2 files changed, 72 insertions(+), 6 deletions(-) 10 11 diff --git a/config.def.h b/config.def.h 12 index 1c0b587..8f88366 100644 13 --- a/config.def.h 14 +++ b/config.def.h 15 @@ -59,6 +59,12 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() 16 static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; 17 static const char *termcmd[] = { "st", NULL }; 18 19 +/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */ 20 +static const StatusCmd statuscmds[] = { 21 + { "notify-send Mouse$BUTTON", 1 }, 22 +}; 23 +static const char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; 24 + 25 static Key keys[] = { 26 /* modifier key function argument */ 27 { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 28 @@ -103,7 +109,9 @@ static Button buttons[] = { 29 { ClkLtSymbol, 0, Button1, setlayout, {0} }, 30 { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 31 { ClkWinTitle, 0, Button2, zoom, {0} }, 32 - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 33 + { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } }, 34 + { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } }, 35 + { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } }, 36 { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 37 { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 38 { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 39 diff --git a/dwm.c b/dwm.c 40 index acbe6c9..851b0ed 100644 41 --- a/dwm.c 42 +++ b/dwm.c 43 @@ -141,6 +141,11 @@ typedef struct { 44 int monitor; 45 } Rule; 46 47 +typedef struct { 48 + const char *cmd; 49 + int id; 50 +} StatusCmd; 51 + 52 /* function declarations */ 53 static void applyrules(Client *c); 54 static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); 55 @@ -239,6 +244,9 @@ static void zoom(const Arg *arg); 56 /* variables */ 57 static const char broken[] = "broken"; 58 static char stext[1024]; 59 +static int statusw; 60 +static int statuscmdn; 61 +static char lastbutton[] = "-"; 62 static int screen; 63 static int sw, sh; /* X display screen geometry width, height */ 64 static int bh, blw = 0; /* bar geometry */ 65 @@ -441,8 +449,27 @@ buttonpress(XEvent *e) 66 arg.ui = 1 << i; 67 } else if (ev->x < x + blw) 68 click = ClkLtSymbol; 69 - else if (ev->x > selmon->ww - (int)TEXTW(stext)) 70 + else if (ev->x > selmon->ww - statusw) { 71 + char *text, *s, ch; 72 + *lastbutton = '0' + ev->button; 73 + 74 + x = selmon->ww - statusw; 75 click = ClkStatusText; 76 + 77 + statuscmdn = 0; 78 + for (text = s = stext; *s && x <= ev->x; s++) { 79 + if ((unsigned char)(*s) < ' ') { 80 + ch = *s; 81 + *s = '\0'; 82 + x += TEXTW(text) - lrpad; 83 + *s = ch; 84 + text = s + 1; 85 + if (x >= ev->x) 86 + break; 87 + statuscmdn = ch; 88 + } 89 + } 90 + } 91 else 92 click = ClkWinTitle; 93 } else if ((c = wintoclient(ev->window))) { 94 @@ -696,7 +723,7 @@ dirtomon(int dir) 95 96 int 97 drawstatusbar(Monitor *m, int bh, char* stext) { 98 - int ret, i, w, x, len; 99 + int ret, i, j, w, x, len; 100 short isCode = 0; 101 char *text; 102 char *p; 103 @@ -705,7 +732,12 @@ drawstatusbar(Monitor *m, int bh, char* stext) { 104 if (!(text = (char*) malloc(sizeof(char)*len))) 105 die("malloc"); 106 p = text; 107 - memcpy(text, stext, len); 108 + 109 + i = -1, j = 0; 110 + while (stext[++i]) 111 + if ((unsigned char)stext[i] >= ' ') 112 + text[j++] = stext[i]; 113 + text[j] = '\0'; 114 115 /* compute width of the status text */ 116 w = 0; 117 @@ -813,7 +845,7 @@ drawbar(Monitor *m) 118 119 /* draw status first so it can be overdrawn by tags later */ 120 if (m == selmon) { /* status is only drawn on selected monitor */ 121 - tw = m->ww - drawstatusbar(m, bh, stext); 122 + tw = statusw = m->ww - drawstatusbar(m, bh, stext); 123 } 124 125 for (c = m->clients; c; c = c->next) { 126 @@ -1753,6 +1785,17 @@ spawn(const Arg *arg) 127 if (fork() == 0) { 128 if (dpy) 129 close(ConnectionNumber(dpy)); 130 + if (arg->v == statuscmd) { 131 + for (int i = 0; i < LENGTH(statuscmds); i++) { 132 + if (statuscmdn == statuscmds[i].id) { 133 + statuscmd[2] = statuscmds[i].cmd; 134 + setenv("BUTTON", lastbutton, 1); 135 + break; 136 + } 137 + } 138 + if (!statuscmd[2]) 139 + exit(EXIT_SUCCESS); 140 + } 141 setsid(); 142 execvp(((char **)arg->v)[0], (char **)arg->v); 143 fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); 144 @@ -2098,8 +2141,23 @@ updatesizehints(Client *c) 145 void 146 updatestatus(void) 147 { 148 - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 149 + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { 150 strcpy(stext, "dwm-"VERSION); 151 + statusw = TEXTW(stext) - lrpad + 2; 152 + } else { 153 + char *text, *s, ch; 154 + statusw = 0; 155 + for (text = s = stext; *s; s++) { 156 + if ((unsigned char)(*s) < ' ') { 157 + ch = *s; 158 + *s = '\0'; 159 + statusw += TEXTW(text) - lrpad; 160 + *s = ch; 161 + text = s + 1; 162 + } 163 + } 164 + statusw += TEXTW(text) - lrpad + 2; 165 + } 166 drawbar(selmon); 167 } 168 169 -- 170 2.31.0 171