dwm-noxz

[fork] suckless dwm - personal fork
git clone https://noxz.tech/git/dwm-noxz.git
Log | Files | README | LICENSE

commit: 8a891e2aa685f1a59505a6e39c382c8e23dcefcb
parent: 141d3d7c2f5acd296760e9dab2bbb0f141cc38bb
author: Chris Noxz <chris@noxz.tech>
date:   Sun, 5 Feb 2023 10:13:48 +0100
Update the tagbar look
Mconfig.def.h13++++
Mdwm.c65+++++++++++++++-----
2 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -20,6 +20,9 @@ static char col_sfl[]           = COL_DEF;
 static char col_tanfg[]         = COL_DEF;
 static char col_tanbg[]         = COL_DEF;
 static char col_tanbr[]         = COL_DEF;
+static char col_taifg[]         = COL_DEF;
+static char col_taibg[]         = COL_DEF;
+static char col_taibr[]         = COL_DEF;
 static char col_tasfg[]         = COL_DEF;
 static char col_tasbg[]         = COL_DEF;
 static char col_tasbr[]         = COL_DEF;
@@ -43,6 +46,7 @@ static char *colors[][4]        = {
 	[SchemeNorm]            = { col_none,   col_none,   col_nbr,    col_none },
 	[SchemeSel]             = { col_none,   col_none,   col_sbr,    col_sfl },
 	[SchemeTagsNorm]        = { col_tanfg,  col_tanbg,  col_tanbr,  col_none },
+	[SchemeTagsIncl]        = { col_taifg,  col_taibg,  col_taibr,  col_none },
 	[SchemeTagsSel]         = { col_tasfg,  col_tasbg,  col_tasbr,  col_none },
 	[SchemeLayout]          = { col_layfg,  col_laybg,  col_laybr,  col_none },
 	[SchemeTitleNorm]       = { col_tinfg,  col_tinbg,  col_none,   col_none },
@@ -57,6 +61,12 @@ static char *colors[][4]        = {
 /* tagging */
 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
 
+static const unsigned int ulinepad = 5;     /* horizontal padding between the underline and tag */
+static const unsigned int ulinestroke = 1;  /* thickness / height of the underline */
+static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */
+static const char ptagf[] = "[%s: %s]";     /* format of a tag label */
+static const char etagf[] = "[%s]";         /* format of an empty tag */
+
 static const Rule rules[] = { NULL
 	/* xprop(1):
 	 * WM_CLASS(STRING) = instance, class
@@ -108,6 +118,9 @@ ResourcePref resources[] = {
 	{ "tagsNormalForeground",       STRING,     &col_tanfg },
 	{ "tagsNormalBackground",       STRING,     &col_tanbg },
 	{ "tagsNormalBorderColor",      STRING,     &col_tanbr },
+	{ "tagsIncludedForeground",     STRING,     &col_taifg },
+	{ "tagsIncludedBackground",     STRING,     &col_taibg },
+	{ "tagsIncludedBorderColor",    STRING,     &col_taibr },
 	{ "tagsSelectedForeground",     STRING,     &col_tasfg },
 	{ "tagsSelectedBackground",     STRING,     &col_tasbg },
 	{ "tagsSelectedBorderColor",    STRING,     &col_tasbr },
diff --git a/dwm.c b/dwm.c
@@ -20,6 +20,7 @@
  *
  * To understand everything else, start reading main().
  */
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <locale.h>
@@ -64,9 +65,9 @@
 enum { DispUi, DispCmdLine }; /* dispatch types */
 enum { LayoutGrid, LayoutTiled, LayoutMonocle, LayoutFloating }; /* layouts, first is default */
 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel, SchemeTagsNorm, SchemeTagsSel, SchemeLayout,
-	SchemeTitleNorm, SchemeTitleSel, SchemeStatusNorm, SchemeStatusAct,
-	SchemeStatusDist, SchemeStatusNoti }; /* color schemes */
+enum { SchemeNorm, SchemeSel, SchemeTagsNorm, SchemeTagsIncl, SchemeTagsSel,
+	SchemeLayout, SchemeTitleNorm, SchemeTitleSel, SchemeStatusNorm,
+	SchemeStatusAct, SchemeStatusDist, SchemeStatusNoti }; /* color schemes */
 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
        NetWMFullscreen, NetActiveWindow, NetWMWindowType,
        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
@@ -302,6 +303,8 @@ static int fifofd;
 /* configuration, allows nested code to access above variables */
 #include "config.h"
 
+unsigned int tagw[LENGTH(tags)];
+
 struct Pertag {
 	unsigned int curtag, prevtag; /* current and previous tag */
 	int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
@@ -474,7 +477,7 @@ attachstack(Client *c)
 void
 buttonpress(XEvent *e)
 {
-	unsigned int i, x, click;
+	unsigned int i, x, click, occ = 0;
 	Arg arg = {0};
 	Client *c;
 	Monitor *m;
@@ -490,9 +493,14 @@ buttonpress(XEvent *e)
 	}
 	if (ev->window == selmon->barwin) {
 		i = x = 0;
-		do
-			x += TEXTW(tags[i]);
-		while (ev->x >= x && ++i < LENGTH(tags));
+		for (c = m->clients; c; c = c->next)
+			occ |= c->tags == 255 ? 0 : c->tags;
+		do {
+			/* do not reserve space for vacant tags */
+			if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+				continue;
+			x += tagw[i];
+		} while (ev->x >= x && ++i < LENGTH(tags));
 		if (i < LENGTH(tags)) {
 			click = ClkTagBar;
 			arg.ui = 1 << i;
@@ -872,12 +880,14 @@ drawbar(Monitor *m)
 	int x, w, tw = 0;
 	int boxs = drw->fonts->h / 9;
 	int boxw = drw->fonts->h / 6 + 2;
-	unsigned int i, occ = 0, urg = 0;
+	unsigned int i, j, occ = 0, urg = 0;
 	char *ts = stext;
 	char *tp = stext;
 	int tx = 0;
 	char ctmp;
 	Client *c;
+	char taglabel[64];
+	char *masterclientontag[LENGTH(tags)];
 
 	/* draw status first so it can be overdrawn by tags later */
 	if (m == selmon) { /* status is only drawn on selected monitor */
@@ -908,20 +918,41 @@ drawbar(Monitor *m)
 		}
 	}
 
+	for (i = 0; i < LENGTH(tags); i++)
+		masterclientontag[i] = NULL;
+
 	for (c = m->clients; c; c = c->next) {
-		occ |= c->tags;
+		occ |= c->tags == 255 ? 0 : c->tags;
 		if (c->isurgent)
 			urg |= c->tags;
+		for (i = 0; i < LENGTH(tags); i++)
+			if (!masterclientontag[i] && c->tags & (1 << i)) {
+				XClassHint ch = { NULL, NULL };
+				XGetClassHint(dpy, c->win, &ch);
+				masterclientontag[i] = ch.res_class;
+				/* to lower */
+				for(j = 0; masterclientontag[i][j]; j++)
+					masterclientontag[i][j] = tolower(masterclientontag[i][j]);
+			}
 	}
 	x = 0;
 	for (i = 0; i < LENGTH(tags); i++) {
-		w = TEXTW(tags[i]);
-		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]);
-		drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
-		if (occ & 1 << i)
-			drw_rect(drw, x + boxs + 1, boxs + 1, boxw, boxw,
-				m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
-				urg & 1 << i);
+		/* do not draw vacant tags */
+		if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+			continue;
+		if (masterclientontag[i])
+			snprintf(taglabel, 64, ptagf, tags[i], masterclientontag[i]);
+		else
+			snprintf(taglabel, 64, etagf, tags[i]);
+		masterclientontag[i] = taglabel;
+		tagw[i] = w = TEXTW(masterclientontag[i]);
+		drw_setscheme(drw,
+			scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel                   /* selected tag */
+			: selmon && selmon->sel && selmon->sel->tags & 1 << i ? SchemeTagsIncl   /* client in tag */
+			: SchemeTagsNorm]);
+		drw_text(drw, x, 0, w, bh, lrpad / 2, masterclientontag[i], urg & 1 << i);
+		if (m->tagset[m->seltags] & 1 << i)
+			drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0);
 		x += w;
 	}
 	w = blw = TEXTW(m->ltsymbol);
@@ -939,7 +970,7 @@ drawbar(Monitor *m)
 				drw_rect(drw, x + boxs + 1, boxs + 1, boxw, boxw, m->sel->isfixed, 0);
 		} else {
 			drw_setscheme(drw, scheme[SchemeTitleNorm]);
-			drw_rect(drw, x + 1, 1, w, bh, 1, 1);
+			drw_rect(drw, x, 0, w, bh, 1, 1);
 		}
 	}
 	drw_map(drw, m->barwin, 0, 0, m->ww, bh);