mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-10-31 20:14:20 +00:00 
			
		
		
		
	Applied the swallow patch
This commit is contained in:
		
							parent
							
								
									01dff7b679
								
							
						
					
					
						commit
						3c67d89f56
					
				| @ -11,11 +11,11 @@ static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0}; | |||||||
| static const int tagcount = 9; | static const int tagcount = 9; | ||||||
| 
 | 
 | ||||||
| static const Rule rules[] = { | static const Rule rules[] = { | ||||||
| 	/* app_id     title       tags mask     isfloating   monitor */ | 	/* app_id     title       tags mask     isfloating  isterm  noswallow  monitor */ | ||||||
| 	/* examples:
 | 	/* examples:
 | ||||||
| 	{ "Gimp",     NULL,       0,            1,           -1 }, | 	{ "Gimp",     NULL,       0,            1,          0,      1,         -1 }, | ||||||
| 	*/ | 	*/ | ||||||
| 	{ "firefox",  NULL,       1 << 8,       0,           -1 }, | 	{ "firefox",  NULL,       1 << 8,       0,          0,      1,         -1 }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* layout(s) */ | /* layout(s) */ | ||||||
|  | |||||||
							
								
								
									
										100
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								dwl.c
									
									
									
									
									
								
							| @ -95,7 +95,8 @@ typedef struct { | |||||||
| } Button; | } Button; | ||||||
| 
 | 
 | ||||||
| typedef struct Monitor Monitor; | typedef struct Monitor Monitor; | ||||||
| typedef struct { | typedef struct Client Client; | ||||||
|  | struct Client { | ||||||
| 	/* Must keep these three elements in this order */ | 	/* Must keep these three elements in this order */ | ||||||
| 	unsigned int type; /* XDGShell or X11* */ | 	unsigned int type; /* XDGShell or X11* */ | ||||||
| 	struct wlr_box geom; /* layout-relative, includes border */ | 	struct wlr_box geom; /* layout-relative, includes border */ | ||||||
| @ -124,9 +125,11 @@ typedef struct { | |||||||
| #endif | #endif | ||||||
| 	unsigned int bw; | 	unsigned int bw; | ||||||
| 	uint32_t tags; | 	uint32_t tags; | ||||||
| 	int isfloating, isurgent, isfullscreen; | 	int isfloating, isurgent, isfullscreen, isterm, noswallow; | ||||||
| 	uint32_t resize; /* configure serial of a pending resize */ | 	uint32_t resize; /* configure serial of a pending resize */ | ||||||
| } Client; | 	pid_t pid; | ||||||
|  | 	Client *swallowing, *swallowedby; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| 	uint32_t mod; | 	uint32_t mod; | ||||||
| @ -208,6 +211,8 @@ typedef struct { | |||||||
| 	const char *title; | 	const char *title; | ||||||
| 	uint32_t tags; | 	uint32_t tags; | ||||||
| 	int isfloating; | 	int isfloating; | ||||||
|  | 	int isterm; | ||||||
|  | 	int noswallow; | ||||||
| 	int monitor; | 	int monitor; | ||||||
| } Rule; | } Rule; | ||||||
| 
 | 
 | ||||||
| @ -318,6 +323,10 @@ static Monitor *xytomon(double x, double y); | |||||||
| static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface, | static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface, | ||||||
| 		Client **pc, LayerSurface **pl, double *nx, double *ny); | 		Client **pc, LayerSurface **pl, double *nx, double *ny); | ||||||
| static void zoom(const Arg *arg); | 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 */ | /* variables */ | ||||||
| static const char broken[] = "broken"; | static const char broken[] = "broken"; | ||||||
| @ -458,6 +467,8 @@ applyrules(Client *c) | |||||||
| 		if ((!r->title || strstr(title, r->title)) | 		if ((!r->title || strstr(title, r->title)) | ||||||
| 				&& (!r->id || strstr(appid, r->id))) { | 				&& (!r->id || strstr(appid, r->id))) { | ||||||
| 			c->isfloating = r->isfloating; | 			c->isfloating = r->isfloating; | ||||||
|  | 			c->isterm     = r->isterm; | ||||||
|  | 			c->noswallow  = r->noswallow; | ||||||
| 			newtags |= r->tags; | 			newtags |= r->tags; | ||||||
| 			i = 0; | 			i = 0; | ||||||
| 			wl_list_for_each(m, &mons, link) | 			wl_list_for_each(m, &mons, link) | ||||||
| @ -1007,6 +1018,8 @@ createnotify(struct wl_listener *listener, void *data) | |||||||
| 	c->surface.xdg = xdg_surface; | 	c->surface.xdg = xdg_surface; | ||||||
| 	c->bw = borderpx; | 	c->bw = borderpx; | ||||||
| 
 | 
 | ||||||
|  | 	wl_client_get_credentials(c->surface.xdg->client->client, &c->pid, NULL, NULL); | ||||||
|  | 
 | ||||||
| 	LISTEN(&xdg_surface->events.map, &c->map, mapnotify); | 	LISTEN(&xdg_surface->events.map, &c->map, mapnotify); | ||||||
| 	LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); | 	LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); | ||||||
| 	LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); | 	LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); | ||||||
| @ -1325,6 +1338,61 @@ fullscreennotify(struct wl_listener *listener, void *data) | |||||||
| 	setfullscreen(c, client_wants_fullscreen(c)); | 	setfullscreen(c, client_wants_fullscreen(c)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 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, &clients, link) | ||||||
|  | 		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; | ||||||
|  | 	resize(c, w->geom, 0); | ||||||
|  | 	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 | void | ||||||
| incnmaster(const Arg *arg) | incnmaster(const Arg *arg) | ||||||
| { | { | ||||||
| @ -1570,6 +1638,20 @@ mapnotify(struct wl_listener *listener, void *data) | |||||||
| 	} | 	} | ||||||
| 	printstatus(); | 	printstatus(); | ||||||
| 
 | 
 | ||||||
