diff options
| author | Joe <rbo@gmx.us> | 2025-02-28 20:59:22 +0100 | 
|---|---|---|
| committer | Joe <rbo@gmx.us> | 2025-02-28 20:59:22 +0100 | 
| commit | f754a57438a46dafcc0ad6c13ad1d66dc05a21b4 (patch) | |
| tree | 30bd22f50f2f284fdf0c92f7c7c48071f78515de /patches/applied | |
| parent | fuck tearing (diff) | |
| download | dwl-f754a57438a46dafcc0ad6c13ad1d66dc05a21b4.tar.gz dwl-f754a57438a46dafcc0ad6c13ad1d66dc05a21b4.tar.bz2 dwl-f754a57438a46dafcc0ad6c13ad1d66dc05a21b4.tar.xz dwl-f754a57438a46dafcc0ad6c13ad1d66dc05a21b4.tar.zst dwl-f754a57438a46dafcc0ad6c13ad1d66dc05a21b4.zip | |
swallowd
Diffstat (limited to '')
| -rw-r--r-- | patches/applied/swallow.patch | 240 | 
1 files changed, 240 insertions, 0 deletions
| diff --git a/patches/applied/swallow.patch b/patches/applied/swallow.patch new file mode 100644 index 0000000..b4581c4 --- /dev/null +++ b/patches/applied/swallow.patch @@ -0,0 +1,240 @@ +From 4b80c425c9f414bc079a0e61f5a3ef42eea85476 Mon Sep 17 00:00:00 2001 +From: choc <notchoc@proton.me> +Date: Fri, 15 Sep 2023 10:36:21 +0800 +Subject: [PATCH] implement swallow + +--- + client.h     |  12 ++++++ + config.def.h |   7 ++-- + dwl.c        | 112 ++++++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 123 insertions(+), 8 deletions(-) + +diff --git a/client.h b/client.h +index 42f225f..bc9cad2 100644 +--- a/client.h ++++ b/client.h +@@ -131,6 +131,18 @@ client_get_appid(Client *c) + 	return c->surface.xdg->toplevel->app_id; + } +  ++static inline int ++client_get_pid(Client *c) ++{ ++	pid_t pid; ++#ifdef XWAYLAND ++	if (client_is_x11(c)) ++		return c->surface.xwayland->pid; ++#endif ++	wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); ++	return pid; ++} ++ + static inline void + client_get_clip(Client *c, struct wlr_box *clip) + { +diff --git a/config.def.h b/config.def.h +index 22d2171..7e5fef1 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -22,10 +22,11 @@ static int log_level = WLR_ERROR; +  + /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ + static const Rule rules[] = { +-	/* app_id             title       tags mask     isfloating   monitor */ ++	/* app_id             title       tags mask     isfloating  isterm  noswallow  monitor */ + 	/* examples: */ +-	{ "Gimp_EXAMPLE",     NULL,       0,            1,           -1 }, /* Start on currently visible tags floating, not tiled */ +-	{ "firefox_EXAMPLE",  NULL,       1 << 8,       0,           -1 }, /* Start on ONLY tag "9" */ ++	{ "Gimp_EXAMPLE",     NULL,       0,            1,          0,      0,         -1 }, /* Start on currently visible tags floating, not tiled */ ++	{ "firefox_EXAMPLE",  NULL,       1 << 8,       0,          0,      0,         -1 }, /* Start on ONLY tag "9" */ ++	{ "foot",             NULL,       0,            0,          1,      1,         -1 }, /* make foot swallow clients that are not foot */ + }; +  + /* layout(s) */ +diff --git a/dwl.c b/dwl.c +index dc0437e..c6a5e9d 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -103,7 +103,8 @@ typedef struct { + } Button; +  + typedef struct Monitor Monitor; +-typedef struct { ++typedef struct Client Client; ++struct Client { + 	/* Must keep these three elements in this order */ + 	unsigned int type; /* XDGShell or X11* */ + 	struct wlr_box geom; /* layout-relative, includes border */ +@@ -138,9 +139,11 @@ typedef struct { + #endif + 	unsigned int bw; + 	uint32_t tags; +-	int isfloating, isurgent, isfullscreen; ++	int isfloating, isurgent, isfullscreen, isterm, noswallow; + 	uint32_t resize; /* configure serial of a pending resize */ +-} Client; ++	pid_t pid; ++	Client *swallowing, *swallowedby; ++}; +  + typedef struct { + 	uint32_t mod; +@@ -229,6 +232,8 @@ typedef struct { + 	const char *title; + 	uint32_t tags; + 	int isfloating; ++	int isterm; ++	int noswallow; + 	int monitor; + } Rule; +  +@@ -351,6 +356,10 @@ static Monitor *xytomon(double x, double y); + static void xytonode(double x, double y, struct wlr_surface **psurface, + 		Client **pc, LayerSurface **pl, double *nx, double *ny); + static void zoom(const Arg *arg); ++static pid_t getparentprocess(pid_t p); ++static int isdescprocess(pid_t p, pid_t c); ++static Client *termforwin(Client *w); ++static void swallow(Client *c, Client *w); +  + /* variables */ + static const char broken[] = "broken"; +@@ -461,10 +470,14 @@ applyrules(Client *c) + 	if (!(title = client_get_title(c))) + 		title = broken; +  ++	c->pid = client_get_pid(c); ++ + 	for (r = rules; r < END(rules); r++) { + 		if ((!r->title || strstr(title, r->title)) + 				&& (!r->id || strstr(appid, r->id))) { + 			c->isfloating = r->isfloating; ++			c->isterm     = r->isterm; ++			c->noswallow  = r->noswallow; + 			newtags |= r->tags; + 			i = 0; + 			wl_list_for_each(m, &mons, link) { +@@ -473,6 +486,21 @@ applyrules(Client *c) + 			} + 		} + 	} ++	if (!c->noswallow && !client_is_float_type(c) ++			&& !c->surface.xdg->initial_commit) { ++		Client *p = termforwin(c); ++		if (p) { ++			c->swallowedby = p; ++			p->swallowing  = c; ++			wl_list_remove(&c->link); ++			wl_list_remove(&c->flink); ++			swallow(c, p); ++			wl_list_remove(&p->link); ++			wl_list_remove(&p->flink); ++			mon = p->mon; ++			newtags = p->tags; ++		} ++	} + 	setmon(c, mon, newtags); + } +  +@@ -1467,6 +1495,63 @@ handlesig(int signo) + 	} + } +  ++pid_t ++getparentprocess(pid_t p) ++{ ++	unsigned int v = 0; ++ ++	FILE *f; ++	char buf[256]; ++	snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); ++ ++	if (!(f = fopen(buf, "r"))) ++		return 0; ++ ++	fscanf(f, "%*u %*s %*c %u", &v); ++	fclose(f); ++ ++	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(Client *w) ++{ ++	Client *c; ++ ++	if (!w->pid || w->isterm || w->noswallow) ++		return NULL; ++ ++	wl_list_for_each(c, &fstack, flink) ++		if (c->isterm && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) ++			return c; ++ ++	return NULL; ++} ++ ++void ++swallow(Client *c, Client *w) ++{ ++	c->bw = w->bw; ++	c->isfloating = w->isfloating; ++	c->isurgent = w->isurgent; ++	c->isfullscreen = w->isfullscreen; ++	c->tags = w->tags; ++	c->geom = w->geom; ++	wl_list_insert(&w->link, &c->link); ++	wl_list_insert(&w->flink, &c->flink); ++	wlr_scene_node_set_enabled(&w->scene->node, 0); ++	wlr_scene_node_set_enabled(&c->scene->node, 1); ++} ++ + void + incnmaster(const Arg *arg) + { +@@ -2746,15 +2831,32 @@ unmapnotify(struct wl_listener *listener, void *data) + 		grabc = NULL; + 	} +  ++	if (c->swallowedby) ++		swallow(c->swallowedby, c); ++ + 	if (client_is_unmanaged(c)) { + 		if (c == exclusive_focus) { + 			exclusive_focus = NULL; + 			focusclient(focustop(selmon), 1); + 		} + 	} else { +-		wl_list_remove(&c->link); ++		if (!c->swallowing) ++			wl_list_remove(&c->link); + 		setmon(c, NULL, 0); +-		wl_list_remove(&c->flink); ++		if (!c->swallowing) ++			wl_list_remove(&c->flink); ++	} ++ ++	if (c->swallowedby) { ++		c->swallowedby->prev = c->geom; ++		setfullscreen(c->swallowedby, c->isfullscreen); ++		c->swallowedby->swallowing = NULL; ++		c->swallowedby = NULL; ++	} ++ ++	if (c->swallowing) { ++		c->swallowing->swallowedby = NULL; ++		c->swallowing = NULL; + 	} +  + 	wlr_scene_node_destroy(&c->scene->node); +--  +2.43.0 + | 
