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