| dwm-scratchpads-20200414-728d397b.diff - sites - public wiki contents of suckle… | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| dwm-scratchpads-20200414-728d397b.diff (7977B) | |
| --- | |
| 1 From 728d397b21982af88737277fd9d6939a7b558786 Mon Sep 17 00:00:00 2001 | |
| 2 From: Christian Tenllado <[email protected]> | |
| 3 Date: Tue, 14 Apr 2020 23:31:15 +0200 | |
| 4 Subject: [PATCH] Multiple scratchpads | |
| 5 | |
| 6 This patch enables multiple scratchpads, each with one asigned window. | |
| 7 This enables the same scratchpad workflow that you have in i3. | |
| 8 | |
| 9 Scratchpads are implemented as special tags, whose mask does not | |
| 10 apply to new spawned windows. To assign a window to a scratchpad you | |
| 11 have to set up a rule, as you do with regular tags. | |
| 12 | |
| 13 Windows tagged with scratchpad tags can be set floating or not in the | |
| 14 rules array. Most users would probably want them floating (i3 style), | |
| 15 but having them tiled does also perfectly work and might fit better the | |
| 16 DWM approach. In case they are set floating, the patch moves them to the | |
| 17 center of the screen whenever they are shown. The patch can easily be | |
| 18 modified to make this last feature configurable in the rules array (see | |
| 19 the center patch). | |
| 20 | |
| 21 The togglescratch function, borrowed from the previous scratchpad patch | |
| 22 and slightly modified, can be used to spawn a registered scratchpad | |
| 23 process or toggle its view. This function looks for a window tagged with | |
| 24 the selected scratchpad tag. If it is found its view is toggled. If it is | |
| 25 not found the corresponding registered command is spawned. The | |
| 26 config.def.h shows three examples of its use to spawn a terminal in the | |
| 27 first scratchpad tag, a second terminal running ranger on the second | |
| 28 scratchpad tag and the keepassxc application to manage passwords on a | |
| 29 third scratchpad tag. | |
| 30 | |
| 31 If you prefer to spawn your scratchpad applications from the startup | |
| 32 script, you might opt for binding keys to toggleview instead, as | |
| 33 scratchpads are just special tags (you may even extend the TAGKEYS macro | |
| 34 to generalize the key bindings). | |
| 35 --- | |
| 36 config.def.h | 28 ++++++++++++++++++++++++---- | |
| 37 dwm.c | 43 +++++++++++++++++++++++++++++++++++++++++-- | |
| 38 2 files changed, 65 insertions(+), 6 deletions(-) | |
| 39 | |
| 40 diff --git a/config.def.h b/config.def.h | |
| 41 index 1c0b587..06265e1 100644 | |
| 42 --- a/config.def.h | |
| 43 +++ b/config.def.h | |
| 44 @@ -18,17 +18,33 @@ static const char *colors[][3] = { | |
| 45 [SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |
| 46 }; | |
| 47 | |
| 48 +typedef struct { | |
| 49 + const char *name; | |
| 50 + const void *cmd; | |
| 51 +} Sp; | |
| 52 +const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL }; | |
| 53 +const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "rang… | |
| 54 +const char *spcmd3[] = {"keepassxc", NULL }; | |
| 55 +static Sp scratchpads[] = { | |
| 56 + /* name cmd */ | |
| 57 + {"spterm", spcmd1}, | |
| 58 + {"spranger", spcmd2}, | |
| 59 + {"keepassxc", spcmd3}, | |
| 60 +}; | |
| 61 + | |
| 62 /* tagging */ | |
| 63 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "… | |
| 64 - | |
| 65 static const Rule rules[] = { | |
| 66 /* xprop(1): | |
| 67 * WM_CLASS(STRING) = instance, class | |
| 68 * WM_NAME(STRING) = title | |
| 69 */ | |
| 70 /* class instance title tags mask isfloating … | |
| 71 - { "Gimp", NULL, NULL, 0, 1, … | |
| 72 - { "Firefox", NULL, NULL, 1 << 8, 0, … | |
| 73 + { "Gimp", NULL, NULL, … | |
| 74 + { "Firefox", NULL, NULL, … | |
| 75 + { NULL, "spterm", NULL, … | |
| 76 + { NULL, "spfm", NULL, … | |
| 77 + { NULL, "keepassxc", NULL, … | |
| 78 }; | |
| 79 | |
| 80 /* layout(s) */ | |
| 81 @@ -59,6 +75,7 @@ static char dmenumon[2] = "0"; /* component of dmenucm… | |
| 82 static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", d… | |
| 83 static const char *termcmd[] = { "st", NULL }; | |
| 84 | |
| 85 + | |
| 86 static Key keys[] = { | |
| 87 /* modifier key function argu… | |
| 88 { MODKEY, XK_p, spawn, {.v … | |
| 89 @@ -84,6 +101,9 @@ static Key keys[] = { | |
| 90 { MODKEY, XK_period, focusmon, {.i … | |
| 91 { MODKEY|ShiftMask, XK_comma, tagmon, {.i … | |
| 92 { MODKEY|ShiftMask, XK_period, tagmon, {.i … | |
| 93 + { MODKEY, XK_y, … | |
| 94 + { MODKEY, XK_u, to… | |
| 95 + { MODKEY, XK_x, to… | |
| 96 TAGKEYS( XK_1, 0) | |
| 97 TAGKEYS( XK_2, 1) | |
| 98 TAGKEYS( XK_3, 2) | |
| 99 @@ -106,7 +126,7 @@ static Button buttons[] = { | |
| 100 { ClkStatusText, 0, Button2, spawn, … | |
| 101 { ClkClientWin, MODKEY, Button1, movemou… | |
| 102 { ClkClientWin, MODKEY, Button2, togglef… | |
| 103 - { ClkClientWin, MODKEY, Button3, resizem… | |
| 104 + { ClkClientWin, MODKEY, Button1, resizem… | |
| 105 { ClkTagBar, 0, Button1, view, … | |
| 106 { ClkTagBar, 0, Button3, togglev… | |
| 107 { ClkTagBar, MODKEY, Button1, tag, … | |
| 108 diff --git a/dwm.c b/dwm.c | |
| 109 index 4465af1..646aa1a 100644 | |
| 110 --- a/dwm.c | |
| 111 +++ b/dwm.c | |
| 112 @@ -54,7 +54,10 @@ | |
| 113 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) | |
| 114 #define WIDTH(X) ((X)->w + 2 * (X)->bw) | |
| 115 #define HEIGHT(X) ((X)->h + 2 * (X)->bw) | |
| 116 -#define TAGMASK ((1 << LENGTH(tags)) - 1) | |
| 117 +#define NUMTAGS (LENGTH(tags) + … | |
| 118 +#define TAGMASK ((1 << NUMTAGS) - 1) | |
| 119 +#define SPTAG(i) ((1 << LENGTH(tags)) <… | |
| 120 +#define SPTAGMASK (((1 << LENGTH(scratchpads)… | |
| 121 #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) | |
| 122 | |
| 123 /* enums */ | |
| 124 @@ -211,6 +214,7 @@ static void tagmon(const Arg *arg); | |
| 125 static void tile(Monitor *); | |
| 126 static void togglebar(const Arg *arg); | |
| 127 static void togglefloating(const Arg *arg); | |
| 128 +static void togglescratch(const Arg *arg); | |
| 129 static void toggletag(const Arg *arg); | |
| 130 static void toggleview(const Arg *arg); | |
| 131 static void unfocus(Client *c, int setfocus); | |
| 132 @@ -299,6 +303,11 @@ applyrules(Client *c) | |
| 133 { | |
| 134 c->isfloating = r->isfloating; | |
| 135 c->tags |= r->tags; | |
| 136 + if ((r->tags & SPTAGMASK) && r->isfloating) { | |
| 137 + c->x = c->mon->wx + (c->mon->ww / 2 - W… | |
| 138 + c->y = c->mon->wy + (c->mon->wh / 2 - H… | |
| 139 + } | |
| 140 + | |
| 141 for (m = mons; m && m->num != r->monitor; m = m… | |
| 142 if (m) | |
| 143 c->mon = m; | |
| 144 @@ -308,7 +317,7 @@ applyrules(Client *c) | |
| 145 XFree(ch.res_class); | |
| 146 if (ch.res_name) | |
| 147 XFree(ch.res_name); | |
| 148 - c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagse… | |
| 149 + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tags… | |
| 150 } | |
| 151 | |
| 152 int | |
| 153 @@ -1616,6 +1625,10 @@ showhide(Client *c) | |
| 154 if (!c) | |
| 155 return; | |
| 156 if (ISVISIBLE(c)) { | |
| 157 + if ((c->tags & SPTAGMASK) && c->isfloating) { | |
| 158 + c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) … | |
| 159 + c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c)… | |
| 160 + } | |
| 161 /* show clients top down */ | |
| 162 XMoveWindow(dpy, c->win, c->x, c->y); | |
| 163 if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloati… | |
| 164 @@ -1719,6 +1732,32 @@ togglefloating(const Arg *arg) | |
| 165 arrange(selmon); | |
| 166 } | |
| 167 | |
| 168 +void | |
| 169 +togglescratch(const Arg *arg) | |
| 170 +{ | |
| 171 + Client *c; | |
| 172 + unsigned int found = 0; | |
| 173 + unsigned int scratchtag = SPTAG(arg->ui); | |
| 174 + Arg sparg = {.v = scratchpads[arg->ui].cmd}; | |
| 175 + | |
| 176 + for (c = selmon->clients; c && !(found = c->tags & scratchtag);… | |
| 177 + if (found) { | |
| 178 + unsigned int newtagset = selmon->tagset[selmon->seltags… | |
| 179 + if (newtagset) { | |
| 180 + selmon->tagset[selmon->seltags] = newtagset; | |
| 181 + focus(NULL); | |
| 182 + arrange(selmon); | |
| 183 + } | |
| 184 + if (ISVISIBLE(c)) { | |
| 185 + focus(c); | |
| 186 + restack(selmon); | |
| 187 + } | |
| 188 + } else { | |
| 189 + selmon->tagset[selmon->seltags] |= scratchtag; | |
| 190 + spawn(&sparg); | |
| 191 + } | |
| 192 +} | |
| 193 + | |
| 194 void | |
| 195 toggletag(const Arg *arg) | |
| 196 { | |
| 197 -- | |
| 198 2.20.1 | |
| 199 |