Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-swallow-6.1.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-swallow-6.1.diff (9337B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 7054c06..2bfd607 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -24,9 +24,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 4eefb71..34ea872 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_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" $…
32 diff --git a/dwm.c b/dwm.c
33 index 0362114..1d38293 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 @@ -92,9 +94,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 @@ -138,6 +142,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 @@ -170,12 +176,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 @@ -206,8 +214,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 @@ -227,6 +237,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 @@ -267,6 +278,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 @@ -296,6 +309,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 @@ -412,6 +426,48 @@ attachstack(Client *c)
119 c->mon->stack = c;
120 }
121
122 +void
123 +swallow(Client *p, Client *c)
124 +{
125 + if (c->noswallow || c->isterminal)
126 + return;
127 +
128 + detach(c);
129 + detachstack(c);
130 +
131 + setclientstate(c, WithdrawnState);
132 + XUnmapWindow(dpy, p->win);
133 +
134 + p->swallowing = c;
135 + c->mon = p->mon;
136 +
137 + Window w = p->win;
138 + p->win = c->win;
139 + c->win = w;
140 + updatetitle(p);
141 + arrange(p->mon);
142 + XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
143 + configure(p);
144 + updateclientlist();
145 +}
146 +
147 +void
148 +unswallow(Client *c)
149 +{
150 + c->win = c->swallowing->win;
151 +
152 + free(c->swallowing);
153 + c->swallowing = NULL;
154 +
155 + updatetitle(c);
156 + arrange(c->mon);
157 + XMapWindow(dpy, c->win);
158 + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
159 + configure(c);
160 + setclientstate(c, NormalState);
161 + focus(c);
162 +}
163 +
164 void
165 buttonpress(XEvent *e)
166 {
167 @@ -475,7 +531,7 @@ cleanup(void)
168 selmon->lt[selmon->sellt] = &foo;
169 for (m = mons; m; m = m->next)
170 while (m->stack)
171 - unmanage(m->stack, 0);
172 + unmanage(m->stack, 0); // XXX - unmanage swallo…
173 XUngrabKey(dpy, AnyKey, AnyModifier, root);
174 while (mons)
175 cleanupmon(mons);
176 @@ -661,6 +717,9 @@ destroynotify(XEvent *e)
177
178 if ((c = wintoclient(ev->window)))
179 unmanage(c, 1);
180 +
181 + else if ((c = swallowingclient(ev->window)))
182 + unmanage(c->swallowing, 1);
183 }
184
185 void
186 @@ -1032,12 +1091,13 @@ killclient(const Arg *arg)
187 void
188 manage(Window w, XWindowAttributes *wa)
189 {
190 - Client *c, *t = NULL;
191 + Client *c, *t, *term = NULL;
192 Window trans = None;
193 XWindowChanges wc;
194
195 c = ecalloc(1, sizeof(Client));
196 c->win = w;
197 + c->pid = winpid(w);
198 updatetitle(c);
199 if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(tr…
200 c->mon = t->mon;
201 @@ -1045,7 +1105,9 @@ manage(Window w, XWindowAttributes *wa)
202 } else {
203 c->mon = selmon;
204 applyrules(c);
205 + term = termforwin(c);
206 }
207 +
208 /* geometry */
209 c->x = c->oldx = wa->x;
210 c->y = c->oldy = wa->y;
211 @@ -1085,8 +1147,11 @@ manage(Window w, XWindowAttributes *wa)
212 if (c->mon == selmon)
213 unfocus(selmon->sel, 0);
214 c->mon->sel = c;
215 - arrange(c->mon);
216 + if (!term)
217 + arrange(c->mon);
218 XMapWindow(dpy, c->win);
219 + if (term)
220 + swallow(term, c);
221 focus(NULL);
222 }
223
224 @@ -1758,6 +1823,20 @@ unmanage(Client *c, int destroyed)
225 Monitor *m = c->mon;
226 XWindowChanges wc;
227
228 + if (c->swallowing) {
229 + unswallow(c);
230 + return;
231 + }
232 +
233 + Client *s = swallowingclient(c->win);
234 + if (s) {
235 + free(s->swallowing);
236 + s->swallowing = NULL;
237 + arrange(m);
238 + focus(NULL);
239 + return;
240 + }
241 +
242 /* The server grab construct avoids race conditions. */
243 detach(c);
244 detachstack(c);
245 @@ -1773,9 +1852,12 @@ unmanage(Client *c, int destroyed)
246 XUngrabServer(dpy);
247 }
248 free(c);
249 - focus(NULL);
250 - updateclientlist();
251 - arrange(m);
252 +
253 + if (!s) {
254 + arrange(m);
255 + focus(NULL);
256 + updateclientlist();
257 + }
258 }
259
260 void
261 @@ -2040,16 +2122,116 @@ view(const Arg *arg)
262 arrange(selmon);
263 }
264
265 +pid_t
266 +winpid(Window w)
267 +{
268 + pid_t result = 0;
269 +
270 + xcb_res_client_id_spec_t spec = {0};
271 + spec.client = w;
272 + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
273 +
274 + xcb_generic_error_t *e = NULL;
275 + xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(…
276 + xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_…
277 +
278 + if (!r)
279 + return (pid_t)0;
280 +
281 + xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids…
282 + for (; i.rem; xcb_res_client_id_value_next(&i)) {
283 + spec = i.data->spec;
284 + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID…
285 + uint32_t *t = xcb_res_client_id_value_value(i.d…
286 + result = *t;
287 + break;
288 + }
289 + }
290 +
291 + free(r);
292 +
293 + if (result == (pid_t)-1)
294 + result = 0;
295 + return result;
296 +}
297 +
298 +pid_t
299 +getparentprocess(pid_t p)
300 +{
301 + unsigned int v = 0;
302 +
303 +#ifdef __linux__
304 + FILE *f;
305 + char buf[256];
306 + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
307 +
308 + if (!(f = fopen(buf, "r")))
309 + return 0;
310 +
311 + fscanf(f, "%*u %*s %*c %u", &v);
312 + fclose(f);
313 +#endif /* __linux__ */
314 +
315 + return (pid_t)v;
316 +}
317 +
318 +int
319 +isdescprocess(pid_t p, pid_t c)
320 +{
321 + while (p != c && c != 0)
322 + c = getparentprocess(c);
323 +
324 + return (int)c;
325 +}
326 +
327 +Client *
328 +termforwin(const Client *w)
329 +{
330 + Client *c;
331 + Monitor *m;
332 +
333 + if (!w->pid || w->isterminal)
334 + return NULL;
335 +
336 + for (m = mons; m; m = m->next) {
337 + for (c = m->clients; c; c = c->next) {
338 + if (c->isterminal && !c->swallowing && c->pid &…
339 + return c;
340 + }
341 + }
342 +
343 + return NULL;
344 +}
345 +
346 +Client *
347 +swallowingclient(Window w)
348 +{
349 + Client *c;
350 + Monitor *m;
351 +
352 + for (m = mons; m; m = m->next) {
353 + for (c = m->clients; c; c = c->next) {
354 + if (c->swallowing && c->swallowing->win == w)
355 + return c;
356 + }
357 + }
358 +
359 + return NULL;
360 +}
361 +
362 Client *
363 wintoclient(Window w)
364 {
365 Client *c;
366 Monitor *m;
367
368 - for (m = mons; m; m = m->next)
369 - for (c = m->clients; c; c = c->next)
370 + for (m = mons; m; m = m->next) {
371 + for (c = m->clients; c; c = c->next) {
372 if (c->win == w)
373 return c;
374 + }
375 + }
376 +
377 return NULL;
378 }
379
380 @@ -2131,6 +2313,8 @@ main(int argc, char *argv[])
381 fputs("warning: no locale support\n", stderr);
382 if (!(dpy = XOpenDisplay(NULL)))
383 die("dwm: cannot open display\n");
384 + if (!(xcon = XGetXCBConnection(dpy)))
385 + die("dwm: cannot get xcb connection\n");
386 checkotherwm();
387 setup();
388 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.