~ruther/dwl

122005a93200e35bca7e41fe55c7844bff2e1c59 — Rutherther 11 months ago 3128a18 + 84d4d33
Merge branch 'patch/namedscratchpads' into patched
4 files changed, 841 insertions(+), 5 deletions(-)

M config.def.h
M dwl.c
A namedscratchpads-diff.patch
A namedscratchpads.patch
M config.def.h => config.def.h +12 -5
@@ 21,10 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 */
	/* 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" */
	/* app_id     title       tags mask     isfloating   monitor scratchkey */
	/* examples:
	{ "Gimp",     NULL,       0,            1,           -1 },
	*/
	{ "firefox",  NULL,       1 << 8,       0,           -1,      0  },
	{ NULL,     "scratchpad", 0,            1,           -1,     's' },
};

/* layout(s) */


@@ 119,12 121,17 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
static const char *termcmd[] = { "foot", 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_b,          togglebar,      {0} },
	{ MODKEY,                    XKB_KEY_grave,      togglescratch,  {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglescratch, {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglematchingscratch, {.v = scratchpadcmd } },
	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} },

M dwl.c => dwl.c +134 -0
@@ 141,6 141,7 @@ typedef struct {
	uint32_t tags;
	int isfloating, isurgent, isfullscreen;
	uint32_t resize; /* configure serial of a pending resize */
	char scratchkey;
} Client;

typedef struct {


@@ 237,6 238,7 @@ typedef struct {
	uint32_t tags;
	int isfloating;
	int monitor;
	const char scratchkey;
} Rule;

typedef struct {


@@ 348,6 350,7 @@ static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
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);


@@ 356,6 359,9 @@ static void tile(Monitor *m);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void togglescratch(const Arg *arg);
static void focusortogglescratch(const Arg *arg);
static void focusortogglematchingscratch(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);


@@ 480,6 486,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)))


@@ 489,6 496,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) {


@@ 2751,6 2759,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)
{


@@ 2851,6 2869,122 @@ togglefullscreen(const Arg *arg)
}

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(c->tags == 0 ? focustop(selmon) : c, 1);
		arrange(selmon);
	} else{
		spawnscratch(arg);
	}
}

void
focusortogglescratch(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) {
		if (VISIBLEON(c, selmon)) {
			if (focustop(selmon) == c) {
				// hide
				c->tags = 0;
				focusclient(focustop(selmon), 1);
			} else {
				// focus
				focusclient(c, 1);
			}
		} else {
			// show
			if (c->mon == selmon) {
				c->tags = selmon->tagset[selmon->seltags];
			} else {
				setmon(c, selmon, 0);
			}
			focusclient(c, 1);
		}
		arrange(selmon);
	} else{
		spawnscratch(arg);
	}
}

void
focusortogglematchingscratch(const Arg *arg)
{
	Client *c;
	unsigned int found = 0;
	unsigned int hide = 0;

	wl_list_for_each(c, &clients, link) {
		if (c->scratchkey == 0) {
			continue;
		}
		if (c->scratchkey == ((char**)arg->v)[0][0]) {
			if (VISIBLEON(c, selmon)) {
				if (found == 1) {
					if (hide == 1) {
						c->tags = 0;
						focusclient(focustop(selmon), 1);
					}
					continue;
				}
				if (focustop(selmon) == c) {
					// hide
					c->tags = 0;
					focusclient(focustop(selmon), 1);
					hide = 1;
				} else {
					// focus
					focusclient(c, 1);
				}
			} else {
				// show
				if (c->mon == selmon) {
					c->tags = selmon->tagset[selmon->seltags];
				} else {
					setmon(c, selmon, 0);
				}
				// focus
				focusclient(c, 1);
			}
			found = 1;
			continue;
		}
		if (VISIBLEON(c, selmon)) {
			// hide
			c->tags = 0;
		}
	}

	if (found) {
		arrange(selmon);
	} else {
		spawnscratch(arg);
	}
}

void
toggletag(const Arg *arg)
{
	uint32_t newtags;

A namedscratchpads-diff.patch => namedscratchpads-diff.patch +230 -0
@@ 0,0 1,230 @@
diff --git a/config.def.h b/config.def.h
index db0babc..3205165 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,11 +20,12 @@ static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0}; /* You can al
 static int log_level = WLR_ERROR;
 
 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) */
