diff --git a/config.def.h b/config.def.h index 93d843f..461c659 100644 --- a/config.def.h +++ b/config.def.h @@ -40,15 +40,16 @@ static const Rule rules[] = { * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title */ - /* class instance title tags mask allowkill isfloating monitor */ - {"firefox", NULL, NULL, 1 << 0, 0, 0, -1}, - {"thunderbird", NULL, NULL, 1 << 6, 1, 0, -1}, - {"org.mozilla.Thunderbird", NULL, NULL, 1 << 6, 1, 0, -1}, - {"ManagerDesktop", NULL, NULL, 1 << 7, 1, 0, -1}, - {"Manager", NULL, NULL, 1 << 7, 1, 0, -1}, - {"InputLeap", NULL, NULL, 1 << 8, 1, 1, -1}, - {"Nextcloud", NULL, NULL, 1 << 8, 1, 0, -1}, - {"feishin", NULL, NULL, 1 << 2, 1, 0, -1}, + /* class instance title tags mask allowkill isfloating monitor */ + {"firefox", NULL, NULL, 1 << 0, 0, 0, -1 0}, + {"thunderbird", NULL, NULL, 1 << 6, 1, 0, -1 0}, + {"org.mozilla.Thunderbird", NULL, NULL, 1 << 6, 1, 0, -1 0}, + {"ManagerDesktop", NULL, NULL, 1 << 7, 1, 0, -1 0}, + {"Manager", NULL, NULL, 1 << 7, 1, 0, -1 0}, + {"InputLeap", NULL, NULL, 1 << 8, 1, 1, -1 0}, + {"Nextcloud", NULL, NULL, 1 << 8, 1, 0, -1 0}, + {"feishin", NULL, NULL, 1 << 2, 1, 0, -1 0}, + { NULL, NULL, "scratchpad", 0, 1, 0, -1, 's'}, }; /* layout(s) */ @@ -89,6 +90,8 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in static const char *dmenucmd[] = {"dmenu_run", NULL}; static const char *slockcmd[] = {"slock", NULL}; static const char *termcmd[] = {TERMINAL, "-e", "tmux-worker", NULL}; +/*First arg only serves to match against key in rules*/ +static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL}; #include "movestack.c" #include "shift-tools.c" @@ -100,6 +103,8 @@ static const Keychord *keychords[] = { &((Keychord){1, {{MODKEY | ControlMask | ShiftMask, XK_apostrophe}}, quit, {0}}), &((Keychord){1, {{MODKEY | ShiftMask, XK_apostrophe}}, quit, {1}}), + &((Keychord){1, {{MODKEY, XK_grave}}, togglescratch, {.v = scratchpadcmd }}), + &((Keychord){1, {{MODKEY, XK_apostrophe}}, killclient, {0}}), &((Keychord){1, {{MODKEY, XK_a}}, spawn, {.v = dmenucmd}}), diff --git a/dwm-namedscratchpads-6.5.diff b/dwm-namedscratchpads-6.5.diff new file mode 100644 index 0000000..70990a6 --- /dev/null +++ b/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.c b/dwm.c index dfa2dc7..435dae3 100644 --- a/dwm.c +++ b/dwm.c @@ -110,6 +110,7 @@ struct Client { int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; int allowkill; int issteam; + char scratchkey; Client *next; Client *snext; Monitor *mon; @@ -164,6 +165,7 @@ typedef struct { int allowkill; int isfloating; int monitor; + const char scratchkey; } Rule; typedef struct Systray Systray; @@ -249,12 +251,14 @@ static void sigterm(int unused); static void sigstatusbar(const Arg *arg); static void spawn(const Arg *arg); static Monitor *systraytomon(Monitor *m); +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 toggleallowkill(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); @@ -352,6 +356,7 @@ applyrules(Client *c) c->isfloating = 0; c->tags = 0; c->allowkill = allowkill; + c->scratchkey = 0; XGetClassHint(dpy, c->win, &ch); class = ch.res_class ? ch.res_class : broken; instance = ch.res_name ? ch.res_name : broken; @@ -368,6 +373,7 @@ applyrules(Client *c) c->isfloating = r->isfloating; c->tags |= r->tags; c->allowkill = r->allowkill; + c->scratchkey = r->scratchkey; for (m = mons; m && m->num != r->monitor; m = m->next); if (m) c->mon = m; @@ -377,6 +383,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]; } @@ -2101,6 +2108,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) { @@ -2188,6 +2216,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) {