~ruther/dwl

48b1d2b1c6404e47960958663a66102a96bb85af — choc 1 year, 6 months ago 8006e79 patch/swallow
swallow patch with x support

fixed to work after commit 985417b
4 files changed, 126 insertions(+), 10 deletions(-)

M client.h
M config.def.h
M config.mk
M dwl.c
M client.h => client.h +12 -0
@@ 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)
{

M config.def.h => config.def.h +4 -3
@@ 21,11 21,12 @@ static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;

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 },
	{ "foot",     NULL,       0,            0,          1,      1,         -1 },
};

/* layout(s) */

M config.mk => config.mk +2 -2
@@ 11,5 11,5 @@ DATADIR = $(PREFIX)/share
XWAYLAND =
XLIBS =
# Uncomment to build XWayland support
#XWAYLAND = -DXWAYLAND
#XLIBS = xcb xcb-icccm
XWAYLAND = -DXWAYLAND
XLIBS = xcb xcb-icccm

M dwl.c => dwl.c +108 -5
@@ 99,7 99,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 */


@@ 134,9 135,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;


@@ 219,6 222,8 @@ typedef struct {
	const char *title;
	uint32_t tags;
	int isfloating;
	int isterm;
	int noswallow;
	int monitor;
} Rule;



@@ 334,6 339,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";


@@ 441,10 450,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) {


@@ 453,6 466,21 @@ applyrules(Client *c)
			}
		}
	}
	wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
	if (!c->noswallow && !client_is_float_type(c)) {
		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);
}



@@ 1320,6 1348,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)
{


@@ 2574,15 2659,33 @@ 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);

Do not follow this link