summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-03-04 19:15:34 -0500
committerMalfurious <m@lfurio.us>2024-03-05 21:04:53 -0500
commitd4ee7a81f7b908d7305b35918c61d4f497161ca8 (patch)
tree68baf6514e3f2c6e69523a0771290cfc48a39358
parentc487d2524a1c8429b74285ef05557fb408483da0 (diff)
downloaddwm-d4ee7a81f7b908d7305b35918c61d4f497161ca8.tar.gz
dwm-d4ee7a81f7b908d7305b35918c61d4f497161ca8.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 9f6f41e..54d0c54 100644
--- a/config.def.h
+++ b/config.def.h
@@ -29,13 +29,16 @@ static const unsigned int alphas[][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) */
@@ -113,6 +116,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 11bce9a..46b5b37 100644
--- a/dwm.c
+++ b/dwm.c
@@ -54,7 +54,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
@@ -145,6 +147,7 @@ typedef struct {
unsigned int tags;
int isfloating;
int monitor;
+ const char *scratchpad_exec;
} Rule;
/* function declarations */
@@ -226,6 +229,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);
@@ -381,6 +385,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;
@@ -390,7 +398,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;