From fd64a18e6f0e5e18126229a9a22d61c4001b4878 Mon Sep 17 00:00:00 2001 From: nshan651 Date: Fri, 19 Jun 2026 15:21:24 -0500 Subject: [PATCH] namedscratchpads: update for v0.8 dwl. --- patches/namedscratchpads/README.md | 3 +- .../namedscratchpads-0.8.patch | 277 ++++++++++++++++++ 2 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 patches/namedscratchpads/namedscratchpads-0.8.patch diff --git a/patches/namedscratchpads/README.md b/patches/namedscratchpads/README.md index e436583..e6b3ff2 100644 --- a/patches/namedscratchpads/README.md +++ b/patches/namedscratchpads/README.md @@ -10,10 +10,11 @@ This patch adds the following functions: If you don't assign keybindings to any of the above functions and so get a compiler warning about them not being used, just remove them from your dwl branch to stop the warning. ### Download -- [git branch (v0.6)](https://codeberg.org/bencc/dwl/src/branch/namedscratchpads) - [2024-07-13 (v0.6)](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads.patch) +- [namedscratchpads-0.8.patch](/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads-0.8.patch) ### Authors +- [nshan651](https://codeberg.org/nshan651) - [Ben Collerson](https://codeberg.org/bencc) - [wochap](https://codeberg.org/wochap) - [Louis-Michel Raynauld](https://github.com/loumray) diff --git a/patches/namedscratchpads/namedscratchpads-0.8.patch b/patches/namedscratchpads/namedscratchpads-0.8.patch new file mode 100644 index 0000000..b457512 --- /dev/null +++ b/patches/namedscratchpads/namedscratchpads-0.8.patch @@ -0,0 +1,277 @@ +From 40ef197886f402c44a5a5c6856478cad5277e0bb Mon Sep 17 00:00:00 2001 +From: nshan651 +Date: Fri, 19 Jun 2026 13:04:21 -0500 +Subject: [PATCH 1/2] namedscratchpads: v0.8 compatibility + +--- + config.def.h | 11 ++++++++--- + dwl.c | 39 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 47 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 8a6eda0..79b4efb 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -21,9 +21,10 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca + static int log_level = WLR_ERROR; + + static const Rule rules[] = { +- /* app_id title tags mask isfloating monitor */ +- { "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 */ ++ { "Gimp_EXAMPLE", NULL, 0, 1, -1, 0 }, /* Start on currently visible tags floating, not tiled */ ++ { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1, 0 }, /* Start on ONLY tag "9" */ ++ { NULL, "scratchpad", 0, 1, -1, 's' }, + /* default/example rule: can be changed but cannot be eliminated; at least one rule must exist */ + }; + +@@ -118,11 +119,15 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA + static const char *termcmd[] = { "foot", NULL }; + static const char *menucmd[] = { "wmenu-run", NULL }; + ++/* named scratchpads - First arg only serves to match against key in rules*/ ++static const char *scratchpadcmd[] = { "s", "foot", "-T", "scratchpad", NULL }; ++ + static const Key keys[] = { + /* Note that Shift changes certain key codes: 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 44f3ad9..3e3db4c 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -138,6 +138,7 @@ typedef struct { + unsigned int bw; + uint32_t tags; + int isfloating, isurgent, isfullscreen; ++ char scratchkey; + uint32_t resize; /* configure serial of a pending resize */ + } Client; + +@@ -228,6 +229,7 @@ typedef struct { + uint32_t tags; + int isfloating; + int monitor; ++ const char scratchkey; + } Rule; + + typedef struct { +@@ -330,12 +332,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); +@@ -483,6 +487,7 @@ applyrules(Client *c) + const Rule *r; + Monitor *mon = selmon, *m; + ++ c->scratchkey = 0; + appid = client_get_appid(c); + title = client_get_title(c); + +@@ -490,6 +495,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) { +@@ -2677,6 +2683,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) + { +@@ -2760,6 +2776,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.52.0 + + +From e21146a0924c5940c7fb912d0c99790e2553b613 Mon Sep 17 00:00:00 2001 +From: nshan651 +Date: Fri, 19 Jun 2026 13:05:33 -0500 +Subject: [PATCH 2/2] namedscratchpads: focusortoggle functions v0.8 + +--- + config.def.h | 2 ++ + dwl.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 89 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 79b4efb..e253862 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -128,6 +128,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, 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 3e3db4c..0f406d9 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -286,6 +286,8 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data); + static Monitor *dirtomon(enum wlr_direction dir); + static void focusclient(Client *c, int lift); + static void focusmon(const Arg *arg); ++static void focusortogglematchingscratch(const Arg *arg); ++static void focusortogglescratch(const Arg *arg); + static void focusstack(const Arg *arg); + static Client *focustop(Monitor *m); + static void fullscreennotify(struct wl_listener *listener, void *data); +@@ -1491,6 +1493,91 @@ focusmon(const Arg *arg) + focusclient(focustop(selmon), 1); + } + ++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 ++ c->tags = selmon->tagset[selmon->seltags]; ++ // focus ++ focusclient(c, 1); ++ } ++ found = 1; ++ continue; ++ } ++ if (VISIBLEON(c, selmon)) { ++ // hide ++ c->tags = 0; ++ } ++ } ++ ++ if (found) { ++ 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 ++ c->tags = selmon->tagset[selmon->seltags]; ++ focusclient(c, 1); ++ } ++ arrange(selmon); ++ } else{ ++ spawnscratch(arg); ++ } ++} ++ + void + focusstack(const Arg *arg) + { +-- +2.52.0 +