aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/dwm/dwm.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-06 19:56:41 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-06 19:56:41 -0700
commit4e0318919dd726f485ea3a495ff0989f69f35630 (patch)
treeff22628bcaa163881afad87fc2501d5dffa43be2 /sys/cmd/dwm/dwm.c
parent186fe25ab798fe559be242dbe2eaff8e553c4e06 (diff)
hand added swallow patch
Diffstat (limited to 'sys/cmd/dwm/dwm.c')
-rw-r--r--sys/cmd/dwm/dwm.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/sys/cmd/dwm/dwm.c b/sys/cmd/dwm/dwm.c
index 22ccc91..8e8d44c 100644
--- a/sys/cmd/dwm/dwm.c
+++ b/sys/cmd/dwm/dwm.c
@@ -3,6 +3,7 @@
/* global variables */
char broken[] = "<broken>";
char stext[256];
+int scanner;
int screen;
int sw, sh; /* X display screen geometry width, height */
int bh, blw = 0; /* bar geometry */
@@ -26,6 +27,8 @@ void (*handler[LASTEvent]) (XEvent *) = {
[UnmapNotify] = unmapnotify
};
+xcb_connection_t *xcon;
+
Atom wmatom[WMLast] = {0}, netatom[NetLast] = {0};
int running = 1;
Cur *cursor[MouseLast] = {0};
@@ -282,6 +285,8 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
+ else if ((c = swallowing(ev->window)))
+ unmanage(c->swallowing, 1);
}
Monitor *
@@ -498,12 +503,13 @@ keypress(XEvent *e)
void
manage(Window w, XWindowAttributes *wa)
{
- Client *c, *t = nil;
+ Client *c, *t = nil, *term = nil;
Window trans = None;
XWindowChanges wc;
c = ecalloc(1, sizeof(Client));
c->win = w;
+ c->pid = winpid(w);
/* geometry */
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
@@ -518,6 +524,7 @@ manage(Window w, XWindowAttributes *wa)
} else {
c->mon = selmon;
applyrules(c);
+ term = termof(c);
}
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
@@ -539,12 +546,15 @@ manage(Window w, XWindowAttributes *wa)
updatewmhints(c);
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
grabbuttons(c, 0);
+
if (!c->isfloating)
c->isfloating = c->oldstate = trans != None || c->isfixed;
if (c->isfloating)
XRaiseWindow(dpy, c->win);
+
attach(c);
attachstack(c);
+
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
@@ -554,6 +564,8 @@ manage(Window w, XWindowAttributes *wa)
c->mon->sel = c;
arrange(c->mon);
XMapWindow(dpy, c->win);
+ if (term)
+ swallow(term, c);
focus(nil);
}
@@ -706,6 +718,9 @@ scan(void)
uint i, num;
Window d1, d2, *wins = nil;
XWindowAttributes wa;
+ char swin[256];
+
+ scanner = 1;
if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
for (i = 0; i < num; i++) {
@@ -714,6 +729,8 @@ scan(void)
continue;
if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
manage(wins[i], &wa);
+ else if (gettextprop(wins[i], netatom[NetClientList], swin, sizeof swin))
+ manage(wins[i], &wa);
}
for (i = 0; i < num; i++) { /* now the transients */
if (!XGetWindowAttributes(dpy, wins[i], &wa))
@@ -725,6 +742,8 @@ scan(void)
if (wins)
XFree(wins);
}
+
+ scanner = 0;
}
void
@@ -806,6 +825,22 @@ sigchld(int unused)
while (0 < waitpid(-1, nil, WNOHANG));
}
+Client *
+swallowing(Window w)
+{
+ Client *c;
+ Monitor *m;
+
+ for (m = mons; m; m = m->next) {
+ for (c = m->clients; c; c = c->next) {
+ if (c->swallowing && c->swallowing->win == w)
+ return c;
+ }
+ }
+
+ return nil;
+}
+
void
tile(Monitor *m)
{
@@ -830,7 +865,7 @@ tile(Monitor *m)
h = (m->wh - ty) / (n - i) - m->gapx;
resize(c, m->wx + mw + m->gapx, m->wy + ty, m->ww - mw - (2*c->bw) - (2*m->gapx), h - (2*c->bw), 0);
if (ty + HEIGHT(c) < m->wh)
- ty += HEIGHT(c) + m->gapx;
+ ty += HEIGHT(c);
}
}
@@ -997,6 +1032,40 @@ updatestatus(void)
drawbar(selmon);
}
+pid_t
+winpid(Window w)
+{
+ pid_t result = 0;
+
+ xcb_res_client_id_spec_t spec = {0};
+ spec.client = w;
+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
+
+ xcb_generic_error_t *e = NULL;
+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
+
+ if (!r)
+ return (pid_t)0;
+
+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
+ for (; i.rem; xcb_res_client_id_value_next(&i)) {
+ spec = i.data->spec;
+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
+ uint32_t *t = xcb_res_client_id_value_value(i.data);
+ result = *t;
+ break;
+ }
+ }
+
+ free(r);
+
+ if (result == (pid_t)-1)
+ result = 0;
+
+ return result;
+}
+
Client *
wintoclient(Window w)
{
@@ -1074,6 +1143,8 @@ main(int argc, char *argv[])
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(nil)))
fatal("dwm: cannot open display");
+ if (!(xcon = XGetXCBConnection(dpy)))
+ fatal("dwm: cannot get xcb connection");
checkotherwm();
setup();