Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-swallow-20160717-56a31dc.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-swallow-20160717-56a31dc.diff (9208B)
---
1 diff --git a/config.def.h b/config.def.h
2 index fd77a07..69976b3 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -26,9 +26,10 @@ static const Rule rules[] = {
6 * WM_CLASS(STRING) = instance, class
7 * WM_NAME(STRING) = title
8 */
9 - /* class instance title tags mask isfloating …
10 - { "Gimp", NULL, NULL, 0, 1, …
11 - { "Firefox", NULL, NULL, 1 << 8, 0, …
12 + /* class instance title tags mask isfloating …
13 + { "Gimp", NULL, NULL, 0, 1, …
14 + { "Firefox", NULL, NULL, 1 << 8, 0, …
15 + { "st", NULL, NULL, 0, 0, …
16 };
17
18 /* layout(s) */
19 diff --git a/config.mk b/config.mk
20 index 80dc936..5ed14e3 100644
21 --- a/config.mk
22 +++ b/config.mk
23 @@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
24
25 # includes and libs
26 INCS = -I${X11INC} -I${FREETYPEINC}
27 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
28 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxc…
29
30 # flags
31 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSIO…
32 diff --git a/dwm.c b/dwm.c
33 index b2bc9bd..528df2f 100644
34 --- a/dwm.c
35 +++ b/dwm.c
36 @@ -40,6 +40,8 @@
37 #include <X11/extensions/Xinerama.h>
38 #endif /* XINERAMA */
39 #include <X11/Xft/Xft.h>
40 +#include <X11/Xlib-xcb.h>
41 +#include <xcb/res.h>
42
43 #include "drw.h"
44 #include "util.h"
45 @@ -93,9 +95,11 @@ struct Client {
46 int basew, baseh, incw, inch, maxw, maxh, minw, minh;
47 int bw, oldbw;
48 unsigned int tags;
49 - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull…
50 + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull…
51 + pid_t pid;
52 Client *next;
53 Client *snext;
54 + Client *swallowing;
55 Monitor *mon;
56 Window win;
57 };
58 @@ -139,6 +143,8 @@ typedef struct {
59 const char *title;
60 unsigned int tags;
61 int isfloating;
62 + int isterminal;
63 + int noswallow;
64 int monitor;
65 } Rule;
66
67 @@ -171,12 +177,14 @@ static void focus(Client *c);
68 static void focusin(XEvent *e);
69 static void focusmon(const Arg *arg);
70 static void focusstack(const Arg *arg);
71 +static pid_t getparentprocess(pid_t p);
72 static int getrootptr(int *x, int *y);
73 static long getstate(Window w);
74 static int gettextprop(Window w, Atom atom, char *text, unsigned int si…
75 static void grabbuttons(Client *c, int focused);
76 static void grabkeys(void);
77 static void incnmaster(const Arg *arg);
78 +static int isdescprocess(pid_t p, pid_t c);
79 static void keypress(XEvent *e);
80 static void killclient(const Arg *arg);
81 static void manage(Window w, XWindowAttributes *wa);
82 @@ -207,8 +215,10 @@ static void setup(void);
83 static void showhide(Client *c);
84 static void sigchld(int unused);
85 static void spawn(const Arg *arg);
86 +static Client *swallowingclient(Window w);
87 static void tag(const Arg *arg);
88 static void tagmon(const Arg *arg);
89 +static Client *termforwin(const Client *c);
90 static void tile(Monitor *);
91 static void togglebar(const Arg *arg);
92 static void togglefloating(const Arg *arg);
93 @@ -228,6 +238,7 @@ static void updatewindowtype(Client *c);
94 static void updatetitle(Client *c);
95 static void updatewmhints(Client *c);
96 static void view(const Arg *arg);
97 +static pid_t winpid(Window w);
98 static Client *wintoclient(Window w);
99 static Monitor *wintomon(Window w);
100 static int xerror(Display *dpy, XErrorEvent *ee);
101 @@ -269,6 +280,8 @@ static Drw *drw;
102 static Monitor *mons, *selmon;
103 static Window root;
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 +311,7 @@ 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->isfloating = r->isfloating;
116 c->tags |= r->tags;
117 for (m = mons; m && m->num != r->monitor; m = m…
118 @@ -415,6 +429,47 @@ attachstack(Client *c)
119 }
120
121 void
122 +swallow(Client *p, Client *c)
123 +{
124 + if (c->noswallow || c->isterminal)
125 + return;
126 +
127 + detach(c);
128 + detachstack(c);
129 +
130 + setclientstate(c, WithdrawnState);
131 + XUnmapWindow(dpy, p->win);
132 +
133 + p->swallowing = c;
134 + c->mon = p->mon;
135 +
136 + Window w = p->win;
137 + p->win = c->win;
138 + c->win = w;
139 + updatetitle(p);
140 + arrange(p->mon);
141 + XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
142 + configure(p);
143 + updateclientlist();
144 +}
145 +
146 +void
147 +unswallow(Client *c)
148 +{
149 + c->win = c->swallowing->win;
150 +
151 + free(c->swallowing);
152 + c->swallowing = NULL;
153 +
154 + updatetitle(c);
155 + arrange(c->mon);
156 + XMapWindow(dpy, c->win);
157 + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
158 + configure(c);
159 + setclientstate(c, NormalState);
160 +}
161 +
162 +void
163 buttonpress(XEvent *e)
164 {
165 unsigned int i, x, click;
166 @@ -477,7 +531,7 @@ cleanup(void)
167 selmon->lt[selmon->sellt] = &foo;
168 for (m = mons; m; m = m->next)
169 while (m->stack)
170 - unmanage(m->stack, 0);
171 + unmanage(m->stack, 0); // XXX - unmanage swallo…
172 XUngrabKey(dpy, AnyKey, AnyModifier, root);
173 while (mons)
174 cleanupmon(mons);
175 @@ -665,6 +719,9 @@ destroynotify(XEvent *e)
176
177 if ((c = wintoclient(ev->window)))
178 unmanage(c, 1);
179 +
180 + else if ((c = swallowingclient(ev->window)))
181 + unmanage(c->swallowing, 1);
182 }
183
184 void
185 @@ -1034,12 +1091,13 @@ killclient(const Arg *arg)
186 void
187 manage(Window w, XWindowAttributes *wa)
188 {
189 - Client *c, *t = NULL;
190 + Client *c, *t = NULL, *term = NULL;
191 Window trans = None;
192 XWindowChanges wc;
193
194 c = ecalloc(1, sizeof(Client));
195 c->win = w;
196 + c->pid = winpid(w);
197 /* geometry */
198 c->x = c->oldx = wa->x;
199 c->y = c->oldy = wa->y;
200 @@ -1054,6 +1112,7 @@ manage(Window w, XWindowAttributes *wa)
201 } else {
202 c->mon = selmon;
203 applyrules(c);
204 + term = termforwin(c);
205 }
206
207 if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
208 @@ -1090,6 +1149,8 @@ manage(Window w, XWindowAttributes *wa)
209 c->mon->sel = c;
210 arrange(c->mon);
211 XMapWindow(dpy, c->win);
212 + if (term)
213 + swallow(term, c);
214 focus(NULL);
215 }
216
217 @@ -1757,6 +1818,20 @@ unmanage(Client *c, int destroyed)
218 Monitor *m = c->mon;
219 XWindowChanges wc;
220
221 + if (c->swallowing) {
222 + unswallow(c);
223 + return;
224 + }
225 +
226 + Client *s = swallowingclient(c->win);
227 + if (s) {
228 + free(s->swallowing);
229 + s->swallowing = NULL;
230 + arrange(m);
231 + focus(NULL);
232 + return;
233 + }
234 +
235 /* The server grab construct avoids race conditions. */
236 detach(c);
237 detachstack(c);
238 @@ -1772,9 +1847,12 @@ unmanage(Client *c, int destroyed)
239 XUngrabServer(dpy);
240 }
241 free(c);
242 - focus(NULL);
243 - updateclientlist();
244 - arrange(m);
245 +
246 + if (!s) {
247 + arrange(m);
248 + focus(NULL);
249 + updateclientlist();
250 + }
251 }
252
253 void
254 @@ -2039,16 +2117,116 @@ view(const Arg *arg)
255 arrange(selmon);
256 }
257
258 +pid_t
259 +winpid(Window w)
260 +{
261 + pid_t result = 0;
262 +
263 + xcb_res_client_id_spec_t spec = {0};
264 + spec.client = w;
265 + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
266 +
267 + xcb_generic_error_t *e = NULL;
268 + xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(…
269 + xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_…
270 +
271 + if (!r)
272 + return (pid_t)0;
273 +
274 + xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids…
275 + for (; i.rem; xcb_res_client_id_value_next(&i)) {
276 + spec = i.data->spec;
277 + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID…
278 + uint32_t *t = xcb_res_client_id_value_value(i.d…
279 + result = *t;
280 + break;
281 + }
282 + }
283 +
284 + free(r);
285 +
286 + if (result == (pid_t)-1)
287 + result = 0;
288 + return result;
289 +}
290 +
291 +pid_t
292 +getparentprocess(pid_t p)
293 +{
294 + unsigned int v = 0;
295 +
296 +#ifdef __linux__
297 + FILE *f;
298 + char buf[256];
299 + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
300 +
301 + if (!(f = fopen(buf, "r")))
302 + return 0;
303 +
304 + fscanf(f, "%*u %*s %*c %u", &v);
305 + fclose(f);
306 +#endif /* __linux__ */
307 +
308 + return (pid_t)v;
309 +}
310 +
311 +int
312 +isdescprocess(pid_t p, pid_t c)
313 +{
314 + while (p != c && c != 0)
315 + c = getparentprocess(c);
316 +
317 + return (int)c;
318 +}
319 +
320 +Client *
321 +termforwin(const Client *w)
322 +{
323 + Client *c;
324 + Monitor *m;
325 +
326 + if (!w->pid || w->isterminal)
327 + return NULL;
328 +
329 + for (m = mons; m; m = m->next) {
330 + for (c = m->clients; c; c = c->next) {
331 + if (c->isterminal && !c->swallowing && c->pid &…
332 + return c;
333 + }
334 + }
335 +
336 + return NULL;
337 +}
338 +
339 +Client *
340 +swallowingclient(Window w)
341 +{
342 + Client *c;
343 + Monitor *m;
344 +
345 + for (m = mons; m; m = m->next) {
346 + for (c = m->clients; c; c = c->next) {
347 + if (c->swallowing && c->swallowing->win == w)
348 + return c;
349 + }
350 + }
351 +
352 + return NULL;
353 +}
354 +
355 Client *
356 wintoclient(Window w)
357 {
358 Client *c;
359 Monitor *m;
360
361 - for (m = mons; m; m = m->next)
362 - for (c = m->clients; c; c = c->next)
363 + for (m = mons; m; m = m->next) {
364 + for (c = m->clients; c; c = c->next) {
365 if (c->win == w)
366 return c;
367 + }
368 + }
369 +
370 return NULL;
371 }
372
373 @@ -2130,6 +2308,8 @@ main(int argc, char *argv[])
374 fputs("warning: no locale support\n", stderr);
375 if (!(dpy = XOpenDisplay(NULL)))
376 die("dwm: cannot open display\n");
377 + if (!(xcon = XGetXCBConnection(dpy)))
378 + die("dwm: cannot get xcb connection\n");
379 checkotherwm();
380 setup();
381 scan();
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.