@@ -115,11 +116,17 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 static const char *termcmd[] = { "foot", 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_grave,      focusortogglescratch, {.v = scratchpadcmd } },
+	// { MODKEY,                    XKB_KEY_grave,      focusortogglematchingscratch, {.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 ef27a1d..4786f12 100644
--- a/dwl.c
+++ b/dwl.c
@@ -130,6 +130,7 @@ typedef struct {
 	uint32_t tags;
 	int isfloating, isurgent, isfullscreen;
 	uint32_t resize; /* configure serial of a pending resize */
+	char scratchkey;
 } Client;
 
 typedef struct {
@@ -215,6 +216,7 @@ typedef struct {
 	uint32_t tags;
 	int isfloating;
 	int monitor;
+	const char scratchkey;
 } Rule;
 
 typedef struct {
@@ -307,12 +309,16 @@ static void setpsel(struct wl_listener *listener, void *data);
 static void setsel(struct wl_listener *listener, void *data);
 static void setup(void);
 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 focusortogglescratch(const Arg *arg);
+static void focusortogglematchingscratch(const Arg *arg);
 static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unlocksession(struct wl_listener *listener, void *data);
@@ -424,6 +430,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)))
@@ -433,6 +440,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)
@@ -2372,6 +2380,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)
 {
@@ -2454,6 +2472,122 @@ 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(c->tags == 0 ? focustop(selmon) : c, 1);
+		arrange(selmon);
+	} else{
+		spawnscratch(arg);
+	}
+}
+
+void
+focusortogglescratch(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) {
+		if (VISIBLEON(c, selmon)) {
+			if (focustop(selmon) == c) {
+				// hide
+				c->tags = 0;
+				focusclient(focustop(selmon), 1);
+			} else {
+				// focus
+				focusclient(c, 1);
+			}
+		} else {
+			// show
+			if (c->mon == selmon) {
+				c->tags = selmon->tagset[selmon->seltags];
+			} else {
+				setmon(c, selmon, 0);
+			}
+			focusclient(c, 1);
+		}
+		arrange(selmon);
+	} else{
+		spawnscratch(arg);
+	}
+}
+
+void
+focusortogglematchingscratch(const Arg *arg)
+{
+	Client *c;
+	unsigned int found = 0;
+	unsigned int hide = 0;
+
+	wl_list_for_each(c, &clients, link) {
+		if (c->scratchkey == 0) {
+			continue;
+		}
+		if (c->scratchkey == ((char**)arg->v)[0][0]) {
+			if (VISIBLEON(c, selmon)) {
+				if (found == 1) {
+					if (hide == 1) {
+						c->tags = 0;
+						focusclient(focustop(selmon), 1);
+					}
+					continue;
+				}
+				if (focustop(selmon) == c) {
+					// hide
+					c->tags = 0;
+					focusclient(focustop(selmon), 1);
+					hide = 1;
+				} else {
+					// focus
+					focusclient(c, 1);
+				}
+			} else {
+				// show
+				if (c->mon == selmon) {
+					c->tags = selmon->tagset[selmon->seltags];
+				} else {
+					setmon(c, selmon, 0);
+				}
+				// focus
+				focusclient(c, 1);
+			}
+			found = 1;
+			continue;
+		}
+		if (VISIBLEON(c, selmon)) {
+			// hide
+			c->tags = 0;
+		}
+	}
+
+	if (found) {
+		arrange(selmon);
+	} else {
+		spawnscratch(arg);
+	}
+}
+
 void
 toggletag(const Arg *arg)
 {

A namedscratchpads.patch => namedscratchpads.patch +465 -0
@@ 0,0 1,465 @@
From 0dc34efe899c9e6dca6eb8770f3dedd2afe5ee83 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 22 Nov 2023 18:55:15 -0500
Subject: [PATCH 1/7] apply main...loumray:namedscratchpads.patch

---
 config.def.h |  9 +++++++--
 dwl.c        | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/config.def.h b/config.def.h
index db0babc..157aee4 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,11 +20,12 @@ static const float fullscreen_bg[]         = {0.1, 0.1, 0.1, 1.0}; /* You can al
 static int log_level = WLR_ERROR;
 
 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) */
@@ -115,11 +116,15 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 static const char *termcmd[] = { "foot", 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 ef27a1d..81e5db8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -130,6 +130,7 @@ typedef struct {
 	uint32_t tags;
 	int isfloating, isurgent, isfullscreen;
 	uint32_t resize; /* configure serial of a pending resize */
+	char scratchkey;
 } Client;
 
 typedef struct {
@@ -215,6 +216,7 @@ typedef struct {
 	uint32_t tags;
 	int isfloating;
 	int monitor;
+	const char scratchkey;
 } Rule;
 
 typedef struct {
@@ -307,12 +309,14 @@ static void setpsel(struct wl_listener *listener, void *data);
 static void setsel(struct wl_listener *listener, void *data);
 static void setup(void);
 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 unlocksession(struct wl_listener *listener, void *data);
@@ -424,6 +428,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)))
@@ -433,6 +438,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)
@@ -2372,6 +2378,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)
 {
@@ -2454,6 +2470,29 @@ 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(c->tags == 0 ? focustop(selmon) : c, 1);
+		arrange(selmon);
+	} else{
+		spawnscratch(arg);
+	}
+}
+
 void
 toggletag(const Arg *arg)
 {
-- 
2.43.2


From e750aa243a25ec78e611883b5e72314067326746 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 22 Nov 2023 18:58:57 -0500
Subject: [PATCH 2/7] add focusortogglescratch function

---
 config.def.h |  1 +
 dwl.c        | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/config.def.h b/config.def.h
index 157aee4..0f672d4 100644
--- a/config.def.h
+++ b/config.def.h
@@ -125,6 +125,7 @@ static const Key keys[] = {
 	{ 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|WLR_MODIFIER_SHIFT, XKB_KEY_grave,      focusortogglescratch, {.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 81e5db8..83d771e 100644
--- a/dwl.c
+++ b/dwl.c
@@ -317,6 +317,7 @@ 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 focusortogglescratch(const Arg *arg);
 static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unlocksession(struct wl_listener *listener, void *data);
@@ -2493,6 +2494,42 @@ togglescratch(const Arg *arg)
 	}
 }
 
+void
+focusortogglescratch(const Arg *arg)
+{
+	Client *c;
+	Client *cwithfocus;
+	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) {
+		if (VISIBLEON(c, selmon)) {
+			cwithfocus = focustop(selmon);
+			if (cwithfocus == c) {
+				// hide
+				c->tags = 0;
+				focusclient(cwithfocus, 1);
+			} else {
+				// focus
+				focusclient(c, 1);
+			}
+		} else {
+			// show
+			c->tags = selmon->tagset[selmon->seltags];
+			focusclient(c, 1);
+		}
+		arrange(selmon);
+	} else{
+		spawnscratch(arg);
+	}
+}
+
 void
 toggletag(const Arg *arg)
 {
-- 
2.43.2


From 5ee62daed7e4fb60d09ba72793bf872307697203 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 22 Nov 2023 20:42:20 -0500
Subject: [PATCH 3/7] fix focus after hiding

---
 dwl.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/dwl.c b/dwl.c
index 83d771e..6b5d55d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2498,7 +2498,6 @@ void
 focusortogglescratch(const Arg *arg)
 {
 	Client *c;
-	Client *cwithfocus;
 	unsigned int found = 0;
 
 	/* search for first window that matches the scratchkey */
@@ -2510,11 +2509,10 @@ focusortogglescratch(const Arg *arg)
 
 	if (found) {
 		if (VISIBLEON(c, selmon)) {
-			cwithfocus = focustop(selmon);
-			if (cwithfocus == c) {
+			if (focustop(selmon) == c) {
 				// hide
 				c->tags = 0;
-				focusclient(cwithfocus, 1);
+				focusclient(focustop(selmon), 1);
 			} else {
 				// focus
 				focusclient(c, 1);
-- 
2.43.2


From 0b3d70706a0aca6d4414d20a3f2ac4928e70d04e Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 6 Mar 2024 14:36:48 -0500
Subject: [PATCH 4/7] add focusortogglematchingscratch

works like focusortoggle but it also hides all others scratchpads
---
 dwl.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/dwl.c b/dwl.c
index 6b5d55d..e179940 100644
--- a/dwl.c
+++ b/dwl.c
@@ -318,6 +318,7 @@ static void togglefloating(const Arg *arg);
 static void togglefullscreen(const Arg *arg);
 static void togglescratch(const Arg *arg);
 static void focusortogglescratch(const Arg *arg);
+static void focusortogglematchingscratch(const Arg *arg);
 static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unlocksession(struct wl_listener *listener, void *data);
@@ -2528,6 +2529,48 @@ focusortogglescratch(const Arg *arg)
 	}
 }
 
+void
+focusortogglematchingscratch(const Arg *arg)
+{
+	Client *c;
+	unsigned int found = 0;
+
+	wl_list_for_each(c, &clients, link) {
+		if (c->scratchkey == 0) {
+			continue;
+		}
+		if (c->scratchkey == ((char**)arg->v)[0][0]) {
+			found = 1;
+			if (VISIBLEON(c, selmon)) {
+				if (focustop(selmon) == c) {
+					// hide
+					c->tags = 0;
+					focusclient(focustop(selmon), 1);
+				} else {
+					// focus
+					focusclient(c, 1);
+				}
+			} else {
+				// show
+				c->tags = selmon->tagset[selmon->seltags];
+				// focus
+				focusclient(c, 1);
+			}
+			continue;
+		}
+		if (VISIBLEON(c, selmon)) {
+			// hide
+			c->tags = 0;
+		}
+	}
+
+	if (found) {
+		arrange(selmon);
+	} else {
+		spawnscratch(arg);
+	}
+}
+
 void
 toggletag(const Arg *arg)
 {
-- 
2.43.2


From a14d6da36f1a77cd73daf751828224dd407e78f9 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 6 Mar 2024 15:20:45 -0500
Subject: [PATCH 5/7] fix: edge case where there are more than 1 window with
 the same scratchkey

---
 dwl.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index e179940..4c40f86 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2534,18 +2534,26 @@ focusortogglematchingscratch(const Arg *arg)
 {
 	Client *c;
 	unsigned int found = 0;
+	unsigned int hide = 0;
 
 	wl_list_for_each(c, &clients, link) {
 		if (c->scratchkey == 0) {
 			continue;
 		}
 		if (c->scratchkey == ((char**)arg->v)[0][0]) {
-			found = 1;
 			if (VISIBLEON(c, selmon)) {
+				if (found == 1) {
+					if (hide == 1) {
+						c->tags = 0;
+						focusclient(focustop(selmon), 1);
+					}
+					continue;
+				}
 				if (focustop(selmon) == c) {
 					// hide
 					c->tags = 0;
 					focusclient(focustop(selmon), 1);
+					hide = 1;
 				} else {
 					// focus
 					focusclient(c, 1);
@@ -2556,6 +2564,7 @@ focusortogglematchingscratch(const Arg *arg)
 				// focus
 				focusclient(c, 1);
 			}
+			found = 1;
 			continue;
 		}
 		if (VISIBLEON(c, selmon)) {
-- 
2.43.2


From 8d86b275615f4f6242828d2ce4606380ba309c58 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 6 Mar 2024 15:22:24 -0500
Subject: [PATCH 6/7] add examples

---
 config.def.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/config.def.h b/config.def.h
index 0f672d4..3205165 100644
--- a/config.def.h
+++ b/config.def.h
@@ -125,7 +125,8 @@ static const Key keys[] = {
 	{ 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|WLR_MODIFIER_SHIFT, XKB_KEY_grave,      focusortogglescratch, {.v = scratchpadcmd } },
+	// { MODKEY,                    XKB_KEY_grave,      focusortogglescratch, {.v = scratchpadcmd } },
+	// { MODKEY,                    XKB_KEY_grave,      focusortogglematchingscratch, {.v = scratchpadcmd } },
 	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
 	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
 	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} },
-- 
2.43.2


From 3787e1d356af7f59f6f096e2125233ab29617862 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Mon, 8 Apr 2024 16:36:56 -0500
Subject: [PATCH 7/7] fix: move window to focused monitor if necessary

---
 dwl.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 4c40f86..4786f12 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2520,7 +2520,11 @@ focusortogglescratch(const Arg *arg)
 			}
 		} else {
 			// show
-			c->tags = selmon->tagset[selmon->seltags];
+			if (c->mon == selmon) {
+				c->tags = selmon->tagset[selmon->seltags];
+			} else {
+				setmon(c, selmon, 0);
+			}
 			focusclient(c, 1);
 		}
 		arrange(selmon);
@@ -2560,7 +2564,11 @@ focusortogglematchingscratch(const Arg *arg)
 				}
 			} else {
 				// show
-				c->tags = selmon->tagset[selmon->seltags];
+				if (c->mon == selmon) {
+					c->tags = selmon->tagset[selmon->seltags];
+				} else {
+					setmon(c, selmon, 0);
+				}
 				// focus
 				focusclient(c, 1);
 			}
-- 
2.43.2


Do not follow this link