diff --git a/README.md b/README.md index 34c31b4..2d0987a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2020-04-16 - Upgraded the scratchpad patch to the multiple scratchpads patch \[[ref](https://lists.suckless.org/hackers/2004/17205.html)\] + 2020-04-13 - Added statuscmd patch 2020-03-31 - Added the rounded corners patch diff --git a/config.def.h b/config.def.h index 77a4ae0..a164d5b 100644 --- a/config.def.h +++ b/config.def.h @@ -256,6 +256,18 @@ char *colors[][3] = { }; #endif // VTCOLORS_PATCH / FLOAT_BORDER_COLOR_PATCH +#if SCRATCHPAD_PATCH +const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL }; +const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL }; +const char *spcmd3[] = {"keepassxc", NULL }; +static Sp scratchpads[] = { + /* name cmd */ + {"spterm", spcmd1}, + {"spranger", spcmd2}, + {"keepassxc", spcmd3}, +}; +#endif // SCRATCHPAD_PATCH + /* tagging */ #if EWMHTAGS_PATCH static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; @@ -418,6 +430,11 @@ static const Rule rules[] = { /* class instance title tags mask isfloating monitor */ { "Gimp", NULL, NULL, 0, 1, -1 }, { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, + #if SCRATCHPAD_PATCH + { NULL, "spterm", NULL, SPTAG(0), 1, -1 }, + { NULL, "spfm", NULL, SPTAG(1), 1, -1 }, + { NULL, "keepassxc",NULL, SPTAG(2), 0, -1 }, + #endif // SCRATCHPAD_PATCH #endif }; @@ -679,10 +696,6 @@ static const char *statuscmds[] = { "notify-send Mouse$BUTTON" }; static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; #endif // STATUSCMD_PATCH -#if SCRATCHPAD_PATCH -static const char scratchpadname[] = "scratchpad"; -static const char *scratchpadcmd[] = { "st", "-t", scratchpadname, "-g", "120x34", NULL }; -#endif // SCRATCHPAD_PATCH #if SCRATCHPAD_ALT_1_PATCH static const unsigned scratchpad_mask = 1u << sizeof tags / sizeof * tags; #endif // SCRATCHPAD_ALT_1_PATCH @@ -691,9 +704,6 @@ static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - #if SCRATCHPAD_PATCH - { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, - #endif // SCRATCHPAD_PATCH { MODKEY, XK_b, togglebar, {0} }, #if STACKER_PATCH STACKKEYS(MODKEY, focus) @@ -815,6 +825,11 @@ static Key keys[] = { { MODKEY|ControlMask|ShiftMask, XK_k, toggleverticalmax, {0} }, { MODKEY|ControlMask, XK_m, togglemax, {0} }, #endif // MAXIMIZE_PATCH + #if SCRATCHPAD_PATCH + { MODKEY, XK_grave, togglescratch, {.ui = 0 } }, + { MODKEY|ControlMask, XK_grave, togglescratch, {.ui = 1 } }, + { MODKEY|ShiftMask, XK_grave, togglescratch, {.ui = 2 } }, + #endif // SCRATCHPAD_PATCH #if UNFLOATVISIBLE_PATCH { MODKEY|Mod4Mask, XK_space, unfloatvisible, {0} }, { MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[0]} }, diff --git a/dwm.c b/dwm.c index c29f8d9..5b87c54 100644 --- a/dwm.c +++ b/dwm.c @@ -75,7 +75,14 @@ #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw) #define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#if SCRATCHPAD_PATCH +#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads)) +#define TAGMASK ((1 << NUMTAGS) - 1) +#define SPTAG(i) ((1 << LENGTH(tags)) << (i)) +#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags)) +#else #define TAGMASK ((1 << LENGTH(tags)) - 1) +#endif // SCRATCHPAD_PATCH #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ @@ -528,6 +535,12 @@ applyrules(Client *c) #endif // SWALLOW_PATCH c->isfloating = r->isfloating; c->tags |= r->tags; + #if SCRATCHPAD_PATCH && !SCRATCHPAD_KEEP_POSITION_AND_SIZE_PATCH + if ((r->tags & SPTAGMASK) && r->isfloating) { + c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); + c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); + } + #endif // SCRATCHPAD_PATCH | SCRATCHPAD_KEEP_POSITION_AND_SIZE_PATCH for (m = mons; m && m->num != r->monitor; m = m->next); if (m) c->mon = m; @@ -559,8 +572,14 @@ applyrules(Client *c) XFree(ch.res_name); #if EMPTYVIEW_PATCH if(c->tags & TAGMASK) c->tags = c->tags & TAGMASK; + #if SCRATCHPAD_PATCH + else if(c->mon->tagset[c->mon->seltags]) c->tags = c->mon->tagset[c->mon->seltags] & ~SPTAGMASK; + #else else if(c->mon->tagset[c->mon->seltags]) c->tags = c->mon->tagset[c->mon->seltags]; + #endif // SCRATCHPAD_PATCH else c->tags = 1; + #elif SCRATCHPAD_PATCH + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK); #else c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; #endif // EMPTYVIEW_PATCH @@ -2115,16 +2134,6 @@ manage(Window w, XWindowAttributes *wa) c->bw = borderpx; #endif // SETBORDERPX_PATCH - #if SCRATCHPAD_PATCH - selmon->tagset[selmon->seltags] &= ~scratchtag; - if (!strcmp(c->name, scratchpadname)) { - c->mon->tagset[c->mon->seltags] |= c->tags = scratchtag; - c->isfloating = True; - c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); - c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); - } - #endif // SCRATCHPAD_PATCH - wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc); #if FLOAT_BORDER_COLOR_PATCH @@ -3081,6 +3090,12 @@ showhide(Client *c) if (!c) return; if (ISVISIBLE(c)) { + #if SCRATCHPAD_PATCH && !SCRATCHPAD_KEEP_POSITION_AND_SIZE_PATCH + if ((c->tags & SPTAGMASK) && c->isfloating) { + c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); + c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); + } + #endif // SCRATCHPAD_PATCH | SCRATCHPAD_KEEP_POSITION_AND_SIZE_PATCH /* show clients top down */ #if SAVEFLOATS_PATCH || EXRESIZE_PATCH if (!c->mon->lt[c->mon->sellt]->arrange && c->sfx != -9999 && !c->isfullscreen) { @@ -3149,9 +3164,6 @@ spawn(const Arg *arg) } #endif // STATUSCMD_PATCH - #if SCRATCHPAD_PATCH - selmon->tagset[selmon->seltags] &= ~scratchtag; - #endif // SCRATCHPAD_PATCH if (fork() == 0) { if (dpy) close(ConnectionNumber(dpy)); diff --git a/patch/scratchpad.c b/patch/scratchpad.c index 7ba6366..4edff52 100644 --- a/patch/scratchpad.c +++ b/patch/scratchpad.c @@ -1,23 +1,25 @@ -static unsigned int scratchtag = 1 << LENGTH(tags); - void togglescratch(const Arg *arg) { - Client *c; - unsigned int found = 0; + Client *c; + unsigned int found = 0; + unsigned int scratchtag = SPTAG(arg->ui); + Arg sparg = {.v = scratchpads[arg->ui].cmd}; - for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next); - if (found) { - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag; - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } - if (ISVISIBLE(c)) { - focus(c); - restack(selmon); - } - } else - spawn(arg); + for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next); + if (found) { + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag; + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); + arrange(selmon); + } + if (ISVISIBLE(c)) { + focus(c); + restack(selmon); + } + } else { + selmon->tagset[selmon->seltags] |= scratchtag; + spawn(&sparg); + } } \ No newline at end of file diff --git a/patch/scratchpad.h b/patch/scratchpad.h index be5c3a4..3142cdf 100644 --- a/patch/scratchpad.h +++ b/patch/scratchpad.h @@ -1 +1,6 @@ +typedef struct { + const char *name; + const void *cmd; +} Sp; + static void togglescratch(const Arg *arg); \ No newline at end of file diff --git a/patches.def.h b/patches.def.h index 261603a..72fabc3 100644 --- a/patches.def.h +++ b/patches.def.h @@ -397,12 +397,21 @@ */ #define SAVEFLOATS_PATCH 0 -/* The scratchpad patch allows you to spawn or restore a floating terminal window. +/* The scratchpad patch allows you to spawn or restore floating terminal windows. * It is typically useful when one need to do some short typing. + * Upgraded to Christian Tenllado's multiple scratchpad version. + * https://lists.suckless.org/hackers/2004/17205.html * https://dwm.suckless.org/patches/scratchpad/ */ #define SCRATCHPAD_PATCH 0 +/* The scratchpad patch above automatically resizes and centers the scratchpad window every + * time you spawn it. This alteration of the patch disables that so that the size and position + * of the scratchpad window is retained when you respawn it. If you enable this then you may + * want to also take the centered patch and enable the iscentered flag for floating scratchpads. + */ +#define SCRATCHPAD_KEEP_POSITION_AND_SIZE_PATCH 0 + /* This alternative patch enables a scratchpad feature in dwm similar to the scratchpad * feature in i3wm. * https://github.com/GasparVardanyan/dwm-scratchpad