sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit d049cc1637e48d9bd850f053247ce39d1a4d6314
parent 3e0473b3d7953007409a5f30c899fd3dbb09c0e6
Author: GasparVardanyan <gaspar_pm@proton.me>
Date:   Sun,  1 Sep 2024 22:48:13 +0400

[dwm][patch][namedscratchpads] adopt this patch to work with dwm 6.5

The 'spawnscratch' function failed to launch qutebrowser.
I changed it to look like the 'spawn' function and now qutebrowser
works fine. There was SIGCHLD-related stuff added to the 'spawn'
function recently. I've copied it to 'spawnscratch'.

Diffstat:
Adwm.suckless.org/patches/namedscratchpads/dwm-namedscratchpads-6.5.diff | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/namedscratchpads/dwm-scratchtagwins-6.5.diff | 244+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/namedscratchpads/index.md | 4+++-
3 files changed, 395 insertions(+), 1 deletion(-)

diff --git a/dwm.suckless.org/patches/namedscratchpads/dwm-namedscratchpads-6.5.diff b/dwm.suckless.org/patches/namedscratchpads/dwm-namedscratchpads-6.5.diff @@ -0,0 +1,148 @@ +diff --git a/config.def.h b/config.def.h +index 9efa774..c3e236e 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -26,9 +26,10 @@ static const Rule rules[] = { + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask isfloating monitor scratch key */ ++ { "Gimp", NULL, NULL, 0, 1, -1, 0 }, ++ { "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, ++ { NULL, NULL, "scratchpad", 0, 1, -1, 's' }, + }; + + /* layout(s) */ +@@ -60,10 +61,14 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; + static const char *termcmd[] = { "st", NULL }; + ++/*First arg only serves to match against key in rules*/ ++static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL}; ++ + static const Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, ++ { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, +diff --git a/dwm.c b/dwm.c +index f1d86b2..be6a754 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -93,6 +93,7 @@ struct Client { + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ char scratchkey; + Client *next; + Client *snext; + Monitor *mon; +@@ -139,6 +140,7 @@ typedef struct { + unsigned int tags; + int isfloating; + int monitor; ++ const char scratchkey; + } Rule; + + /* function declarations */ +@@ -206,11 +208,13 @@ static void setup(void); + static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void spawn(const Arg *arg); ++static void spawnscratch(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); ++static void togglescratch(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unfocus(Client *c, int setfocus); +@@ -287,6 +291,7 @@ applyrules(Client *c) + /* rule matching */ + c->isfloating = 0; + c->tags = 0; ++ c->scratchkey = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; +@@ -299,6 +304,7 @@ applyrules(Client *c) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; ++ c->scratchkey = r->scratchkey; + for (m = mons; m && m->num != r->monitor; m = m->next); + if (m) + c->mon = m; +@@ -308,6 +314,7 @@ applyrules(Client *c) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); ++ + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; + } + +@@ -1666,6 +1673,27 @@ spawn(const Arg *arg) + } + } + ++void spawnscratch(const Arg *arg) ++{ ++ struct sigaction sa; ++ ++ if (fork() == 0) { ++ if (dpy) ++ close(ConnectionNumber(dpy)); ++ setsid(); ++ ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = 0; ++ sa.sa_handler = SIG_DFL; ++ sigaction(SIGCHLD, &sa, NULL); ++ ++ execvp(((char **)arg->v)[1], ((char **)arg->v)+1); ++ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); ++ perror(" failed"); ++ exit(EXIT_SUCCESS); ++ } ++} ++ + void + tag(const Arg *arg) + { +@@ -1735,6 +1763,28 @@ togglefloating(const Arg *arg) + arrange(selmon); + } + ++void ++togglescratch(const Arg *arg) ++{ ++ Client *c; ++ unsigned int found = 0; ++ ++ for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); ++ if (found) { ++ c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; ++ focus(NULL); ++ arrange(selmon); ++ ++ if (ISVISIBLE(c)) { ++ focus(c); ++ restack(selmon); ++ } ++ ++ } else{ ++ spawnscratch(arg); ++ } ++} ++ + void + toggletag(const Arg *arg) + { diff --git a/dwm.suckless.org/patches/namedscratchpads/dwm-scratchtagwins-6.5.diff b/dwm.suckless.org/patches/namedscratchpads/dwm-scratchtagwins-6.5.diff @@ -0,0 +1,244 @@ +diff --git a/config.def.h b/config.def.h +index 9efa774..ac40b35 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -21,14 +21,26 @@ static const char *colors[][3] = { + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + ++#include "scratchtagwins.c" ++ + static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask isfloating monitor scratch key */ ++ { "Gimp", NULL, NULL, 0, 1, -1, 0 }, ++ { "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, ++ { NULL, NULL, "scratchpad", 0, 1, -1, 's' }, ++ SCRATCHTAGWIN_RULE (scratchtagwin1, 1), ++ SCRATCHTAGWIN_RULE (scratchtagwin2, 2), ++ SCRATCHTAGWIN_RULE (scratchtagwin3, 3), ++ SCRATCHTAGWIN_RULE (scratchtagwin4, 4), ++ SCRATCHTAGWIN_RULE (scratchtagwin5, 5), ++ SCRATCHTAGWIN_RULE (scratchtagwin6, 6), ++ SCRATCHTAGWIN_RULE (scratchtagwin7, 7), ++ SCRATCHTAGWIN_RULE (scratchtagwin8, 8), ++ SCRATCHTAGWIN_RULE (scratchtagwin9, 9), + }; + + /* layout(s) */ +@@ -60,10 +72,35 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; + static const char *termcmd[] = { "st", NULL }; + ++SCRATCHTAGWIN (scratchtagwin1, 1); ++SCRATCHTAGWIN (scratchtagwin2, 2); ++SCRATCHTAGWIN (scratchtagwin3, 3); ++SCRATCHTAGWIN (scratchtagwin4, 4); ++SCRATCHTAGWIN (scratchtagwin5, 5); ++SCRATCHTAGWIN (scratchtagwin6, 6); ++SCRATCHTAGWIN (scratchtagwin7, 7); ++SCRATCHTAGWIN (scratchtagwin8, 8); ++SCRATCHTAGWIN (scratchtagwin9, 9); ++ ++/*First arg only serves to match against key in rules*/ ++static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL}; ++ + static const Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, ++ { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, ++ SCRATCHTAGWIN_KEY (scratchtagwin1, 1) ++ SCRATCHTAGWIN_KEY (scratchtagwin2, 2) ++ SCRATCHTAGWIN_KEY (scratchtagwin3, 3) ++ SCRATCHTAGWIN_KEY (scratchtagwin4, 4) ++ SCRATCHTAGWIN_KEY (scratchtagwin5, 5) ++ SCRATCHTAGWIN_KEY (scratchtagwin6, 6) ++ SCRATCHTAGWIN_KEY (scratchtagwin7, 7) ++ SCRATCHTAGWIN_KEY (scratchtagwin8, 8) ++ SCRATCHTAGWIN_KEY (scratchtagwin9, 9) ++ { MODKEY|Mod1Mask|ShiftMask, XK_0, makescratchtagwin, {.i = 0} }, ++ { MODKEY|Mod1Mask|ShiftMask, XK_s, makescratchtagwin, {.i = 's'} }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, +diff --git a/dwm.c b/dwm.c +index f1d86b2..be6a754 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -93,6 +93,7 @@ struct Client { + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ char scratchkey; + Client *next; + Client *snext; + Monitor *mon; +@@ -139,6 +140,7 @@ typedef struct { + unsigned int tags; + int isfloating; + int monitor; ++ const char scratchkey; + } Rule; + + /* function declarations */ +@@ -206,11 +208,13 @@ static void setup(void); + static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void spawn(const Arg *arg); ++static void spawnscratch(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); ++static void togglescratch(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unfocus(Client *c, int setfocus); +@@ -287,6 +291,7 @@ applyrules(Client *c) + /* rule matching */ + c->isfloating = 0; + c->tags = 0; ++ c->scratchkey = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; +@@ -299,6 +304,7 @@ applyrules(Client *c) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; ++ c->scratchkey = r->scratchkey; + for (m = mons; m && m->num != r->monitor; m = m->next); + if (m) + c->mon = m; +@@ -308,6 +314,7 @@ applyrules(Client *c) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); ++ + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; + } + +@@ -1666,6 +1673,27 @@ spawn(const Arg *arg) + } + } + ++void spawnscratch(const Arg *arg) ++{ ++ struct sigaction sa; ++ ++ if (fork() == 0) { ++ if (dpy) ++ close(ConnectionNumber(dpy)); ++ setsid(); ++ ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = 0; ++ sa.sa_handler = SIG_DFL; ++ sigaction(SIGCHLD, &sa, NULL); ++ ++ execvp(((char **)arg->v)[1], ((char **)arg->v)+1); ++ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); ++ perror(" failed"); ++ exit(EXIT_SUCCESS); ++ } ++} ++ + void + tag(const Arg *arg) + { +@@ -1735,6 +1763,28 @@ togglefloating(const Arg *arg) + arrange(selmon); + } + ++void ++togglescratch(const Arg *arg) ++{ ++ Client *c; ++ unsigned int found = 0; ++ ++ for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); ++ if (found) { ++ c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; ++ focus(NULL); ++ arrange(selmon); ++ ++ if (ISVISIBLE(c)) { ++ focus(c); ++ restack(selmon); ++ } ++ ++ } else{ ++ spawnscratch(arg); ++ } ++} ++ + void + toggletag(const Arg *arg) + { +diff --git a/scratchtagwins.c b/scratchtagwins.c +new file mode 100644 +index 0000000..f51be3b +--- /dev/null ++++ b/scratchtagwins.c +@@ -0,0 +1,53 @@ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++#include <X11/XF86keysym.h> ++ ++# define SCRATCHTAGWIN(name, id) \ ++ static const char * name [] = { # id, \ ++ "tabbed", \ ++ "-p", "s+1", \ ++ "-n", # name, \ ++ "-g", "1195x672", \ ++ "-c", "st", "-w", \ ++ NULL \ ++ } \ ++ ++# define SCRATCHTAGWIN_RULE(name, id) \ ++ { NULL, # name, NULL, 0, 1, -1, '0' + id } \ ++ ++# define SCRATCHTAGWIN_KEY(name, id) \ ++ { MODKEY|Mod1Mask, XK_ ## id, togglescratch, {.v = name } }, \ ++ { MODKEY|Mod1Mask|ShiftMask,XK_ ## id, makescratchtagwin,{.i = '0' + id } }, \ ++ ++static void makescratchtagwin (const Arg * arg) ++{ ++ if (selmon -> sel) ++ { ++ if (arg -> i != 0) ++ { ++ _Bool exists = 0; ++ ++ for (Client * c = selmon -> clients; c; c = c -> next) ++ if (c -> scratchkey == arg -> i) ++ { ++ exists = 1; ++ break; ++ } ++ ++ if (exists) return; ++ } ++ ++ selmon -> sel -> scratchkey = arg -> i; ++ if (arg -> i != 0) ++ { ++ selmon -> sel -> tags = 0, ++ selmon -> sel -> isfloating = 1; ++ } ++ else ++ selmon -> sel -> tags = selmon -> tagset [selmon -> seltags]; ++ focus (selmon -> sel); ++ arrange (selmon); ++ } ++} diff --git a/dwm.suckless.org/patches/namedscratchpads/index.md b/dwm.suckless.org/patches/namedscratchpads/index.md @@ -14,12 +14,14 @@ A new field in the rules array is added to associate the command with the corres Works well with [floatrules](../floatrules/) for window positioning. Apply the scratchtagwins patch on top of this patch, to have 'scratchpad tags' -support. Contribute to this sub-patch on this [gitlab repo](https://gitlab.com/GasparVardanyan/dwm/-/tree/scratchtagwins). +support. Contribute to this sub-patch on this [gitlab repo](https://gitlab.com/GasparVardanyan/dwm/-/tree/namedscratchpads-scratchtagwins). Download -------- * [dwm-namedscratchpads-6.2.diff](dwm-namedscratchpads-6.2.diff) * [dwm-scratchtagwins-6.3.diff](dwm-scratchtagwins-6.3.diff) +* [dwm-namedscratchpads-6.5.diff](dwm-namedscratchpads-6.5.diff) + * [dwm-scratchtagwins-6.5.diff](dwm-scratchtagwins-6.5.diff) Authors -------