From 37b25c9685f265acaf864cb91c6c540befcfb80b Mon Sep 17 00:00:00 2001 From: Malfurious Date: Wed, 28 Feb 2024 20:19:03 -0500 Subject: patch: barlayout This is an overhaul of the statusbar appearance, inspired by a combination of the patches: rearrangebar, taglabels, hide-vacant-tags, and statusallmons. The bar layout (from left to right) is now just tag labels, status, and the layout symbol. However, tag labels are generally larger than usual and contain the name of the leading client on each tag. The format of these new labels is controlled by a new option in config.h. The layout symbol is moved all the way to the far right, per rearrangebar, however the center area is left clear for the tag labels to grow into. statusallmons and hide-vacant-tags work exactly as normal, but are implemented from scratch in this patch to avoid conflicts. This patch addresses some oversights by the others in the buttonpress() function for handling clicks on the statusbar. The logic is updated to correctly handle the new location of the status and ltsymbol. Tag labels are stored in the Monitor struct (instead of the original patch's global variable) so tag clicks can be handled correctly on multimonitor. This patch is updated to identify any hidden clients opened by the scratchpadz patch. --- config.def.h | 1 + dwm.c | 85 ++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/config.def.h b/config.def.h index 4ac4099..9ef5309 100644 --- a/config.def.h +++ b/config.def.h @@ -27,6 +27,7 @@ static const unsigned int alphas[][3] = { /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; +static const char *tagfmt = "[%s: %.30s]"; static const Rule rules[] = { /* xprop(1): diff --git a/dwm.c b/dwm.c index 7ca234b..a82e276 100644 --- a/dwm.c +++ b/dwm.c @@ -113,6 +113,7 @@ typedef struct { void (*arrange)(Monitor *); } Layout; +#define TAGSTRLEN 40 struct Monitor { char ltsymbol[16]; float mfact; @@ -124,6 +125,7 @@ struct Monitor { unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; + char tagstrs[32][TAGSTRLEN]; /* no more than 32 tags */ int showbar; int topbar; Client *clients; @@ -441,18 +443,24 @@ buttonpress(XEvent *e) } if (ev->window == selmon->barwin) { i = x = 0; - do - x += TEXTW(tags[i]); - while (ev->x >= x && ++i < LENGTH(tags)); + unsigned int occ = 0; + for (c = m->clients; c; c = c->next) + occ |= c->tags; + do { + /* Do not reserve space for vacant tags */ + if (!(occ & 1<tagset[m->seltags] & 1<tagstrs[i]); + } while (ev->x >= x && ++i < LENGTH(tags)); if (i < LENGTH(tags)) { click = ClkTagBar; arg.ui = 1 << i; - } else if (ev->x < x + TEXTW(selmon->ltsymbol)) + } else if (ev->x > selmon->ww - TEXTW(selmon->ltsymbol)) click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext)) + else if (ev->x > selmon->ww - (TEXTW(selmon->ltsymbol) + TEXTW(stext))) click = ClkStatusText; - else - click = ClkWinTitle; + //else + // click = ClkWinTitle; } else if ((c = wintoclient(ev->window))) { focus(c); restack(selmon); @@ -715,13 +723,26 @@ drawbar(Monitor *m) if (!m->showbar) return; - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + /* clear bar from last draw */ + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, m->ww, bh, lrpad / 2, 1); + + /* show a notification if scratchpads are opened (clients exist on unreachable tags) */ + char ltsym[24] = {0}; + strcpy(ltsym, m->ltsymbol); + for (c = m->clients; c; c = c->next) { + if (c->tags & ~((1 << LENGTH(tags)) - 1)) { + strcat(ltsym, " *"); + break; + } } + /* draw status first so it can be overdrawn by tags later */ + w = TEXTW(ltsym); + tw = TEXTW(stext) - lrpad + w; /* right padding for the tiling symbol */ + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + drw_text(drw, m->ww - w, 0, w, bh, lrpad / 2, ltsym, 0); + for (c = m->clients; c; c = c->next) { occ |= c->tags; if (c->isurgent) @@ -729,30 +750,25 @@ drawbar(Monitor *m) } x = 0; for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); + /* Do not draw vacant tags */ + if (!(occ & 1<tagset[m->seltags] & 1<tagstrs[i], TAGSTRLEN, "%s", tags[i]); + for (c = m->clients; c; c = c->next) { + if (c->tags & (1<tagstrs[i], TAGSTRLEN, tagfmt, tags[i], c->name); + break; + } + } + + w = TEXTW(m->tagstrs[i]); drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, boxs, boxw, boxw, - m == selmon && selmon->sel && selmon->sel->tags & 1 << i, - urg & 1 << i); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->tagstrs[i], urg & 1 << i); x += w; } - w = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } + drw_map(drw, m->barwin, 0, 0, m->ww, bh); } @@ -2018,7 +2034,8 @@ updatestatus(void) { if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) strcpy(stext, "dwm-"VERSION); - drawbar(selmon); + for (Monitor *m = mons; m; m = m->next) + drawbar(m); } void -- cgit v1.2.3