summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-02-28 20:19:03 -0500
committerMatt Hunter <m@lfurio.us>2026-01-18 00:18:17 -0500
commite780d94ea2baf22968391532ed1564a9ab728847 (patch)
treef44cdedb872476e0627a316e28911c359a21ec7d
parent4da63c93feab351ecc33d47a86c4ad06680d1ee3 (diff)
downloaddwm-e780d94ea2baf22968391532ed1564a9ab728847.tar.gz
dwm-e780d94ea2baf22968391532ed1564a9ab728847.zip
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.
-rw-r--r--config.def.h1
-rw-r--r--dwm.c85
2 files changed, 52 insertions, 34 deletions
diff --git a/config.def.h b/config.def.h
index 3a88b1c..13af0c4 100644
--- a/config.def.h
+++ b/config.def.h
@@ -22,6 +22,7 @@ static const char *colors[][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 fb6153c..e82d8f1 100644
--- a/dwm.c
+++ b/dwm.c
@@ -112,6 +112,7 @@ typedef struct {
void (*arrange)(Monitor *);
} Layout;
+#define TAGSTRLEN 40
struct Monitor {
char ltsymbol[16];
float mfact;
@@ -123,6 +124,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;
@@ -439,18 +441,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<<i || m->tagset[m->seltags] & 1<<i))
+ continue;
+ x += TEXTW(selmon->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);
@@ -713,13 +721,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)
@@ -727,30 +748,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<<i || m->tagset[m->seltags] & 1<<i))
+ continue;
+
+ /* Determine tagstr name */
+ snprintf(m->tagstrs[i], TAGSTRLEN, "%s", tags[i]);
+ for (c = m->clients; c; c = c->next) {
+ if (c->tags & (1<<i)) {
+ snprintf(m->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