summaryrefslogtreecommitdiffhomepage
path: root/patch
diff options
context:
space:
mode:
authorbakkeby <[email protected]>2019-10-22 19:08:00 +0200
committerbakkeby <[email protected]>2019-10-24 09:33:20 +0200
commit3726d8d1ead98778f585e0f75256977dcba4de07 (patch)
tree43b61a0e65427cf9b7d9b774c6c9c4e08872ebbf /patch
parent71e61d180ec5d365a3fd3eb4739d33f5da80a517 (diff)
downloaddwm-flexipatch-3726d8d1ead98778f585e0f75256977dcba4de07.tar.gz
dwm-flexipatch-3726d8d1ead98778f585e0f75256977dcba4de07.zip
Adding swallow patch
Diffstat (limited to 'patch')
-rw-r--r--patch/include.c3
-rw-r--r--patch/include.h3
-rw-r--r--patch/swallow.c149
-rw-r--r--patch/swallow.h5
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