diff options
Diffstat (limited to 'patches')
| -rw-r--r-- | patches/dwl-alwayscenter.diff | 23 | ||||
| -rw-r--r-- | patches/dwl-autostart.diff | 132 | ||||
| -rw-r--r-- | patches/dwl-cursorwarp.diff | 145 | ||||
| -rw-r--r-- | patches/dwl-namedscratchpads.diff | 176 | ||||
| -rw-r--r-- | patches/dwl-push.diff | 129 | ||||
| -rw-r--r-- | patches/dwl-smartborders.diff | 164 | ||||
| -rw-r--r-- | patches/dwl-swallow.diff | 194 | 
7 files changed, 963 insertions, 0 deletions
| diff --git a/patches/dwl-alwayscenter.diff b/patches/dwl-alwayscenter.diff new file mode 100644 index 0000000..24e52ba --- /dev/null +++ b/patches/dwl-alwayscenter.diff @@ -0,0 +1,23 @@ +From 9173fdaf0d1eb853ff194ea11767ac15a0d13560 Mon Sep 17 00:00:00 2001 +From: Guido Cella <guido@guidocella.xyz> +Date: Sat, 17 Apr 2021 08:59:55 +0200 +Subject: [PATCH] Center floating windows + +Credits to Benjamin Chausse for fixing this with multiple monitors. +--- + dwl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dwl.c b/dwl.c +index 22287fb3..80c16459 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -467,6 +467,8 @@ applyrules(Client *c) + 					mon = m; + 		} + 	} ++	c->geom.x = (mon->w.width - c->geom.width) / 2 + mon->m.x; ++	c->geom.y = (mon->w.height - c->geom.height) / 2 + mon->m.y; + 	wlr_scene_node_reparent(c->scene, layers[c->isfloating ? LyrFloat : LyrTile]); + 	setmon(c, mon, newtags); + } diff --git a/patches/dwl-autostart.diff b/patches/dwl-autostart.diff new file mode 100644 index 0000000..1bccc40 --- /dev/null +++ b/patches/dwl-autostart.diff @@ -0,0 +1,132 @@ +From 744a6ce137f30b4b4ab9271bfb5ea5b1ccf4423c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= + <leohdz172@protonmail.com> +Date: Wed, 9 Feb 2022 07:02:47 -0600 +Subject: [PATCH] apply autostart patch from dwm + +https://dwm.suckless.org/patches/cool_autostart/ +--- + config.def.h |  6 ++++++ + dwl.c        | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 58 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 29c6dbf8..35372a68 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -86,6 +86,12 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; + static const double accel_speed = 0.0; +  ++/* Autostart */ ++static const char *const autostart[] = { ++        "sh", "-c", "swaybg --image /xap/local/background", NULL, ++        NULL /* terminate */ ++}; ++ + /* If you want to use the windows key change this to WLR_MODIFIER_LOGO */ + #define MODKEY WLR_MODIFIER_ALT + #define TAGKEYS(KEY,SKEY,TAG) \ +diff --git a/dwl.c b/dwl.c +index 40ea05a6..514ec4b0 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -213,6 +213,7 @@ static void arrange(Monitor *m); + static void arrangelayer(Monitor *m, struct wl_list *list, + 		struct wlr_box *usable_area, int exclusive); + static void arrangelayers(Monitor *m); ++static void autostartexec(void); + static void axisnotify(struct wl_listener *listener, void *data); + static void buttonpress(struct wl_listener *listener, void *data); + static void chvt(const Arg *arg); +@@ -379,6 +380,9 @@ static Atom netatom[NetLast]; + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; +  ++static pid_t *autostart_pids; ++static size_t autostart_len; ++ + /* function implementations */ + void + applybounds(Client *c, struct wlr_box *bbox) +@@ -403,6 +407,29 @@ applybounds(Client *c, struct wlr_box *bbox) + 		c->geom.y = bbox->y; + } +  ++void ++autostartexec(void) { ++	const char *const *p; ++	size_t i = 0; ++ ++	/* count entries */ ++	for (p = autostart; *p; autostart_len++, p++) ++		while (*++p); ++ ++	autostart_pids = calloc(autostart_len, sizeof(pid_t)); ++	for (p = autostart; *p; i++, p++) { ++		if ((autostart_pids[i] = fork()) == 0) { ++			setsid(); ++			execvp(*p, (char *const *)p); ++			fprintf(stderr, "dwl: execvp %s\n", *p); ++			perror(" failed"); ++			_exit(EXIT_FAILURE); ++		} ++		/* skip arguments */ ++		while (*++p); ++	} ++} ++ + void + applyexclusive(struct wlr_box *usable_area, + 		uint32_t anchor, int32_t exclusive, +@@ -1721,6 +1748,16 @@ printstatus(void) + void + quit(const Arg *arg) + { ++	size_t i; ++ ++	/* kill child processes */ ++	for (i = 0; i < autostart_len; i++) { ++		if (0 < autostart_pids[i]) { ++			kill(autostart_pids[i], SIGTERM); ++			waitpid(autostart_pids[i], NULL, 0); ++		} ++	} ++ + 	wl_display_terminate(dpy); + } +  +@@ -1808,6 +1845,7 @@ run(char *startup_cmd) + 	setenv("WAYLAND_DISPLAY", socket, 1); +  + 	/* Now that the socket exists, run the startup command */ ++	autostartexec(); + 	if (startup_cmd) { + 		int piperw[2]; + 		if (pipe(piperw) < 0) +@@ -2183,11 +2221,24 @@ sigchld(int unused) + 	 * setting our own disposition for SIGCHLD. + 	 */ + 	pid_t pid; ++ + 	if (signal(SIGCHLD, sigchld) == SIG_ERR) + 		die("can't install SIGCHLD handler:"); +-	while (0 < (pid = waitpid(-1, NULL, WNOHANG))) ++	while (0 < (pid = waitpid(-1, NULL, WNOHANG))) { ++		pid_t *p, *lim; + 		if (pid == child_pid) + 			child_pid = -1; ++		if (!(p = autostart_pids)) ++			continue; ++		lim = &p[autostart_len]; ++ ++		for (; p < lim; p++) { ++			if (*p == pid) { ++				*p = -1; ++				break; ++			} ++		} ++	} + } +  + void diff --git a/patches/dwl-cursorwarp.diff b/patches/dwl-cursorwarp.diff new file mode 100644 index 0000000..0c4b320 --- /dev/null +++ b/patches/dwl-cursorwarp.diff @@ -0,0 +1,145 @@ +From 8703fcdeac789425fbea768c3efa30884518e72e Mon Sep 17 00:00:00 2001 +From: Faerryn <alexandre.liao@gmail.com> +Date: Thu, 26 May 2022 23:18:59 -0400 +Subject: [PATCH 1/3] cursor wrap + +--- + dwl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/dwl.c b/dwl.c +index d0f5afc8..7427fa06 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -1107,6 +1107,16 @@ focusclient(Client *c, int lift) + 	struct wlr_keyboard *kb; + 	int i; +  ++	/* Warp cursor to center of client if it is outside */ ++	if (c && (cursor->x < c->geom.x || ++		cursor->x > c->geom.x + c->geom.width || ++		cursor->y < c->geom.y || ++		cursor->y > c->geom.y + c->geom.height)) ++		wlr_cursor_warp_closest( cursor, ++			  NULL, ++			  c->geom.x + c->geom.width / 2.0, ++			  c->geom.y + c->geom.height / 2.0); ++ + 	/* Raise client in stacking order if requested */ + 	if (c && lift) + 		wlr_scene_node_raise_to_top(c->scene); + +From 9cd5b806a96823fc10784a39c86d57156e749d11 Mon Sep 17 00:00:00 2001 +From: Faerryn <alexandre.liao@gmail.com> +Date: Fri, 27 May 2022 14:51:09 -0400 +Subject: [PATCH 2/3] both focusclient and arrange will warp cursor + +--- + dwl.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/dwl.c b/dwl.c +index 7427fa06..2bdcaa56 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -290,6 +290,7 @@ static void updatetitle(struct wl_listener *listener, void *data); + static void urgent(struct wl_listener *listener, void *data); + static void view(const Arg *arg); + static void virtualkeyboard(struct wl_listener *listener, void *data); ++static void warpcursor(const Client *c); + 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); +@@ -489,6 +490,9 @@ arrange(Monitor *m) + 	if (m->lt[m->sellt]->arrange) + 		m->lt[m->sellt]->arrange(m); + 	/* TODO recheck pointer focus here... or in resize()? */ ++	c = selclient(); ++	if (c) ++		warpcursor(c); + } +  + void +@@ -1108,14 +1112,8 @@ focusclient(Client *c, int lift) + 	int i; +  + 	/* Warp cursor to center of client if it is outside */ +-	if (c && (cursor->x < c->geom.x || +-		cursor->x > c->geom.x + c->geom.width || +-		cursor->y < c->geom.y || +-		cursor->y > c->geom.y + c->geom.height)) +-		wlr_cursor_warp_closest( cursor, +-			  NULL, +-			  c->geom.x + c->geom.width / 2.0, +-			  c->geom.y + c->geom.height / 2.0); ++	if (c) ++		warpcursor(c); +  + 	/* Raise client in stacking order if requested */ + 	if (c && lift) +@@ -2375,6 +2373,18 @@ virtualkeyboard(struct wl_listener *listener, void *data) + 	createkeyboard(device); + } +  ++void ++warpcursor(const Client *c) { ++	if (cursor->x < c->geom.x || ++		cursor->x > c->geom.x + c->geom.width || ++		cursor->y < c->geom.y || ++		cursor->y > c->geom.y + c->geom.height) ++		wlr_cursor_warp_closest(cursor, ++			  NULL, ++			  c->geom.x + c->geom.width / 2.0, ++			  c->geom.y + c->geom.height / 2.0); ++} ++ + Monitor * + xytomon(double x, double y) + { + +From 95a8e2c3372b2dc245533001164b1e427751d394 Mon Sep 17 00:00:00 2001 +From: Faerryn <alexandre.liao@gmail.com> +Date: Sat, 28 May 2022 12:35:32 -0400 +Subject: [PATCH 3/3] add an option to config.h for cursor_warp + +--- + config.def.h | 3 +++ + dwl.c        | 4 ++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 4f131dda..f82dd582 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,9 @@ static const float rootcolor[]      = {0.3, 0.3, 0.3, 1.0}; + static const float bordercolor[]    = {0.5, 0.5, 0.5, 1.0}; + static const float focuscolor[]     = {1.0, 0.0, 0.0, 1.0}; +  ++/* cursor warping */ ++static const bool cursor_warp = true; ++ + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +  +diff --git a/dwl.c b/dwl.c +index 2bdcaa56..e593b152 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -491,7 +491,7 @@ arrange(Monitor *m) + 		m->lt[m->sellt]->arrange(m); + 	/* TODO recheck pointer focus here... or in resize()? */ + 	c = selclient(); +-	if (c) ++	if (cursor_warp && c) + 		warpcursor(c); + } +  +@@ -1112,7 +1112,7 @@ focusclient(Client *c, int lift) + 	int i; +  + 	/* Warp cursor to center of client if it is outside */ +-	if (c) ++	if (cursor_warp && c) + 		warpcursor(c); +  + 	/* Raise client in stacking order if requested */ diff --git a/patches/dwl-namedscratchpads.diff b/patches/dwl-namedscratchpads.diff new file mode 100644 index 0000000..a83d322 --- /dev/null +++ b/patches/dwl-namedscratchpads.diff @@ -0,0 +1,176 @@ +From 13402c1ccead7a6775520bd1ceef31611583c965 Mon Sep 17 00:00:00 2001 +From: Louis-Michel Raynauld <louismichel@pweb.ca> +Date: Fri, 29 Jul 2022 23:09:10 -0700 +Subject: [PATCH 1/2] port dwm "namedscratchpads" patch to dwl + +--- + config.def.h |  9 +++++++-- + dwl.c        | 42 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 190b0da4..b5f87336 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,11 +10,12 @@ static const float focuscolor[]     = {1.0, 0.0, 0.0, 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   monitor scratchkey */ + 	/* examples: + 	{ "Gimp",     NULL,       0,            1,           -1 }, + 	*/ +-	{ "firefox",  NULL,       1 << 8,       0,           -1 }, ++	{ "firefox",  NULL,       1 << 8,       0,           -1,      0  }, ++	{ NULL,     "scratchpad", 0,            1,           -1,     's' }, + }; +  + /* layout(s) */ +@@ -66,11 +67,15 @@ static const int natural_scrolling = 0; + static const char *termcmd[] = { "alacritty", NULL }; + static const char *menucmd[] = { "bemenu-run", NULL }; +  ++/* named scratchpads - First arg only serves to match against key in rules*/ ++static const char *scratchpadcmd[] = { "s", "alacritty", "-t", "scratchpad", NULL }; ++ + static const Key keys[] = { + 	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ + 	/* modifier                  key                 function        argument */ + 	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} }, + 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd} }, ++	{ MODKEY,                    XKB_KEY_grave,      togglescratch,  {.v = scratchpadcmd } }, + 	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} }, + 	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} }, + 	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} }, +diff --git a/dwl.c b/dwl.c +index b09fc6f9..f21488c0 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -118,6 +118,7 @@ typedef struct { + 	int isfloating, isurgent; + 	uint32_t resize; /* configure serial of a pending resize */ + 	int isfullscreen; ++	char scratchkey; + } Client; +  + typedef struct { +@@ -198,6 +199,7 @@ typedef struct { + 	unsigned int tags; + 	int isfloating; + 	int monitor; ++	const char scratchkey; + } Rule; +  + /* function declarations */ +@@ -273,12 +275,14 @@ static void setsel(struct wl_listener *listener, void *data); + static void setup(void); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void spawnscratch(const Arg *arg); + static void startdrag(struct wl_listener *listener, void *data); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglefloating(const Arg *arg); + static void togglefullscreen(const Arg *arg); ++static void togglescratch(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unmaplayersurface(LayerSurface *layersurface); +@@ -457,6 +461,7 @@ applyrules(Client *c) + 	Monitor *mon = selmon, *m; +  + 	c->isfloating = client_is_float_type(c); ++	c->scratchkey = 0; + 	if (!(appid = client_get_appid(c))) + 		appid = broken; + 	if (!(title = client_get_title(c))) +@@ -466,6 +471,7 @@ applyrules(Client *c) + 		if ((!r->title || strstr(title, r->title)) + 				&& (!r->id || strstr(appid, r->id))) { + 			c->isfloating = r->isfloating; ++			c->scratchkey = r->scratchkey; + 			newtags |= r->tags; + 			i = 0; + 			wl_list_for_each(m, &mons, link) +@@ -2092,6 +2098,16 @@ spawn(const Arg *arg) + 	} + } +  ++void spawnscratch(const Arg *arg) ++{ ++	if (fork() == 0) { ++		dup2(STDERR_FILENO, STDOUT_FILENO); ++		setsid(); ++		execvp(((char **)arg->v)[1], ((char **)arg->v)+1); ++		die("dwl: execvp %s failed:", ((char **)arg->v)[1]); ++	} ++} ++ + void + startdrag(struct wl_listener *listener, void *data) + { +@@ -2176,6 +2192,32 @@ togglefullscreen(const Arg *arg) + 		setfullscreen(sel, !sel->isfullscreen); + } +  ++void ++togglescratch(const Arg *arg) ++{ ++	Client *c; ++	unsigned int found = 0; ++ ++	/* search for first window that matches the scratchkey */ ++	wl_list_for_each(c, &clients, link) ++		if (c->scratchkey == ((char**)arg->v)[0][0]) { ++			found = 1; ++			break; ++		} ++ ++	if (found) { ++		c->tags = VISIBLEON(c, selmon) ? 0 : selmon->tagset[selmon->seltags]; ++		focusclient(NULL, 0); ++		if (VISIBLEON(c, selmon)) { ++			focusclient(c, 0); ++		} ++		arrange(selmon); ++ ++	} else{ ++		spawnscratch(arg); ++	} ++} ++ + void + toggletag(const Arg *arg) + { + +From be5e75b1bad480a7eedd81ef68cc331687fbe7cd Mon Sep 17 00:00:00 2001 +From: Louis-Michel Raynauld <louismichel@pweb.ca> +Date: Fri, 5 Aug 2022 22:20:59 -0700 +Subject: [PATCH 2/2] Fix focus after hiding and make sure toggle scratchpad + appears on top of others scratchpads if any. + +--- + dwl.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/dwl.c b/dwl.c +index f21488c0..e0ecdb8e 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -2207,12 +2207,9 @@ togglescratch(const Arg *arg) +  + 	if (found) { + 		c->tags = VISIBLEON(c, selmon) ? 0 : selmon->tagset[selmon->seltags]; +-		focusclient(NULL, 0); +-		if (VISIBLEON(c, selmon)) { +-			focusclient(c, 0); +-		} +-		arrange(selmon); +  ++		focusclient(c->tags == 0 ? focustop(selmon) : c, 1); ++		arrange(selmon); + 	} else{ + 		spawnscratch(arg); + 	} diff --git a/patches/dwl-push.diff b/patches/dwl-push.diff new file mode 100644 index 0000000..06a1532 --- /dev/null +++ b/patches/dwl-push.diff @@ -0,0 +1,129 @@ +From dcb7a4d91075a9d918d082eb948c61d26eb0bc02 Mon Sep 17 00:00:00 2001 +From: "Devin J. Pohly" <djpohly@gmail.com> +Date: Thu, 4 Mar 2021 00:45:50 -0600 +Subject: [PATCH 1/2] port dwm "push" patch to dwl + +--- + Makefile |  2 ++ + dwl.c    |  2 ++ + push.c   | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 67 insertions(+) + create mode 100644 push.c + +diff --git a/Makefile b/Makefile +index a0d1cc37..1701b63e 100644 +--- a/Makefile ++++ b/Makefile +@@ -49,6 +49,8 @@ config.h: | config.def.h +  + dwl.o: config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h +  ++dwl.o: push.c ++ + dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o +  + clean: +diff --git a/dwl.c b/dwl.c +index 72f1046b..4cfd7d07 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -369,7 +369,9 @@ static Atom netatom[NetLast]; + #endif +  + /* configuration, allows nested code to access above variables */ ++#include "push.h" + #include "config.h" ++#include "push.c" +  + /* attempt to encapsulate suck into one file */ + #include "client.h" +diff --git a/push.c b/push.c +new file mode 100644 +index 00000000..26ed462f +--- /dev/null ++++ b/push.c +@@ -0,0 +1,63 @@ ++static Client * ++nexttiled(Client *sel) { ++	Client *c; ++	wl_list_for_each(c, &sel->link, link) { ++		if (&c->link == &clients) ++			break;  /* don't wrap */ ++		if (!c->isfloating && VISIBLEON(c, selmon)) ++			return c; ++	} ++	return NULL; ++} ++ ++static Client * ++prevtiled(Client *sel) { ++	Client *c; ++	wl_list_for_each_reverse(c, &sel->link, link) { ++		if (&c->link == &clients) ++			break;  /* don't wrap */ ++		if (!c->isfloating && VISIBLEON(c, selmon)) ++			return c; ++	} ++	return NULL; ++} ++ ++static void ++pushup(const Arg *arg) { ++	Client *sel = selclient(); ++	Client *c; ++ ++	if(!sel || sel->isfloating) ++		return; ++	if((c = prevtiled(sel))) { ++		/* attach before c */ ++		wl_list_remove(&sel->link); ++		wl_list_insert(c->link.prev, &sel->link); ++	} else { ++		/* move to the end */ ++		wl_list_remove(&sel->link); ++		wl_list_insert(clients.prev, &sel->link); ++	} ++	focusclient(sel, 1); ++	arrange(selmon); ++} ++ ++static void ++pushdown(const Arg *arg) { ++	Client *sel = selclient(); ++	Client *c; ++ ++	if(!sel || sel->isfloating) ++		return; ++	if((c = nexttiled(sel))) { ++		/* attach after c */ ++		wl_list_remove(&sel->link); ++		wl_list_insert(&c->link, &sel->link); ++	} else { ++		/* move to the front */ ++		wl_list_remove(&sel->link); ++		wl_list_insert(&clients, &sel->link); ++	} ++	focusclient(sel, 1); ++	arrange(selmon); ++} + +From 156a13d9f9f9d8df16b184f5ec0c84e6e5b94df6 Mon Sep 17 00:00:00 2001 +From: "Devin J. Pohly" <djpohly@gmail.com> +Date: Thu, 4 Mar 2021 13:52:58 -0600 +Subject: [PATCH 2/2] add missing header + +--- + push.h | 4 ++++ + 1 file changed, 4 insertions(+) + create mode 100644 push.h + +diff --git a/push.h b/push.h +new file mode 100644 +index 00000000..59c0f80e +--- /dev/null ++++ b/push.h +@@ -0,0 +1,4 @@ ++static Client *nexttiled(Client *sel); ++static Client *prevtiled(Client *sel); ++static void pushdown(const Arg *arg); ++static void pushup(const Arg *arg); diff --git a/patches/dwl-smartborders.diff b/patches/dwl-smartborders.diff new file mode 100644 index 0000000..9f21db9 --- /dev/null +++ b/patches/dwl-smartborders.diff @@ -0,0 +1,164 @@ +From 24d23869dc7c27feddf33753946aac02197fdb67 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= + <leohdz172@protonmail.com> +Date: Tue, 16 Aug 2022 15:28:00 -0500 +Subject: [PATCH]  don't draw borders if there is only one window + +Co-authored-by: Andrey Proskurin <andreyproskurin@protonmail.com> +--- + config.def.h |  1 + + dwl.c        | 36 ++++++++++++++++++++++++------------ + 2 files changed, 25 insertions(+), 12 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 29c6dbf8..19632a50 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + static const int sloppyfocus        = 1;  /* focus follows mouse */ + static const unsigned int borderpx  = 1;  /* border pixel of windows */ + static const int lockfullscreen     = 1;  /* 1 will force focus on the fullscreen window */ ++static const int smartborders       = 1; + static const float rootcolor[]      = {0.3, 0.3, 0.3, 1.0}; + static const float bordercolor[]    = {0.5, 0.5, 0.5, 1.0}; + static const float focuscolor[]     = {1.0, 0.0, 0.0, 1.0}; +diff --git a/dwl.c b/dwl.c +index 40ea05a6..8f654f69 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -262,7 +262,7 @@ static void quit(const Arg *arg); + static void quitsignal(int signo); + static void rendermon(struct wl_listener *listener, void *data); + static void requeststartdrag(struct wl_listener *listener, void *data); +-static void resize(Client *c, struct wlr_box geo, int interact); ++static void resize(Client *c, struct wlr_box geo, int interact, int draw_borders); + static void run(char *startup_cmd); + static Client *selclient(void); + static void setcursor(struct wl_listener *listener, void *data); +@@ -754,7 +754,7 @@ closemon(Monitor *m) + 	wl_list_for_each(c, &clients, link) { + 		if (c->isfloating && c->geom.x > m->m.width) + 			resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, +-				.width = c->geom.width, .height = c->geom.height}, 0); ++				.width = c->geom.width, .height = c->geom.height}, 0, 1); + 		if (c->mon == m) + 			setmon(c, selmon, c->tags); + 	} +@@ -1456,7 +1456,7 @@ monocle(Monitor *m) + 	wl_list_for_each(c, &clients, link) { + 		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + 			continue; +-		resize(c, m->w, 0); ++		resize(c, m->w, 0, !smartborders); + 	} + 	focusclient(focustop(m), 1); + } +@@ -1499,11 +1499,11 @@ motionnotify(uint32_t time) + 	if (cursor_mode == CurMove) { + 		/* Move the grabbed client to the new position. */ + 		resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, +-			.width = grabc->geom.width, .height = grabc->geom.height}, 1); ++			.width = grabc->geom.width, .height = grabc->geom.height}, 1, 1); + 		return; + 	} else if (cursor_mode == CurResize) { + 		resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, +-			.width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1); ++			.width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1, 1); + 		return; + 	} +  +@@ -1776,10 +1776,11 @@ requeststartdrag(struct wl_listener *listener, void *data) + } +  + void +-resize(Client *c, struct wlr_box geo, int interact) ++resize(Client *c, struct wlr_box geo, int interact, int draw_borders) + { + 	struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; + 	c->geom = geo; ++	c->bw = draw_borders ? borderpx : 0; + 	applybounds(c, bbox); +  + 	/* Update scene-graph, including borders */ +@@ -1885,6 +1886,8 @@ setfloating(Client *c, int floating) + { + 	c->isfloating = floating; + 	wlr_scene_node_reparent(c->scene, layers[c->isfloating ? LyrFloat : LyrTile]); ++	if (c->isfloating && !c->bw) ++		resize(c, c->mon->m, 0, 1); + 	arrange(c->mon); + 	printstatus(); + } +@@ -1898,7 +1901,7 @@ setfullscreen(Client *c, int fullscreen) +  + 	if (fullscreen) { + 		c->prev = c->geom; +-		resize(c, c->mon->m, 0); ++		resize(c, c->mon->m, 0, 0); + 		/* The xdg-protocol specifies: + 		 * + 		 * If the fullscreened surface is not opaque, the compositor must make +@@ -1916,7 +1919,7 @@ setfullscreen(Client *c, int fullscreen) + 	} else { + 		/* restore previous size instead of arrange for floating windows since + 		 * client positions are set by the user and cannot be recalculated */ +-		resize(c, c->prev, 0); ++		resize(c, c->prev, 0, 1); + 		if (c->fullscreen_bg) { + 			wlr_scene_node_destroy(&c->fullscreen_bg->node); + 			c->fullscreen_bg = NULL; +@@ -1933,6 +1936,12 @@ setlayout(const Arg *arg) + 		selmon->sellt ^= 1; + 	if (arg && arg->v) + 		selmon->lt[selmon->sellt] = (Layout *)arg->v; ++	if (!selmon->lt[selmon->sellt]->arrange) { ++		/* floating layout, draw borders around all clients */ ++		Client *c; ++		wl_list_for_each(c, &clients, link) ++			resize(c, c->mon->m, 0, 1); ++	} + 	/* TODO change layout symbol? */ + 	arrange(selmon); + 	printstatus(); +@@ -1969,7 +1978,7 @@ setmon(Client *c, Monitor *m, unsigned int newtags) + 	} + 	if (m) { + 		/* Make sure window actually overlaps with the monitor */ +-		resize(c, c->geom, 0); ++		resize(c, c->geom, 0, 1); + 		wlr_surface_send_enter(client_surface(c), m->wlr_output); + 		c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ + 		arrange(m); +@@ -2238,7 +2247,7 @@ tagmon(const Arg *arg) + void + tile(Monitor *m) + { +-	unsigned int i, n = 0, mw, my, ty; ++	unsigned int i, n = 0, mw, my, ty, draw_borders = 1; + 	Client *c; +  + 	wl_list_for_each(c, &clients, link) +@@ -2247,6 +2256,9 @@ tile(Monitor *m) + 	if (n == 0) + 		return; +  ++	if (n == smartborders) ++		draw_borders = 0; ++ + 	if (n > m->nmaster) + 		mw = m->nmaster ? m->w.width * m->mfact : 0; + 	else +@@ -2257,11 +2269,11 @@ tile(Monitor *m) + 			continue; + 		if (i < m->nmaster) { + 			resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, +-				.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); ++				.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0, draw_borders); + 			my += c->geom.height; + 		} else { + 			resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, +-				.width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); ++				.width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0, draw_borders); + 			ty += c->geom.height; + 		} + 		i++; diff --git a/patches/dwl-swallow.diff b/patches/dwl-swallow.diff new file mode 100644 index 0000000..8240686 --- /dev/null +++ b/patches/dwl-swallow.diff @@ -0,0 +1,194 @@ +From 17585c99f57856d39fd0d4c489d8bafd103d53f4 Mon Sep 17 00:00:00 2001 +From: Dmitry Zakharchenko <dmitz@disroot.org> +Date: Sun, 28 Aug 2022 11:38:08 +0300 +Subject: [PATCH] update swallow patch + +--- + config.def.h |  6 ++-- + dwl.c        | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 97 insertions(+), 6 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 29c6dbf8..4aa6903b 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 66aea65c..e897a9ff 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -90,7 +90,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 */ +@@ -119,9 +120,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 singular_anchor; +@@ -200,6 +203,8 @@ typedef struct { + 	const char *title; + 	unsigned int tags; + 	int isfloating; ++	int isterm; ++	int noswallow; + 	int monitor; + } Rule; +  +@@ -295,6 +300,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"; +@@ -479,6 +488,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) +@@ -975,6 +986,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); +@@ -1239,6 +1252,61 @@ fullscreennotify(struct wl_listener *listener, void *data) + 	setfullscreen(c, fullscreen); + } +  ++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, 0); ++		wlr_scene_node_set_enabled(c->scene, 1); ++} ++ + void + incnmaster(const Arg *arg) + { +@@ -1430,6 +1498,19 @@ mapnotify(struct wl_listener *listener, void *data) + 		setfullscreen(c, 1); +  + 	c->mon->un_map = 1; ++	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); ++	} + } +  + void +@@ -2322,6 +2403,16 @@ unmapnotify(struct wl_listener *listener, void *data) + 		cursor_mode = CurNormal; + 		grabc = NULL; + 	} ++	if (c->swallowing) { ++			c->swallowing->swallowedby = NULL; ++			c->swallowing = NULL; ++	} ++ ++	if (c->swallowedby) { ++			swallow(c->swallowedby, c); ++			c->swallowedby->swallowing = NULL; ++			c->swallowedby = NULL; ++	} +  + 	if (c->mon) + 		c->mon->un_map = 1; | 
