From f86f23588bd96803137e65a0ef7a8dcc285e4583 Mon Sep 17 00:00:00 2001 From: v4hn Date: Thu, 4 Feb 2021 14:12:34 +0100 Subject: [PATCH 1/2] introduce locktagsfor functionality To reduce procrastination and focus on individual tasks in workflows where multiple projects are open in disjoint tag sets, this patch enables users to lock their currently selected tags for some duration and force them to focus on what is currently shown on their screen. The patch retains all WM functionality that does not change tags, especially multi-monitor setups and layout changes. Of course the patch does not support you at all if you procrastinate away from your computer or just open new unrelated windows. Forbidding the latter would be much harder and too restrictive from the perspective of the patch author. To use this patch add a shortcut to your config.h. E.g., to lock tags for 300 seconds via MOD+F1, add + { MODKEY, XK_F1, locktagsfor, {.ui = 300 } }, --- dwm.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/dwm.c b/dwm.c index 137a10f..3da1c1a 100644 --- a/dwm.c +++ b/dwm.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,7 @@ static void grabkeys(void); static void incnmaster(const Arg *arg); static void keypress(XEvent *e); static void killclient(const Arg *arg); +static void locktagsfor(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); @@ -246,6 +248,8 @@ static Display *dpy; static Drw *drw; static Monitor *mons, *selmon; static Window root; +static time_t locktagsuntil = 0; +static int tagslocked(){ return difftime(locktagsuntil, time(NULL)) > 0; } /* configuration, allows nested code to access above variables */ #include "config.def.h" @@ -789,12 +793,16 @@ drawbar(Monitor *m) urg |= c->tags; } x = 0; + + const int locked = tagslocked(); + for (i = 0; i < LENGTH(tags); i++) { w = TEXTW(tags[i]); drw_setscheme(drw, m->tagset[m->seltags] & 1 << i ? &scheme[SchemeSel] : &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, tags[i], urg & 1 << i); + drw_text(drw, x, 0, w, bh, + !locked || m->tagset[m->seltags] & 1 << i ? tags[i] : "", !locked && (urg & 1 << i)); drw_rect(drw, x + 1, 1, dx, dx, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, - occ & 1 << i, urg & 1 << i); + (m->tagset[m->seltags] & 1 << i || !locked) && occ & 1 << i, !locked && (urg & 1 << i)); x += w; } w = blw = TEXTW(m->ltsymbol); @@ -1113,6 +1121,19 @@ killclient(const Arg *arg) } } +void +locktagsfor(const Arg *arg) +{ +#if 0 // enable for a shortcut to break out early + if(tagslocked()){ + locktagsuntil = time(NULL); + return; + } +#endif + // all sane implementations implement time_t as integral second count, so we just add seconds here + locktagsuntil = time(NULL) + (time_t) arg->ui; +} + void manage(Window w, XWindowAttributes *wa) { @@ -1747,6 +1768,9 @@ spawn(const Arg *arg) void tag(const Arg *arg) { + if(tagslocked()) + return; + if (selmon->sel && arg->ui & TAGMASK) { selmon->sel->tags = arg->ui & TAGMASK; focus(NULL); @@ -1816,6 +1840,9 @@ toggletag(const Arg *arg) { unsigned int newtags; + if(tagslocked()) + return; + if (!selmon->sel) return; newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); @@ -1832,6 +1859,9 @@ toggleview(const Arg *arg) unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); int i; + if(tagslocked()) + return; + if (newtagset) { if(newtagset == ~0) { selmon->pertag->prevtag = selmon->pertag->curtag; @@ -2153,6 +2183,10 @@ view(const Arg *arg) if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; + + if(tagslocked()) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ if(arg->ui & TAGMASK) { selmon->pertag->prevtag = selmon->pertag->curtag; -- 2.30.1