diff options
| author | bakkeby <[email protected]> | 2019-10-22 19:08:00 +0200 |
|---|---|---|
| committer | bakkeby <[email protected]> | 2019-10-24 09:33:20 +0200 |
| commit | 3726d8d1ead98778f585e0f75256977dcba4de07 (patch) | |
| tree | 43b61a0e65427cf9b7d9b774c6c9c4e08872ebbf /patch | |
| parent | 71e61d180ec5d365a3fd3eb4739d33f5da80a517 (diff) | |
| download | dwm-flexipatch-3726d8d1ead98778f585e0f75256977dcba4de07.tar.gz dwm-flexipatch-3726d8d1ead98778f585e0f75256977dcba4de07.zip | |
Adding swallow patch
Diffstat (limited to 'patch')
| -rw-r--r-- | patch/include.c | 3 | ||||
| -rw-r--r-- | patch/include.h | 3 | ||||
| -rw-r--r-- | patch/swallow.c | 149 | ||||
| -rw-r--r-- | patch/swallow.h | 5 |
4 files changed, 160 insertions, 0 deletions
diff --git a/patch/include.c b/patch/include.c index d3da45a..3c73054 100644 --- a/patch/include.c +++ b/patch/include.c @@ -90,6 +90,9 @@ #if SYSTRAY_PATCH #include "systray.c" #endif +#if SWALLOW_PATCH +#include "swallow.c" +#endif // SWALLOW_PATCH #if SWITCHCOL_PATCH #include "switchcol.c" #endif diff --git a/patch/include.h b/patch/include.h index 1524949..168384e 100644 --- a/patch/include.h +++ b/patch/include.h @@ -90,6 +90,9 @@ #if SYSTRAY_PATCH #include "systray.h" #endif +#if SWALLOW_PATCH +#include "swallow.h" +#endif // SWALLOW_PATCH #if SWITCHCOL_PATCH #include "switchcol.h" #endif diff --git a/patch/swallow.c b/patch/swallow.c new file mode 100644 index 0000000..ae6d45e --- /dev/null +++ b/patch/swallow.c @@ -0,0 +1,149 @@ +#include <X11/Xlib-xcb.h> +#include <xcb/res.h> + +static xcb_connection_t *xcon; + +void +swallow(Client *p, Client *c) +{ + if (c->noswallow || c->isterminal) + return; + + detach(c); + detachstack(c); + + setclientstate(c, WithdrawnState); + XUnmapWindow(dpy, p->win); + + p->swallowing = c; + c->mon = p->mon; + + Window w = p->win; + p->win = c->win; + c->win = w; + updatetitle(p); + arrange(p->mon); + XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); + configure(p); + updateclientlist(); +} + +void +unswallow(Client *c) +{ + c->win = c->swallowing->win; + + free(c->swallowing); + c->swallowing = NULL; + + 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); +} + +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; +} + +pid_t +getparentprocess(pid_t p) +{ + unsigned int v = 0; + +#ifdef __linux__ + FILE *f; + char buf[256]; + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); + + if (!(f = fopen(buf, "r"))) + return 0; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-result" + fscanf(f, "%*u %*s %*c %u", &v); +#pragma GCC diagnostic pop + fclose(f); +#endif /* __linux__ */ + + return (pid_t)v; +} + +int +isdescprocess(pid_t p, pid_t c) +{ + while (p != c && c != 0) + c = getparentprocess(c); + + return (int)c; +} + +Client * +termforwin(const Client *w) +{ + Client *c; + Monitor *m; + + if (!w->pid || w->isterminal) + return NULL; + + c = selmon->sel; + if (c && c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) + return c; + + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) { + if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) + return c; + } + } + + return NULL; +} + +Client * +swallowingclient(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 NULL; +} diff --git a/patch/swallow.h b/patch/swallow.h new file mode 100644 index 0000000..094cbc4 --- /dev/null +++ b/patch/swallow.h @@ -0,0 +1,5 @@ +static pid_t getparentprocess(pid_t p); +static int isdescprocess(pid_t p, pid_t c); +static Client *swallowingclient(Window w); +static Client *termforwin(const Client *c); +static pid_t winpid(Window w);
\ No newline at end of file |
