From 0dc34efe899c9e6dca6eb8770f3dedd2afe5ee83 Mon Sep 17 00:00:00 2001 From: wochap 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 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 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 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 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 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 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