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