|  | 	if (!c->noswallow) { | ||||||
|  | 		Client *cp = termforwin(c); | ||||||
|  | 		if (cp) { | ||||||
|  | 			c->swallowedby = cp; | ||||||
|  | 			cp->swallowing  = c; | ||||||
|  | 			wl_list_remove(&c->link); | ||||||
|  | 			wl_list_remove(&c->flink); | ||||||
|  | 			swallow(c,cp); | ||||||
|  | 			wl_list_remove(&cp->link); | ||||||
|  | 			wl_list_remove(&cp->flink); | ||||||
|  | 			arrange(c->mon); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| unset_fullscreen: | unset_fullscreen: | ||||||
| 	m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); | 	m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); | ||||||
| 	wl_list_for_each(w, &clients, link) | 	wl_list_for_each(w, &clients, link) | ||||||
| @ -2470,6 +2552,18 @@ unmapnotify(struct wl_listener *listener, void *data) | |||||||
| 		grabc = NULL; | 		grabc = NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (c->swallowing) { | ||||||
|  | 		c->swallowing->swallowedby = NULL; | ||||||
|  | 		c->swallowing = NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (c->swallowedby) { | ||||||
|  | 		setfullscreen(c->swallowedby, 0); | ||||||
|  | 		swallow(c->swallowedby, c); | ||||||
|  | 		c->swallowedby->swallowing = NULL; | ||||||
|  | 		c->swallowedby = NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (client_is_unmanaged(c)) { | 	if (client_is_unmanaged(c)) { | ||||||
| 		if (c == exclusive_focus) | 		if (c == exclusive_focus) | ||||||
| 			exclusive_focus = NULL; | 			exclusive_focus = NULL; | ||||||
|  | |||||||
							
								
								
									
										197
									
								
								patches/swallow.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								patches/swallow.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | |||||||
|  | From bc61a2cc74f65ab5bba51ba65edc1efd1269d510 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dmitry Zakharchenko <dmitz@disroot.org> | ||||||
|  | Date: Thu, 5 Jan 2023 14:57:48 +0200 | ||||||
|  | Subject: [PATCH] swallow: sync with 0.4 | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  config.def.h |   6 ++-- | ||||||
|  |  dwl.c        | 100 +++++++++++++++++++++++++++++++++++++++++++++++++-- | ||||||
|  |  2 files changed, 100 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/config.def.h b/config.def.h
 | ||||||
|  | index a4f7c13d..9dcedacd 100644
 | ||||||
|  | --- a/config.def.h
 | ||||||
|  | +++ b/config.def.h
 | ||||||
|  | @@ -12,11 +12,11 @@ static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0};
 | ||||||
|  |  static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | ||||||
|  |   | ||||||
|  |  static const Rule rules[] = { | ||||||
|  | -	/* app_id     title       tags mask     isfloating   monitor */
 | ||||||
|  | +	/* app_id     title       tags mask     isfloating  isterm  noswallow  monitor */
 | ||||||
|  |  	/* examples: | ||||||
|  | -	{ "Gimp",     NULL,       0,            1,           -1 },
 | ||||||
|  | +	{ "Gimp",     NULL,       0,            1,          0,      1,         -1 },
 | ||||||
|  |  	*/ | ||||||
|  | -	{ "firefox",  NULL,       1 << 8,       0,           -1 },
 | ||||||
|  | +	{ "firefox",  NULL,       1 << 8,       0,          0,      1,         -1 },
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* layout(s) */ | ||||||
|  | diff --git a/dwl.c b/dwl.c
 | ||||||
|  | index 19bb6ce3..262fa62c 100644
 | ||||||
|  | --- a/dwl.c
 | ||||||
|  | +++ b/dwl.c
 | ||||||
|  | @@ -95,7 +95,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 */ | ||||||
|  | @@ -124,9 +125,11 @@ typedef struct {
 | ||||||
|  |  #endif | ||||||
|  |  	unsigned int bw; | ||||||
|  |  	unsigned int 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; | ||||||
|  | @@ -201,6 +204,8 @@ typedef struct {
 | ||||||
|  |  	const char *title; | ||||||
|  |  	unsigned int tags; | ||||||
|  |  	int isfloating; | ||||||
|  | +	int isterm;
 | ||||||
|  | +	int noswallow;
 | ||||||
|  |  	int monitor; | ||||||
|  |  } Rule; | ||||||
|  |   | ||||||
|  | @@ -310,6 +315,10 @@ static Monitor *xytomon(double x, double y);
 | ||||||
|  |  static struct wlr_scene_node *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"; | ||||||
|  | @@ -453,6 +462,8 @@ applyrules(Client *c)
 | ||||||
|  |  		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) | ||||||
|  | @@ -990,6 +1001,8 @@ createnotify(struct wl_listener *listener, void *data)
 | ||||||
|  |  	c->surface.xdg = xdg_surface; | ||||||
|  |  	c->bw = borderpx; | ||||||
|  |   | ||||||
|  | +	wl_client_get_credentials(c->surface.xdg->client->client, &c->pid, NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  |  	LISTEN(&xdg_surface->events.map, &c->map, mapnotify); | ||||||
|  |  	LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify); | ||||||
|  |  	LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); | ||||||
|  | @@ -1308,6 +1321,61 @@ fullscreennotify(struct wl_listener *listener, void *data)
 | ||||||
|  |  	setfullscreen(c, client_wants_fullscreen(c)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +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, &clients, link)
 | ||||||
|  | +		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;
 | ||||||
|  | +	resize(c, w->geom, 0);
 | ||||||
|  | +	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) | ||||||
|  |  { | ||||||
|  | @@ -1528,6 +1596,20 @@ mapnotify(struct wl_listener *listener, void *data)
 | ||||||
|  |  	} | ||||||
|  |  	printstatus(); | ||||||
|  |   | ||||||
|  | +	if (!c->noswallow) {
 | ||||||
|  | +		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);
 | ||||||
|  | +			arrange(c->mon);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  unset_fullscreen: | ||||||
|  |  	m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); | ||||||
|  |  	wl_list_for_each(w, &clients, link) | ||||||
|  | @@ -2409,6 +2491,18 @@ unmapnotify(struct wl_listener *listener, void *data)
 | ||||||
|  |  		grabc = NULL; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (c->swallowing) {
 | ||||||
|  | +		c->swallowing->swallowedby = NULL;
 | ||||||
|  | +		c->swallowing = NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (c->swallowedby) {
 | ||||||
|  | +		setfullscreen(c->swallowedby, 0);
 | ||||||
|  | +		swallow(c->swallowedby, c);
 | ||||||
|  | +		c->swallowedby->swallowing = NULL;
 | ||||||
|  | +		c->swallowedby = NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (client_is_unmanaged(c)) { | ||||||
|  |  		if (c == exclusive_focus) | ||||||
|  |  			exclusive_focus = NULL; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Micah Gorrell
						Micah Gorrell