dwm-swallow-20200707-8d1e703.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dwm-swallow-20200707-8d1e703.diff (8904B) | |
--- | |
1 From 8d1e7039c239619bee159e07e32b8d49837bf445 Mon Sep 17 00:00:00 2001 | |
2 From: jmanabc <[email protected]> | |
3 Date: Tue, 7 Jul 2020 21:24:56 -0400 | |
4 Subject: [PATCH] Fixed swallowing by removing scanner variable from dwm.… | |
5 corrected capitalization in config.def.h | |
6 | |
7 --- | |
8 config.def.h | 9 ++- | |
9 config.mk | 2 +- | |
10 dwm.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++-- | |
11 3 files changed, 198 insertions(+), 9 deletions(-) | |
12 | |
13 diff --git a/config.def.h b/config.def.h | |
14 index 1c0b587..fe51476 100644 | |
15 --- a/config.def.h | |
16 +++ b/config.def.h | |
17 @@ -3,6 +3,7 @@ | |
18 /* appearance */ | |
19 static const unsigned int borderpx = 1; /* border pixel of wind… | |
20 static const unsigned int snap = 32; /* snap pixel */ | |
21 +static const int swallowfloating = 0; /* 1 means swallow floa… | |
22 static const int showbar = 1; /* 0 means no bar */ | |
23 static const int topbar = 1; /* 0 means bottom bar */ | |
24 static const char *fonts[] = { "monospace:size=10" }; | |
25 @@ -26,9 +27,11 @@ static const Rule rules[] = { | |
26 * WM_CLASS(STRING) = instance, class | |
27 * WM_NAME(STRING) = title | |
28 */ | |
29 - /* class instance title tags mask isfloating … | |
30 - { "Gimp", NULL, NULL, 0, 1, … | |
31 - { "Firefox", NULL, NULL, 1 << 8, 0, … | |
32 + /* class instance title tags mask isfloating i… | |
33 + { "Gimp", NULL, NULL, 0, 1, 0… | |
34 + { "Firefox", NULL, NULL, 1 << 8, 0, 0… | |
35 + { "St", NULL, NULL, 0, 0, 1… | |
36 + { NULL, NULL, "Event Tester", 0, 0, 0… | |
37 }; | |
38 | |
39 /* layout(s) */ | |
40 diff --git a/config.mk b/config.mk | |
41 index 7084c33..b77641d 100644 | |
42 --- a/config.mk | |
43 +++ b/config.mk | |
44 @@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2 | |
45 | |
46 # includes and libs | |
47 INCS = -I${X11INC} -I${FREETYPEINC} | |
48 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | |
49 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxc… | |
50 | |
51 # flags | |
52 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -D… | |
53 diff --git a/dwm.c b/dwm.c | |
54 index 9fd0286..c58de28 100644 | |
55 --- a/dwm.c | |
56 +++ b/dwm.c | |
57 @@ -40,6 +40,8 @@ | |
58 #include <X11/extensions/Xinerama.h> | |
59 #endif /* XINERAMA */ | |
60 #include <X11/Xft/Xft.h> | |
61 +#include <X11/Xlib-xcb.h> | |
62 +#include <xcb/res.h> | |
63 | |
64 #include "drw.h" | |
65 #include "util.h" | |
66 @@ -92,9 +94,11 @@ struct Client { | |
67 int basew, baseh, incw, inch, maxw, maxh, minw, minh; | |
68 int bw, oldbw; | |
69 unsigned int tags; | |
70 - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull… | |
71 + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull… | |
72 + pid_t pid; | |
73 Client *next; | |
74 Client *snext; | |
75 + Client *swallowing; | |
76 Monitor *mon; | |
77 Window win; | |
78 }; | |
79 @@ -138,6 +142,8 @@ typedef struct { | |
80 const char *title; | |
81 unsigned int tags; | |
82 int isfloating; | |
83 + int isterminal; | |
84 + int noswallow; | |
85 int monitor; | |
86 } Rule; | |
87 | |
88 @@ -235,6 +241,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *e… | |
89 static int xerrorstart(Display *dpy, XErrorEvent *ee); | |
90 static void zoom(const Arg *arg); | |
91 | |
92 +static pid_t getparentprocess(pid_t p); | |
93 +static int isdescprocess(pid_t p, pid_t c); | |
94 +static Client *swallowingclient(Window w); | |
95 +static Client *termforwin(const Client *c); | |
96 +static pid_t winpid(Window w); | |
97 + | |
98 /* variables */ | |
99 static const char broken[] = "broken"; | |
100 static char stext[256]; | |
101 @@ -269,6 +281,8 @@ static Drw *drw; | |
102 static Monitor *mons, *selmon; | |
103 static Window root, wmcheckwin; | |
104 | |
105 +static xcb_connection_t *xcon; | |
106 + | |
107 /* configuration, allows nested code to access above variables */ | |
108 #include "config.h" | |
109 | |
110 @@ -298,6 +312,8 @@ applyrules(Client *c) | |
111 && (!r->class || strstr(class, r->class)) | |
112 && (!r->instance || strstr(instance, r->instance))) | |
113 { | |
114 + c->isterminal = r->isterminal; | |
115 + c->noswallow = r->noswallow; | |
116 c->isfloating = r->isfloating; | |
117 c->tags |= r->tags; | |
118 for (m = mons; m && m->num != r->monitor; m = m… | |
119 @@ -414,6 +430,53 @@ attachstack(Client *c) | |
120 c->mon->stack = c; | |
121 } | |
122 | |
123 +void | |
124 +swallow(Client *p, Client *c) | |
125 +{ | |
126 + | |
127 + if (c->noswallow || c->isterminal) | |
128 + return; | |
129 + if (c->noswallow && !swallowfloating && c->isfloating) | |
130 + return; | |
131 + | |
132 + detach(c); | |
133 + detachstack(c); | |
134 + | |
135 + setclientstate(c, WithdrawnState); | |
136 + XUnmapWindow(dpy, p->win); | |
137 + | |
138 + p->swallowing = c; | |
139 + c->mon = p->mon; | |
140 + | |
141 + Window w = p->win; | |
142 + p->win = c->win; | |
143 + c->win = w; | |
144 + updatetitle(p); | |
145 + XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); | |
146 + arrange(p->mon); | |
147 + configure(p); | |
148 + updateclientlist(); | |
149 +} | |
150 + | |
151 +void | |
152 +unswallow(Client *c) | |
153 +{ | |
154 + c->win = c->swallowing->win; | |
155 + | |
156 + free(c->swallowing); | |
157 + c->swallowing = NULL; | |
158 + | |
159 + /* unfullscreen the client */ | |
160 + setfullscreen(c, 0); | |
161 + updatetitle(c); | |
162 + arrange(c->mon); | |
163 + XMapWindow(dpy, c->win); | |
164 + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | |
165 + setclientstate(c, NormalState); | |
166 + focus(NULL); | |
167 + arrange(c->mon); | |
168 +} | |
169 + | |
170 void | |
171 buttonpress(XEvent *e) | |
172 { | |
173 @@ -653,6 +716,9 @@ destroynotify(XEvent *e) | |
174 | |
175 if ((c = wintoclient(ev->window))) | |
176 unmanage(c, 1); | |
177 + | |
178 + else if ((c = swallowingclient(ev->window))) | |
179 + unmanage(c->swallowing, 1); | |
180 } | |
181 | |
182 void | |
183 @@ -1018,12 +1084,13 @@ killclient(const Arg *arg) | |
184 void | |
185 manage(Window w, XWindowAttributes *wa) | |
186 { | |
187 - Client *c, *t = NULL; | |
188 + Client *c, *t = NULL, *term = NULL; | |
189 Window trans = None; | |
190 XWindowChanges wc; | |
191 | |
192 c = ecalloc(1, sizeof(Client)); | |
193 c->win = w; | |
194 + c->pid = winpid(w); | |
195 /* geometry */ | |
196 c->x = c->oldx = wa->x; | |
197 c->y = c->oldy = wa->y; | |
198 @@ -1038,6 +1105,7 @@ manage(Window w, XWindowAttributes *wa) | |
199 } else { | |
200 c->mon = selmon; | |
201 applyrules(c); | |
202 + term = termforwin(c); | |
203 } | |
204 | |
205 if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) | |
206 @@ -1074,6 +1142,8 @@ manage(Window w, XWindowAttributes *wa) | |
207 c->mon->sel = c; | |
208 arrange(c->mon); | |
209 XMapWindow(dpy, c->win); | |
210 + if (term) | |
211 + swallow(term, c); | |
212 focus(NULL); | |
213 } | |
214 | |
215 @@ -1768,6 +1838,20 @@ unmanage(Client *c, int destroyed) | |
216 Monitor *m = c->mon; | |
217 XWindowChanges wc; | |
218 | |
219 + if (c->swallowing) { | |
220 + unswallow(c); | |
221 + return; | |
222 + } | |
223 + | |
224 + Client *s = swallowingclient(c->win); | |
225 + if (s) { | |
226 + free(s->swallowing); | |
227 + s->swallowing = NULL; | |
228 + arrange(m); | |
229 + focus(NULL); | |
230 + return; | |
231 + } | |
232 + | |
233 detach(c); | |
234 detachstack(c); | |
235 if (!destroyed) { | |
236 @@ -1782,9 +1866,12 @@ unmanage(Client *c, int destroyed) | |
237 XUngrabServer(dpy); | |
238 } | |
239 free(c); | |
240 - focus(NULL); | |
241 - updateclientlist(); | |
242 - arrange(m); | |
243 + | |
244 + if (!s) { | |
245 + arrange(m); | |
246 + focus(NULL); | |
247 + updateclientlist(); | |
248 + } | |
249 } | |
250 | |
251 void | |
252 @@ -2047,6 +2134,103 @@ view(const Arg *arg) | |
253 arrange(selmon); | |
254 } | |
255 | |
256 +pid_t | |
257 +winpid(Window w) | |
258 +{ | |
259 + pid_t result = 0; | |
260 + | |
261 + xcb_res_client_id_spec_t spec = {0}; | |
262 + spec.client = w; | |
263 + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; | |
264 + | |
265 + xcb_generic_error_t *e = NULL; | |
266 + xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(… | |
267 + xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_… | |
268 + | |
269 + if (!r) | |
270 + return (pid_t)0; | |
271 + | |
272 + xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids… | |
273 + for (; i.rem; xcb_res_client_id_value_next(&i)) { | |
274 + spec = i.data->spec; | |
275 + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID… | |
276 + uint32_t *t = xcb_res_client_id_value_value(i.d… | |
277 + result = *t; | |
278 + break; | |
279 + } | |
280 + } | |
281 + | |
282 + free(r); | |
283 + | |
284 + if (result == (pid_t)-1) | |
285 + result = 0; | |
286 + return result; | |
287 +} | |
288 + | |
289 +pid_t | |
290 +getparentprocess(pid_t p) | |
291 +{ | |
292 + unsigned int v = 0; | |
293 + | |
294 +#ifdef __linux__ | |
295 + FILE *f; | |
296 + char buf[256]; | |
297 + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); | |
298 + | |
299 + if (!(f = fopen(buf, "r"))) | |
300 + return 0; | |
301 + | |
302 + fscanf(f, "%*u %*s %*c %u", &v); | |
303 + fclose(f); | |
304 +#endif /* __linux__*/ | |
305 + | |
306 + return (pid_t)v; | |
307 +} | |
308 + | |
309 +int | |
310 +isdescprocess(pid_t p, pid_t c) | |
311 +{ | |
312 + while (p != c && c != 0) | |
313 + c = getparentprocess(c); | |
314 + | |
315 + return (int)c; | |
316 +} | |
317 + | |
318 +Client * | |
319 +termforwin(const Client *w) | |
320 +{ | |
321 + Client *c; | |
322 + Monitor *m; | |
323 + | |
324 + if (!w->pid || w->isterminal) | |
325 + return NULL; | |
326 + | |
327 + for (m = mons; m; m = m->next) { | |
328 + for (c = m->clients; c; c = c->next) { | |
329 + if (c->isterminal && !c->swallowing && c->pid &… | |
330 + return c; | |
331 + } | |
332 + } | |
333 + | |
334 + return NULL; | |
335 +} | |
336 + | |
337 +Client * | |
338 +swallowingclient(Window w) | |
339 +{ | |
340 + Client *c; | |
341 + Monitor *m; | |
342 + | |
343 + for (m = mons; m; m = m->next) { | |
344 + for (c = m->clients; c; c = c->next) { | |
345 + if (c->swallowing && c->swallowing->win == w) | |
346 + return c; | |
347 + } | |
348 + } | |
349 + | |
350 + return NULL; | |
351 +} | |
352 + | |
353 Client * | |
354 wintoclient(Window w) | |
355 { | |
356 @@ -2138,6 +2322,8 @@ main(int argc, char *argv[]) | |
357 fputs("warning: no locale support\n", stderr); | |
358 if (!(dpy = XOpenDisplay(NULL))) | |
359 die("dwm: cannot open display"); | |
360 + if (!(xcon = XGetXCBConnection(dpy))) | |
361 + die("dwm: cannot get xcb connection\n"); | |
362 checkotherwm(); | |
363 setup(); | |
364 #ifdef __OpenBSD__ | |
365 -- | |
366 2.27.0 | |
367 |