dwm-statuscmd-20241009-8933ebc.diff - sites - public wiki contents of suckless.… | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dwm-statuscmd-20241009-8933ebc.diff (6623B) | |
--- | |
1 From ca2a2e6386a746ebfc3480787e5d99da11e7abee Mon Sep 17 00:00:00 2001 | |
2 From: Justinas Grigas <[email protected]> | |
3 Date: Wed, 9 Oct 2024 01:00:20 +0100 | |
4 Subject: [PATCH] [dwm][statuscmd] better click regions | |
5 | |
6 The main improvement of this patch over the previous version 20210405 is… | |
7 the click region now ends on a matching signal raw byte. | |
8 | |
9 The matching byte is optional, and without it dwm will behave as before. | |
10 | |
11 To take advantage of this feature, scripts need to be modified to print … | |
12 byte at the end as well. | |
13 | |
14 In addition, this patch cleanly applies onto master branch. | |
15 --- | |
16 config.def.h | 6 ++- | |
17 dwm.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++--- | |
18 2 files changed, 104 insertions(+), 6 deletions(-) | |
19 | |
20 diff --git a/config.def.h b/config.def.h | |
21 index 9efa774..d008275 100644 | |
22 --- a/config.def.h | |
23 +++ b/config.def.h | |
24 @@ -55,6 +55,8 @@ static const Layout layouts[] = { | |
25 /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | |
26 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL }… | |
27 | |
28 +#define STATUSBAR "dwmblocks" | |
29 + | |
30 /* commands */ | |
31 static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in… | |
32 static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", d… | |
33 @@ -104,7 +106,9 @@ static const Button buttons[] = { | |
34 { ClkLtSymbol, 0, Button1, setlayo… | |
35 { ClkLtSymbol, 0, Button3, setlayo… | |
36 { ClkWinTitle, 0, Button2, zoom, … | |
37 - { ClkStatusText, 0, Button2, spawn, … | |
38 + { ClkStatusText, 0, Button1, sigstat… | |
39 + { ClkStatusText, 0, Button2, sigstat… | |
40 + { ClkStatusText, 0, Button3, sigstat… | |
41 { ClkClientWin, MODKEY, Button1, movemou… | |
42 { ClkClientWin, MODKEY, Button2, togglef… | |
43 { ClkClientWin, MODKEY, Button3, resizem… | |
44 diff --git a/dwm.c b/dwm.c | |
45 index 1443802..94ee0c7 100644 | |
46 --- a/dwm.c | |
47 +++ b/dwm.c | |
48 @@ -171,6 +171,7 @@ static void focusstack(const Arg *arg); | |
49 static Atom getatomprop(Client *c, Atom prop); | |
50 static int getrootptr(int *x, int *y); | |
51 static long getstate(Window w); | |
52 +static pid_t getstatusbarpid(); | |
53 static int gettextprop(Window w, Atom atom, char *text, unsigned int si… | |
54 static void grabbuttons(Client *c, int focused); | |
55 static void grabkeys(void); | |
56 @@ -204,6 +205,7 @@ static void setmfact(const Arg *arg); | |
57 static void setup(void); | |
58 static void seturgent(Client *c, int urg); | |
59 static void showhide(Client *c); | |
60 +static void sigstatusbar(const Arg *arg); | |
61 static void spawn(const Arg *arg); | |
62 static void tag(const Arg *arg); | |
63 static void tagmon(const Arg *arg); | |
64 @@ -236,6 +238,9 @@ static void zoom(const Arg *arg); | |
65 /* variables */ | |
66 static const char broken[] = "broken"; | |
67 static char stext[256]; | |
68 +static int statusw; | |
69 +static int statussig; | |
70 +static pid_t statuspid = -1; | |
71 static int screen; | |
72 static int sw, sh; /* X display screen geometry width, height… | |
73 static int bh; /* bar height */ | |
74 @@ -422,6 +427,7 @@ buttonpress(XEvent *e) | |
75 Client *c; | |
76 Monitor *m; | |
77 XButtonPressedEvent *ev = &e->xbutton; | |
78 + char *text, *s, ch; | |
79 | |
80 click = ClkRootWin; | |
81 /* focus monitor if necessary */ | |
82 @@ -440,9 +446,27 @@ buttonpress(XEvent *e) | |
83 arg.ui = 1 << i; | |
84 } else if (ev->x < x + TEXTW(selmon->ltsymbol)) | |
85 click = ClkLtSymbol; | |
86 - else if (ev->x > selmon->ww - (int)TEXTW(stext)) | |
87 + else if (ev->x > selmon->ww - statusw) { | |
88 + x = selmon->ww - statusw; | |
89 click = ClkStatusText; | |
90 - else | |
91 + statussig = 0; | |
92 + for (text = s = stext; *s && x <= ev->x; s++) { | |
93 + if ((unsigned char)(*s) < ' ') { | |
94 + ch = *s; | |
95 + *s = '\0'; | |
96 + x += TEXTW(text) - lrpad; | |
97 + *s = ch; | |
98 + text = s + 1; | |
99 + if (x >= ev->x) | |
100 + break; | |
101 + /* reset on matching signal raw… | |
102 + if (ch == statussig) | |
103 + statussig = 0; | |
104 + else | |
105 + statussig = ch; | |
106 + } | |
107 + } | |
108 + } else | |
109 click = ClkWinTitle; | |
110 } else if ((c = wintoclient(ev->window))) { | |
111 focus(c); | |
112 @@ -708,9 +732,24 @@ drawbar(Monitor *m) | |
113 | |
114 /* draw status first so it can be overdrawn by tags later */ | |
115 if (m == selmon) { /* status is only drawn on selected monitor … | |
116 + char *text, *s, ch; | |
117 drw_setscheme(drw, scheme[SchemeNorm]); | |
118 - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | |
119 - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); | |
120 + | |
121 + x = 0; | |
122 + for (text = s = stext; *s; s++) { | |
123 + if ((unsigned char)(*s) < ' ') { | |
124 + ch = *s; | |
125 + *s = '\0'; | |
126 + tw = TEXTW(text) - lrpad; | |
127 + drw_text(drw, m->ww - statusw + x, 0, t… | |
128 + x += tw; | |
129 + *s = ch; | |
130 + text = s + 1; | |
131 + } | |
132 + } | |
133 + tw = TEXTW(text) - lrpad + 2; | |
134 + drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, … | |
135 + tw = statusw; | |
136 } | |
137 | |
138 for (c = m->clients; c; c = c->next) { | |
139 @@ -876,6 +915,30 @@ getatomprop(Client *c, Atom prop) | |
140 return atom; | |
141 } | |
142 | |
143 +pid_t | |
144 +getstatusbarpid() | |
145 +{ | |
146 + char buf[32], *str = buf, *c; | |
147 + FILE *fp; | |
148 + | |
149 + if (statuspid > 0) { | |
150 + snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspi… | |
151 + if ((fp = fopen(buf, "r"))) { | |
152 + fgets(buf, sizeof(buf), fp); | |
153 + while ((c = strchr(str, '/'))) | |
154 + str = c + 1; | |
155 + fclose(fp); | |
156 + if (!strcmp(str, STATUSBAR)) | |
157 + return statuspid; | |
158 + } | |
159 + } | |
160 + if (!(fp = popen("pidof -s "STATUSBAR, "r"))) | |
161 + return -1; | |
162 + fgets(buf, sizeof(buf), fp); | |
163 + pclose(fp); | |
164 + return strtol(buf, NULL, 10); | |
165 +} | |
166 + | |
167 int | |
168 getrootptr(int *x, int *y) | |
169 { | |
170 @@ -1643,6 +1706,20 @@ showhide(Client *c) | |
171 } | |
172 } | |
173 | |
174 +void | |
175 +sigstatusbar(const Arg *arg) | |
176 +{ | |
177 + union sigval sv; | |
178 + | |
179 + if (!statussig) | |
180 + return; | |
181 + sv.sival_int = arg->i; | |
182 + if ((statuspid = getstatusbarpid()) <= 0) | |
183 + return; | |
184 + | |
185 + sigqueue(statuspid, SIGRTMIN+statussig, sv); | |
186 +} | |
187 + | |
188 void | |
189 spawn(const Arg *arg) | |
190 { | |
191 @@ -2004,8 +2081,25 @@ updatesizehints(Client *c) | |
192 void | |
193 updatestatus(void) | |
194 { | |
195 - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) | |
196 + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { | |
197 strcpy(stext, "dwm-"VERSION); | |
198 + statusw = TEXTW(stext) - lrpad + 2; | |
199 + } else { | |
200 + char *text, *s, ch; | |
201 + | |
202 + statusw = 0; | |
203 + for (text = s = stext; *s; s++) { | |
204 + if ((unsigned char)(*s) < ' ') { | |
205 + ch = *s; | |
206 + *s = '\0'; | |
207 + statusw += TEXTW(text) - lrpad; | |
208 + *s = ch; | |
209 + text = s + 1; | |
210 + } | |
211 + } | |
212 + statusw += TEXTW(text) - lrpad + 2; | |
213 + | |
214 + } | |
215 drawbar(selmon); | |
216 } | |
217 | |
218 -- | |
219 2.46.2 | |
220 |