Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-anybar-20200810-bb2e722.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-anybar-20200810-bb2e722.diff (10352B)
---
1 From 782f63d8f858b1c14df38aaf623438d7ea2f75e1 Mon Sep 17 00:00:00 2001
2 From: mihirlad55 <[email protected]>
3 Date: Mon, 10 Aug 2020 01:39:35 +0000
4 Subject: [PATCH] Add support for managing external status bars
5
6 This patch allows dwm to manage other status bars such as
7 polybar/lemonbar without them needing to set override-redirect. For
8 all intents and purposes, DWM treats this bar as if it were its own
9 and as a result helps the status bar and DWM live in harmony.
10
11 This has a few advantages
12 * The bar does not block fullscreen windows
13 * DWM makes room for the status bar, so windows do not overlap the bar
14 * The bar can be hidden/killed and DWM will not keep an unsightly gap
15 where the bar was
16 * DWM receives EnterNotify events when your cursor enters the bar
17
18 To use another status bar, set usealtbar to 1 in your config.h and set
19 altbarclass to the class name (can be found using xprop) to the class
20 name of your status bar. Also make sure that if your status bar will
21 be displayed on top, topbar is set to 1 in your config, and if it will
22 be displayed on bottom, topbar is set to 0. This patch does not
23 support bars that are not docked at the top or at the bottom of your
24 monitor.
25
26 The patch is developed at https://github.com/mihirlad55/dwm-anybar
27 ---
28 config.def.h | 3 ++
29 dwm.c | 114 ++++++++++++++++++++++++++++++++++++++++++++-------
30 2 files changed, 103 insertions(+), 14 deletions(-)
31
32 diff --git a/config.def.h b/config.def.h
33 index 1c0b587..d0d60aa 100644
34 --- a/config.def.h
35 +++ b/config.def.h
36 @@ -5,6 +5,9 @@ static const unsigned int borderpx = 1; /* borde…
37 static const unsigned int snap = 32; /* snap pixel */
38 static const int showbar = 1; /* 0 means no bar */
39 static const int topbar = 1; /* 0 means bottom bar */
40 +static const int usealtbar = 1; /* 1 means use non-dwm …
41 +static const char *altbarclass = "Polybar"; /* Alternate bar class…
42 +static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar …
43 static const char *fonts[] = { "monospace:size=10" };
44 static const char dmenufont[] = "monospace:size=10";
45 static const char col_gray1[] = "#222222";
46 diff --git a/dwm.c b/dwm.c
47 index 9fd0286..f149ab4 100644
48 --- a/dwm.c
49 +++ b/dwm.c
50 @@ -47,8 +47,8 @@
51 /* macros */
52 #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
53 #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (Shif…
54 -#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - …
55 - * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - …
56 +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - …
57 + * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - …
58 #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->selt…
59 #define LENGTH(X) (sizeof X / sizeof X[0])
60 #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
61 @@ -116,7 +116,7 @@ struct Monitor {
62 float mfact;
63 int nmaster;
64 int num;
65 - int by; /* bar geometry */
66 + int by, bh; /* bar geometry */
67 int mx, my, mw, mh; /* screen size */
68 int wx, wy, ww, wh; /* window area */
69 unsigned int seltags;
70 @@ -179,6 +179,7 @@ static void incnmaster(const Arg *arg);
71 static void keypress(XEvent *e);
72 static void killclient(const Arg *arg);
73 static void manage(Window w, XWindowAttributes *wa);
74 +static void managealtbar(Window win, XWindowAttributes *wa);
75 static void mappingnotify(XEvent *e);
76 static void maprequest(XEvent *e);
77 static void monocle(Monitor *m);
78 @@ -207,6 +208,7 @@ static void seturgent(Client *c, int urg);
79 static void showhide(Client *c);
80 static void sigchld(int unused);
81 static void spawn(const Arg *arg);
82 +static void spawnbar();
83 static void tag(const Arg *arg);
84 static void tagmon(const Arg *arg);
85 static void tile(Monitor *);
86 @@ -216,6 +218,7 @@ static void toggletag(const Arg *arg);
87 static void toggleview(const Arg *arg);
88 static void unfocus(Client *c, int setfocus);
89 static void unmanage(Client *c, int destroyed);
90 +static void unmanagealtbar(Window w);
91 static void unmapnotify(XEvent *e);
92 static void updatebarpos(Monitor *m);
93 static void updatebars(void);
94 @@ -230,6 +233,7 @@ static void updatewmhints(Client *c);
95 static void view(const Arg *arg);
96 static Client *wintoclient(Window w);
97 static Monitor *wintomon(Window w);
98 +static int wmclasscontains(Window win, const char *class, const char *n…
99 static int xerror(Display *dpy, XErrorEvent *ee);
100 static int xerrordummy(Display *dpy, XErrorEvent *ee);
101 static int xerrorstart(Display *dpy, XErrorEvent *ee);
102 @@ -505,8 +509,10 @@ cleanupmon(Monitor *mon)
103 for (m = mons; m && m->next != mon; m = m->next);
104 m->next = mon->next;
105 }
106 - XUnmapWindow(dpy, mon->barwin);
107 - XDestroyWindow(dpy, mon->barwin);
108 + if (!usealtbar) {
109 + XUnmapWindow(dpy, mon->barwin);
110 + XDestroyWindow(dpy, mon->barwin);
111 + }
112 free(mon);
113 }
114
115 @@ -568,7 +574,7 @@ configurenotify(XEvent *e)
116 for (c = m->clients; c; c = c->next)
117 if (c->isfullscreen)
118 resizeclient(c, m->mx, …
119 - XMoveResizeWindow(dpy, m->barwin, m->wx…
120 + XMoveResizeWindow(dpy, m->barwin, m->wx…
121 }
122 focus(NULL);
123 arrange(NULL);
124 @@ -639,6 +645,7 @@ createmon(void)
125 m->nmaster = nmaster;
126 m->showbar = showbar;
127 m->topbar = topbar;
128 + m->bh = bh;
129 m->lt[0] = &layouts[0];
130 m->lt[1] = &layouts[1 % LENGTH(layouts)];
131 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
132 @@ -649,10 +656,13 @@ void
133 destroynotify(XEvent *e)
134 {
135 Client *c;
136 + Monitor *m;
137 XDestroyWindowEvent *ev = &e->xdestroywindow;
138
139 if ((c = wintoclient(ev->window)))
140 unmanage(c, 1);
141 + else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
142 + unmanagealtbar(ev->window);
143 }
144
145 void
146 @@ -696,6 +706,9 @@ dirtomon(int dir)
147 void
148 drawbar(Monitor *m)
149 {
150 + if (usealtbar)
151 + return;
152 +
153 int x, w, tw = 0;
154 int boxs = drw->fonts->h / 9;
155 int boxw = drw->fonts->h / 6 + 2;
156 @@ -1077,6 +1090,25 @@ manage(Window w, XWindowAttributes *wa)
157 focus(NULL);
158 }
159
160 +void
161 +managealtbar(Window win, XWindowAttributes *wa)
162 +{
163 + Monitor *m;
164 + if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
165 + return;
166 +
167 + m->barwin = win;
168 + m->by = wa->y;
169 + bh = m->bh = wa->height;
170 + updatebarpos(m);
171 + arrange(m);
172 + XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|Property…
173 + XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height…
174 + XMapWindow(dpy, win);
175 + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 3…
176 + (unsigned char *) &win, 1);
177 +}
178 +
179 void
180 mappingnotify(XEvent *e)
181 {
182 @@ -1097,7 +1129,9 @@ maprequest(XEvent *e)
183 return;
184 if (wa.override_redirect)
185 return;
186 - if (!wintoclient(ev->window))
187 + if (wmclasscontains(ev->window, altbarclass, ""))
188 + managealtbar(ev->window, &wa);
189 + else if (!wintoclient(ev->window))
190 manage(ev->window, &wa);
191 }
192
193 @@ -1393,7 +1427,9 @@ scan(void)
194 if (!XGetWindowAttributes(dpy, wins[i], &wa)
195 || wa.override_redirect || XGetTransientForHint…
196 continue;
197 - if (wa.map_state == IsViewable || getstate(wins…
198 + if (wmclasscontains(wins[i], altbarclass, ""))
199 + managealtbar(wins[i], &wa);
200 + else if (wa.map_state == IsViewable || getstate…
201 manage(wins[i], &wa);
202 }
203 for (i = 0; i < num; i++) { /* now the transients */
204 @@ -1546,7 +1582,7 @@ setup(void)
205 if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
206 die("no fonts could be loaded.");
207 lrpad = drw->fonts->h;
208 - bh = drw->fonts->h + 2;
209 + bh = usealtbar ? 0 : drw->fonts->h + 2;
210 updategeom();
211 /* init atoms */
212 utf8string = XInternAtom(dpy, "UTF8_STRING", False);
213 @@ -1595,6 +1631,7 @@ setup(void)
214 XSelectInput(dpy, root, wa.event_mask);
215 grabkeys();
216 focus(NULL);
217 + spawnbar();
218 }
219
220
221 @@ -1653,6 +1690,13 @@ spawn(const Arg *arg)
222 }
223 }
224
225 +void
226 +spawnbar()
227 +{
228 + if (*altbarcmd)
229 + system(altbarcmd);
230 +}
231 +
232 void
233 tag(const Arg *arg)
234 {
235 @@ -1704,7 +1748,7 @@ togglebar(const Arg *arg)
236 {
237 selmon->showbar = !selmon->showbar;
238 updatebarpos(selmon);
239 - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, …
240 + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, …
241 arrange(selmon);
242 }
243
244 @@ -1787,10 +1831,26 @@ unmanage(Client *c, int destroyed)
245 arrange(m);
246 }
247
248 +void
249 +unmanagealtbar(Window w)
250 +{
251 + Monitor *m = wintomon(w);
252 +
253 + if (!m)
254 + return;
255 +
256 + m->barwin = 0;
257 + m->by = 0;
258 + m->bh = 0;
259 + updatebarpos(m);
260 + arrange(m);
261 +}
262 +
263 void
264 unmapnotify(XEvent *e)
265 {
266 Client *c;
267 + Monitor *m;
268 XUnmapEvent *ev = &e->xunmap;
269
270 if ((c = wintoclient(ev->window))) {
271 @@ -1798,12 +1858,16 @@ unmapnotify(XEvent *e)
272 setclientstate(c, WithdrawnState);
273 else
274 unmanage(c, 0);
275 - }
276 + } else if ((m = wintomon(ev->window)) && m->barwin == ev->windo…
277 + unmanagealtbar(ev->window);
278 }
279
280 void
281 updatebars(void)
282 {
283 + if (usealtbar)
284 + return;
285 +
286 Monitor *m;
287 XSetWindowAttributes wa = {
288 .override_redirect = True,
289 @@ -1829,11 +1893,11 @@ updatebarpos(Monitor *m)
290 m->wy = m->my;
291 m->wh = m->mh;
292 if (m->showbar) {
293 - m->wh -= bh;
294 + m->wh -= m->bh;
295 m->by = m->topbar ? m->wy : m->wy + m->wh;
296 - m->wy = m->topbar ? m->wy + bh : m->wy;
297 + m->wy = m->topbar ? m->wy + m->bh : m->wy;
298 } else
299 - m->by = -bh;
300 + m->by = -m->bh;
301 }
302
303 void
304 @@ -2077,6 +2141,28 @@ wintomon(Window w)
305 return selmon;
306 }
307
308 +int
309 +wmclasscontains(Window win, const char *class, const char *name)
310 +{
311 + XClassHint ch = { NULL, NULL };
312 + int res = 1;
313 +
314 + if (XGetClassHint(dpy, win, &ch)) {
315 + if (ch.res_name && strstr(ch.res_name, name) == NULL)
316 + res = 0;
317 + if (ch.res_class && strstr(ch.res_class, class) == NULL)
318 + res = 0;
319 + } else
320 + res = 0;
321 +
322 + if (ch.res_class)
323 + XFree(ch.res_class);
324 + if (ch.res_name)
325 + XFree(ch.res_name);
326 +
327 + return res;
328 +}
329 +
330 /* There's no way to check accesses to destroyed windows, thus those ca…
331 * ignored (especially on UnmapNotify's). Other types of errors call Xl…
332 * default error handler, which may call exit. */
333 --
334 2.28.0
335
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.