dwm-statuscmd-nosignal-20210402-67d76bd.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
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