summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-03-04 19:15:34 -0500
committerMatt Hunter <m@lfurio.us>2026-01-18 00:18:57 -0500
commita6cc118b3606551de5cb9a1a5a59897ba347716c (patch)
tree83ed53f532d35cfa78009381eeeaa5a890b43316
parentcc76324a76064f130d0bdce6b6af266162774b60 (diff)
downloaddwm-a6cc118b3606551de5cb9a1a5a59897ba347716c.tar.gz
dwm-a6cc118b3606551de5cb9a1a5a59897ba347716c.zip
patch: scratchpadz
This patch enables the use of multiple pre-assigned scratchpad terminals. This patch uses reserved tags for stowing scratchpads, these are the tagmasks just beyond those defined for normal use. DWM's rule system is used to handle spawning scratchpad windows. We use one rule per scratchpad to define what SPTAG it belongs to, whether it is floating, an instance identifier, and what program to exec in st (your shell by default). Keybinds should be setup to call togglescratch with a pointer to the rule struct which defines the scratchpad. The togglescratch function uses the information in the rule to craft an st command line to spawn. However, if some client is already open on the rule's tagmask, it will just act like toggleview(tagmask). Normal clients may be opened while viewing scratchpads, they are always excluded from scratchpad tags. This patch is inspired by the "scratchpad" and "scratchpads" patches from suckless.org.
-rw-r--r--config.def.h10
-rw-r--r--dwm.c47
2 files changed, 53 insertions, 4 deletions
diff --git a/config.def.h b/config.def.h
index d969b02..fe50ff3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -24,13 +24,16 @@ static const char *colors[][3] = {
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
static const char *tagfmt = "[%s: %.30s]";
+static const char *scratchpad_size = "120x34";
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
- /* class instance title tags mask isfloating monitor */
- { NULL, NULL, NULL, 0, 0, -1 },
+ /* class instance title tags mask isfloating monitor scratchpad exec */
+ { "st", "sp-shell", NULL, SPTAG(0), 1, -1, NULL },
+ { "st", "sp-pythn", NULL, SPTAG(1), 1, -1, "ipython3" },
+ { "st", "sp-mixer", NULL, SPTAG(2), 1, -1, "alsamixer" },
};
/* layout(s) */
@@ -109,6 +112,9 @@ static const Key keys[] = {
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
+ { MODKEY, XK_grave, togglescratch, {.v = &rules[0]} },
+ { MODKEY, XK_equal, togglescratch, {.v = &rules[1]} },
+ { MODKEY, XK_minus, togglescratch, {.v = &rules[2]} },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
diff --git a/dwm.c b/dwm.c
index d8f0f96..b253eb3 100644
--- a/dwm.c
+++ b/dwm.c
@@ -53,7 +53,9 @@
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
-#define TAGMASK ((1 << LENGTH(tags)) - 1)
+#define TAGMASK (~0)
+#define SPTAG(X) (1 << (LENGTH(tags) + (X)))
+#define SPTAGMASK (~0 << LENGTH(tags))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
#define OPAQUE 0xffU
@@ -144,6 +146,7 @@ typedef struct {
unsigned int tags;
int isfloating;
int monitor;
+ const char *scratchpad_exec;
} Rule;
/* function declarations */
@@ -225,6 +228,7 @@ static void tile(Monitor *m);
static void togglebar(const Arg *arg);
static void holdbar(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);
@@ -379,6 +383,10 @@ applyrules(Client *c)
{
c->isfloating = r->isfloating;
c->tags |= r->tags;
+ 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);
+ }
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
c->mon = m;
@@ -388,7 +396,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];
+ c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
}
int
@@ -1994,6 +2002,41 @@ togglefloating(const Arg *arg)
}
void
+togglescratch(const Arg *arg)
+{
+ const Rule *sp = arg->v;
+
+ unsigned int found = 0;
+ unsigned int scratchtag = sp->tags;
+ Client *c;
+
+ 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 {
+ const char *exec[] = { "st", "-n", sp->instance, "-g", scratchpad_size, NULL, NULL, NULL };
+ if (sp->scratchpad_exec) {
+ exec[5] = "-e";
+ exec[6] = sp->scratchpad_exec;
+ }
+
+ Arg execarg = {.v = exec};
+ selmon->tagset[selmon->seltags] |= scratchtag;
+ spawn(&execarg);
+ }
+}
+
+void
toggletag(const Arg *arg)
{
unsigned int newtags;