diff --git a/config.def.h b/config.def.h index 3e5e1e0..75e60c5 100644 --- a/config.def.h +++ b/config.def.h @@ -8,6 +8,9 @@ static const int corner_radius = 10; static const unsigned int borderpx = 1; /* border pixel of windows */ #endif // ROUNDED_CORNERS_PATCH static const unsigned int snap = 32; /* snap pixel */ +#if SWALLOW_PATCH +static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ +#endif // SWALLOW_PATCH #if VANITYGAPS_PATCH static const unsigned int gappih = 20; /* horiz inner gap between windows */ static const unsigned int gappiv = 10; /* vert inner gap between windows */ diff --git a/dwm.c b/dwm.c index 0168fd1..22a233e 100644 --- a/dwm.c +++ b/dwm.c @@ -732,6 +732,9 @@ applyrules(Client *c) XClassHint ch = { NULL, NULL }; /* rule matching */ + #if SWALLOW_PATCH + c->noswallow = -1; + #endif // SWALLOW_PATCH c->isfloating = 0; c->tags = 0; XGetClassHint(dpy, c->win, &ch); @@ -785,7 +788,10 @@ applyrules(Client *c) #if SWITCHTAG_PATCH #if SWALLOW_PATCH - if (r->switchtag && (c->noswallow || !termforwin(c))) + if (r->switchtag && ( + c->noswallow > 0 || + !termforwin(c) || + !(c->isfloating && swallowfloating && c->noswallow < 0))) #else if (r->switchtag) #endif // SWALLOW_PATCH @@ -1173,7 +1179,6 @@ clientmessage(XEvent *e) #endif // !FAKEFULLSCREEN_PATCH ))); #endif // FAKEFULLSCREEN_CLIENT_PATCH - } } else if (cme->message_type == netatom[NetActiveWindow]) { #if FOCUSONNETACTIVE_PATCH if (c->tags & c->mon->tagset[c->mon->seltags]) { @@ -2125,6 +2130,8 @@ manage(Window w, XWindowAttributes *wa) applyrules(c); #if SWALLOW_PATCH term = termforwin(c); + if (term) + c->mon = term->mon; #endif // SWALLOW_PATCH } @@ -2209,7 +2216,6 @@ manage(Window w, XWindowAttributes *wa) if (c->mon == selmon) unfocus(selmon->sel, 0, c); c->mon->sel = c; - arrange(c->mon); #if BAR_WINTITLEACTIONS_PATCH if (!HIDDEN(c)) XMapWindow(dpy, c->win); @@ -2220,6 +2226,7 @@ manage(Window w, XWindowAttributes *wa) if (term) swallow(term, c); #endif // SWALLOW_PATCH + arrange(c->mon); focus(NULL); } @@ -2792,6 +2799,10 @@ run(void) void scan(void) { + #if SWALLOW_PATCH + scanner = 1; + char swin[256]; + #endif // SWALLOW_PATCH unsigned int i, num; Window d1, d2, *wins = NULL; XWindowAttributes wa; @@ -2808,6 +2819,10 @@ scan(void) #endif // BAR_ANYBAR_PATCH if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) manage(wins[i], &wa); + #if SWALLOW_PATCH + else if (gettextprop(wins[i], netatom[NetClientList], swin, sizeof swin)) + manage(wins[i], &wa); + #endif // SWALLOW_PATCH } for (i = 0; i < num; i++) { /* now the transients */ if (!XGetWindowAttributes(dpy, wins[i], &wa)) @@ -2818,6 +2833,9 @@ scan(void) } XFree(wins); } + #if SWALLOW_PATCH + scanner = 0; + #endif // SWALLOW_PATCH } void diff --git a/patch/swallow.c b/patch/swallow.c index ae6d45e..30b213a 100644 --- a/patch/swallow.c +++ b/patch/swallow.c @@ -1,12 +1,17 @@ #include #include +static int scanner; static xcb_connection_t *xcon; void swallow(Client *p, Client *c) { - if (c->noswallow || c->isterminal) + Client *s; + + if (c->noswallow > 0 || c->isterminal) + return; + if (c->noswallow < 0 && !swallowfloating && c->isfloating) return; detach(c); @@ -21,9 +26,14 @@ swallow(Client *p, Client *c) Window w = p->win; p->win = c->win; c->win = w; + + XChangeProperty(dpy, c->win, netatom[NetClientList], XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(p->win), 1); + updatetitle(p); + s = scanner ? c : p; + XMoveResizeWindow(dpy, p->win, s->x, s->y, s->w, s->h); arrange(p->mon); - XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); configure(p); updateclientlist(); } @@ -36,12 +46,17 @@ unswallow(Client *c) free(c->swallowing); c->swallowing = NULL; + XDeleteProperty(dpy, c->win, netatom[NetClientList]); + + /* unfullscreen the client */ + setfullscreen(c, 0); updatetitle(c); arrange(c->mon); XMapWindow(dpy, c->win); XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - configure(c); setclientstate(c, NormalState); + focus(NULL); + arrange(c->mon); } pid_t @@ -82,21 +97,25 @@ getparentprocess(pid_t p) { unsigned int v = 0; -#ifdef __linux__ +#if defined(__linux__) FILE *f; char buf[256]; snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); if (!(f = fopen(buf, "r"))) - return 0; + return (pid_t)0; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-result" - fscanf(f, "%*u %*s %*c %u", &v); -#pragma GCC diagnostic pop + if (fscanf(f, "%*u %*s %*c %u", (unsigned *)&v) != 1) + v = (pid_t)0; fclose(f); -#endif /* __linux__ */ +#elif defined(__FreeBSD__) + struct kinfo_proc *proc = kinfo_getproc(p); + if (!proc) + return (pid_t)0; + v = proc->ki_ppid; + free(proc); +#endif return (pid_t)v; } diff --git a/patch/swallow.h b/patch/swallow.h index 094cbc4..98ae7fb 100644 --- a/patch/swallow.h +++ b/patch/swallow.h @@ -1,5 +1,7 @@ static pid_t getparentprocess(pid_t p); static int isdescprocess(pid_t p, pid_t c); +static void swallow(Client *p, Client *c); static Client *swallowingclient(Window w); static Client *termforwin(const Client *c); +static void unswallow(Client *c); static pid_t winpid(Window w); \ No newline at end of file