From f45acf87959d42808a198042efe2cc6185ce7fd1 Mon Sep 17 00:00:00 2001 From: bakkeby Date: Tue, 25 Aug 2020 16:27:14 +0200 Subject: [PATCH] Added alttagsdecoration patch. Unified tag icon handling while adding support for different icons per monitor. In general LENGTH(tags) has been replaced with a NUMTAGS macro (defaulting to 9) and the tags[] array has been replaced with a tagicons[][] array, access to which is done through a single function tagicon. This allows one central place where alternative tags, alttagsdecoration, or other future tags logic is handled. This also gives a consistent display of tags regardless of the module that presents tags. Additionally the monitor index has been integrated into dwm for easier access. --- README.md | 7 ++- config.def.h | 96 ++++++++++++++++++++++++-------------- dwm.c | 45 ++++++++++-------- patch/bar_ewmhtags.c | 8 +++- patch/bar_ewmhtags.h | 2 - patch/bar_flexwintitle.c | 2 +- patch/bar_indicators.c | 10 ++-- patch/bar_powerline_tags.c | 27 +++++------ patch/bar_tabgroups.c | 2 +- patch/bar_taggrid.c | 26 +++++------ patch/bar_tagicons.c | 20 ++++++++ patch/bar_tagicons.h | 7 +++ patch/bar_tags.c | 38 +++++---------- patch/focusurgent.c | 4 +- patch/include.c | 2 + patch/include.h | 2 + patch/pertag.c | 24 +++++----- patch/reorganizetags.c | 4 +- patch/shiftview.c | 4 +- patch/shiftviewclients.c | 4 +- patch/tagall.c | 4 +- patches.def.h | 7 +++ 22 files changed, 199 insertions(+), 146 deletions(-) create mode 100644 patch/bar_tagicons.c create mode 100644 patch/bar_tagicons.h diff --git a/README.md b/README.md index b9c9743..cb2435a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2020-08-25 - Unified tag icon handling while adding support for different icons per monitor. Added alttagsdecoration patch. + 2020-08-22 - Added logic to auto-hide bars if nothing is drawn on them (e.g. for standalone bars that only show certain clients). Added clientindicators patch and unified indicator code. Simplified Pango integration by settling on common function signatures. 2020-08-21 - Simplification of color configuration; settling on a set of color schemes that is shared between multiple patches (urgentborder, floatborder and titlecolor patches made non-optional) @@ -162,6 +164,9 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - [alternativetags](https://dwm.suckless.org/patches/alternativetags/) - adds alternative tags which can be toggled on the fly for the sole purpose of providing visual aid + - [alttagsdecoration](https://dwm.suckless.org/patches/alttagsdecoration/) + - provides the ability to use alternative text for tags which contain at least one window + - [alwaysfullscreen](https://dwm.suckless.org/patches/alwaysfullscreen/) - prevents the focus to drift from the active fullscreen client when using focusstack\(\) @@ -412,7 +417,7 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - [rotatestack](https://dwm.suckless.org/patches/rotatestack/) - let's you rotate through the stack using keyboard shortcuts - - [roundedcorners](https://github.com/mitchweaver/suckless/blob/master/dwm/patches_mitch/mitch-06-rounded_corners-db6093f6ec1bb884f7540f2512935b5254750b30.patch) + - [roundedcorners](https://github.com/mitchweaver/suckless/blob/master/dwm/patches/mitch-06-rounded_corners-f04cac6d6e39cd9e3fc4fae526e3d1e8df5e34b2.patch) - adds rounded corners to client windows - [savefloats](https://dwm.suckless.org/patches/save_floats/) diff --git a/config.def.h b/config.def.h index d79f4b2..be4e9e8 100644 --- a/config.def.h +++ b/config.def.h @@ -153,15 +153,15 @@ static char selfloatbgcolor[] = "#117799"; static const unsigned int baralpha = 0xd0; static const unsigned int borderalpha = OPAQUE; static const unsigned int alphas[][3] = { - /* fg bg border */ - [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, - [SchemeSel] = { OPAQUE, baralpha, borderalpha }, - [SchemeTitleNorm] = { OPAQUE, baralpha, borderalpha }, - [SchemeTitleSel] = { OPAQUE, baralpha, borderalpha }, - [SchemeTagsNorm] = { OPAQUE, baralpha, borderalpha }, - [SchemeTagsSel] = { OPAQUE, baralpha, borderalpha }, - [SchemeHid] = { OPAQUE, baralpha, borderalpha }, - [SchemeUrg] = { OPAQUE, baralpha, borderalpha }, + /* fg bg border */ + [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, + [SchemeSel] = { OPAQUE, baralpha, borderalpha }, + [SchemeTitleNorm] = { OPAQUE, baralpha, borderalpha }, + [SchemeTitleSel] = { OPAQUE, baralpha, borderalpha }, + [SchemeTagsNorm] = { OPAQUE, baralpha, borderalpha }, + [SchemeTagsSel] = { OPAQUE, baralpha, borderalpha }, + [SchemeHid] = { OPAQUE, baralpha, borderalpha }, + [SchemeUrg] = { OPAQUE, baralpha, borderalpha }, #if BAR_FLEXWINTITLE_PATCH [SchemeFlexActTTB] = { OPAQUE, baralpha, borderalpha }, [SchemeFlexActLTR] = { OPAQUE, baralpha, borderalpha }, @@ -203,15 +203,15 @@ static const unsigned int alphas[][3] = { static const char title_bg_dark[] = "#303030"; static const char title_bg_light[] = "#fdfdfd"; static const int color_ptrs[][ColCount] = { - /* fg bg border float */ - [SchemeNorm] = { -1, -1, 5, 12 }, - [SchemeSel] = { -1, -1, 11, 13 }, - [SchemeTitleNorm] = { 6, -1, -1, -1 }, - [SchemeTitleSel] = { 6, -1, -1, -1 }, - [SchemeTagsNorm] = { 2, 0, 0, -1 }, - [SchemeTagsSel] = { 6, 5, 5, -1 }, - [SchemeHid] = { 5, 0, 0, -1 }, - [SchemeUrg] = { 7, 9, 9, 15 }, + /* fg bg border float */ + [SchemeNorm] = { -1, -1, 5, 12 }, + [SchemeSel] = { -1, -1, 11, 13 }, + [SchemeTitleNorm] = { 6, -1, -1, -1 }, + [SchemeTitleSel] = { 6, -1, -1, -1 }, + [SchemeTagsNorm] = { 2, 0, 0, -1 }, + [SchemeTagsSel] = { 6, 5, 5, -1 }, + [SchemeHid] = { 5, 0, 0, -1 }, + [SchemeUrg] = { 7, 9, 9, 15 }, }; #endif // BAR_VTCOLORS_PATCH @@ -264,15 +264,15 @@ static char *colors[][ColCount] = { #if BAR_POWERLINE_STATUS_PATCH static char *statuscolors[][ColCount] = { - /* fg bg border float */ - [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor, normfloatcolor }, - [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor, selfloatcolor }, - [SchemeTitleNorm] = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor }, - [SchemeTitleSel] = { titleselfgcolor, titleselbgcolor, titleselbordercolor, titleselfloatcolor }, - [SchemeTagsNorm] = { tagsnormfgcolor, tagsnormbgcolor, tagsnormbordercolor, tagsnormfloatcolor }, - [SchemeTagsSel] = { tagsselfgcolor, tagsselbgcolor, tagsselbordercolor, tagsselfloatcolor }, - [SchemeHid] = { hidfgcolor, hidbgcolor, hidbordercolor, hidfloatcolor }, - [SchemeUrg] = { urgfgcolor, urgbgcolor, urgbordercolor, urgfloatcolor }, + /* fg bg border float */ + [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor, normfloatcolor }, + [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor, selfloatcolor }, + [SchemeTitleNorm] = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor }, + [SchemeTitleSel] = { titleselfgcolor, titleselbgcolor, titleselbordercolor, titleselfloatcolor }, + [SchemeTagsNorm] = { tagsnormfgcolor, tagsnormbgcolor, tagsnormbordercolor, tagsnormfloatcolor }, + [SchemeTagsSel] = { tagsselfgcolor, tagsselbgcolor, tagsselbordercolor, tagsselfloatcolor }, + [SchemeHid] = { hidfgcolor, hidbgcolor, hidbordercolor, hidfloatcolor }, + [SchemeUrg] = { urgfgcolor, urgbgcolor, urgbordercolor, urgfloatcolor }, }; #endif // BAR_POWERLINE_STATUS_PATCH @@ -295,15 +295,38 @@ static Sp scratchpads[] = { }; #endif // SCRATCHPADS_PATCH -/* tagging */ -#if BAR_EWMHTAGS_PATCH -static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -#else -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -#endif // BAR_EWMHTAGS_PATCH -#if BAR_ALTERNATIVE_TAGS_PATCH -static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -#endif // BAR_ALTERNATIVE_TAGS_PATCH +/* Tags + * In a traditional dwm the number of tags in use can be changed simply by changing the number + * of strings in the tags array. This build does things a bit different which has some added + * benefits. If you need to change the number of tags here then change the NUMTAGS macro in dwm.c. + * + * Examples: + * + * 1) static char *tagicons[][NUMTAGS*2] = { + * [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" }, + * } + * + * 2) static char *tagicons[][1] = { + * [DEFAULT_TAGS] = { "•" }, + * } + * + * The first example would result in the tags on the first monitor to be 1 through 9, while the + * tags for the second monitor would be named A through I. A third monitor would start again at + * 1 through 9 while the tags on a fourth monitor would also be named A through I. Note the tags + * count of NUMTAGS*2 in the array initialiser which defines how many tag text / icon exists in + * the array. This can be changed to *3 to add separate icons for a third monitor. + * + * For the second example each tag would be represented as a bullet point. Both cases work the + * same from a technical standpoint - the icon index is derived from the tag index and the monitor + * index. If the icon index is is greater than the number of tag icons then it will wrap around + * until it an icon matches. Similarly if there are two tag icons then it would alternate between + * them. This works seamlessly with alternative tags and alttagsdecoration patches. + */ +static char *tagicons[][NUMTAGS] = { + [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, + [ALTERNATIVE_TAGS] = { "A", "B", "C", "D", "E", "F", "G", "H", "I" }, + [ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" }, +}; #if BAR_TAGGRID_PATCH /* grid of tags */ @@ -461,6 +484,7 @@ static const BarRule barrules[] = { { -1, 1, BAR_ALIGN_LEFT, width_wintitle_floating, draw_wintitle_floating, click_wintitle_floating, "wintitle_floating" }, #endif // BAR_WINTITLE_FLOATING_PATCH #endif // BAR_FLEXWINTITLE_PATCH + { NULL } }; #if DWMC_PATCH diff --git a/dwm.c b/dwm.c index 1ce3639..adf6853 100644 --- a/dwm.c +++ b/dwm.c @@ -45,6 +45,12 @@ #include "drw.h" #include "util.h" +#if BAR_FLEXWINTITLE_PATCH +#ifndef FLEXTILE_DELUXE_LAYOUT +#define FLEXTILE_DELUXE_LAYOUT 1 +#endif +#endif + #if BAR_PANGO_PATCH #include #endif // BAR_PANGO_PATCH @@ -57,6 +63,7 @@ #endif // SPAWNCMD_PATCH /* macros */ +#define NUMTAGS 9 #define BARRULES 20 #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) @@ -79,12 +86,12 @@ #define HEIGHT(X) ((X)->h + 2 * (X)->bw) #define WTYPE "_NET_WM_WINDOW_TYPE_" #if SCRATCHPADS_PATCH -#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads)) -#define TAGMASK ((1 << NUMTAGS) - 1) -#define SPTAG(i) ((1 << LENGTH(tags)) << (i)) -#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags)) +#define TOTALTAGS (NUMTAGS + LENGTH(scratchpads)) +#define TAGMASK ((1 << TOTALTAGS) - 1) +#define SPTAG(i) ((1 << NUMTAGS) << (i)) +#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << NUMTAGS) #else -#define TAGMASK ((1 << LENGTH(tags)) - 1) +#define TAGMASK ((1 << NUMTAGS) - 1) #endif // SCRATCHPADS_PATCH #define TEXTWM(X) (drw_fontset_getwidth(drw, (X), True) + lrpad) #define TEXTW(X) (drw_fontset_getwidth(drw, (X), False) + lrpad) @@ -364,6 +371,7 @@ typedef struct { typedef struct Pertag Pertag; #endif // PERTAG_PATCH struct Monitor { + int index; char ltsymbol[16]; float mfact; #if FLEXTILE_DELUXE_LAYOUT @@ -670,9 +678,9 @@ static Window root, wmcheckwin; /* compile-time check if all tags fit into an unsigned int bit array. */ #if SCRATCHPAD_ALT_1_PATCH -struct NumTags { char limitexceeded[LENGTH(tags) > 30 ? -1 : 1]; }; +struct NumTags { char limitexceeded[NUMTAGS > 30 ? -1 : 1]; }; #else -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; +struct NumTags { char limitexceeded[NUMTAGS > 31 ? -1 : 1]; }; #endif // SCRATCHPAD_ALT_1_PATCH /* function implementations */ @@ -911,7 +919,7 @@ attachstack(Client *c) void buttonpress(XEvent *e) { - int click, i, r, mi; + int click, i, r; Arg arg = {0}; Client *c; Monitor *m; @@ -931,14 +939,13 @@ buttonpress(XEvent *e) focus(NULL); } - for (mi = 0, m = mons; m && m != selmon; m = m->next, mi++); // get the monitor index for (bar = selmon->bar; bar; bar = bar->next) { if (ev->window == bar->win) { for (r = 0; r < LENGTH(barrules); r++) { br = &barrules[r]; if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->clickfunc == NULL) continue; - if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi) + if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->index) continue; if (bar->x[r] <= ev->x && ev->x <= bar->x[r] + bar->w[r]) { carg.rel_x = ev->x - bar->x[r]; @@ -1133,8 +1140,8 @@ clientmessage(XEvent *e) selmon = c->mon; focus(c); } else { - for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++); - if (i < LENGTH(tags)) { + for (i = 0; i < NUMTAGS && !((1 << i) & c->tags); i++); + if (i < NUMTAGS) { const Arg a = {.ui = 1 << i}; selmon = c->mon; view(&a); @@ -1312,8 +1319,8 @@ createmon(void) m->gappoh = gappoh; m->gappov = gappov; #endif // VANITYGAPS_PATCH - for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index + m->index = mi; #if MONITOR_RULES_PATCH for (j = 0; j < LENGTH(monrules); j++) { mr = &monrules[j]; @@ -1374,7 +1381,7 @@ createmon(void) if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); m->pertag->curtag = m->pertag->prevtag = 1; - for (i = 0; i <= LENGTH(tags); i++) { + for (i = 0; i <= NUMTAGS; i++) { #if FLEXTILE_DELUXE_LAYOUT m->pertag->nstacks[i] = m->nstack; #endif // FLEXTILE_DELUXE_LAYOUT @@ -1522,14 +1529,12 @@ drawbarwin(Bar *bar) { if (!bar->win) return; - Monitor *mon; - int r, w, mi, total_drawn = 0; + int r, w, total_drawn = 0; int rx, lx, rw, lw; // bar size, split between left and right if a center module is added const BarRule *br; BarWidthArg warg = { 0 }; BarDrawArg darg = { 0, 0 }; - for (mi = 0, mon = mons; mon && mon != bar->mon; mon = mon->next, mi++); // get the monitor index rw = lw = bar->bw; rx = lx = 0; @@ -1539,7 +1544,7 @@ drawbarwin(Bar *bar) br = &barrules[r]; if (br->bar != bar->idx || br->drawfunc == NULL || (br->monitor == 'A' && bar->mon != selmon)) continue; - if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi) + if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->index) continue; drw_setscheme(drw, scheme[SchemeNorm]); warg.max_width = (br->alignment < BAR_ALIGN_RIGHT_LEFT ? lw : rw); @@ -3630,7 +3635,6 @@ updatebarpos(Monitor *m) bar->by = -bh - y_pad; if (!m->showbar) return; - for (num_bars = 0, bar = m->bar; bar; bar = bar->next) { if (!bar->showbar) continue; @@ -3639,7 +3643,6 @@ updatebarpos(Monitor *m) num_bars++; } m->wh = m->wh - y_pad * num_bars - bh * num_bars; - for (bar = m->bar; bar; bar = bar->next) bar->by = (bar->topbar ? m->wy - bh : m->wy + m->wh); } @@ -3720,6 +3723,8 @@ updategeom(void) cleanupmon(m); } } + for (i = 0, m = mons; m; m = m->next, i++) + m->index = i; free(unique); } else #endif /* XINERAMA */ diff --git a/patch/bar_ewmhtags.c b/patch/bar_ewmhtags.c index 682d900..ee17ac6 100644 --- a/patch/bar_ewmhtags.c +++ b/patch/bar_ewmhtags.c @@ -8,15 +8,19 @@ setcurrentdesktop(void) void setdesktopnames(void) { + int i; XTextProperty text; - Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text); + char *tags[NUMTAGS]; + for (i = 0; i < NUMTAGS; i++) + tags[i] = tagicon(selmon, i); + Xutf8TextListToTextProperty(dpy, tags, NUMTAGS, XUTF8StringStyle, &text); XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]); } void setnumdesktops(void) { - long data[] = { TAGSLENGTH }; + long data[] = { NUMTAGS }; XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); } diff --git a/patch/bar_ewmhtags.h b/patch/bar_ewmhtags.h index 2ec890e..937f1f6 100644 --- a/patch/bar_ewmhtags.h +++ b/patch/bar_ewmhtags.h @@ -1,5 +1,3 @@ -#define TAGSLENGTH (LENGTH(tags)) - static void setcurrentdesktop(void); static void setdesktopnames(void); static void setnumdesktops(void); diff --git a/patch/bar_flexwintitle.c b/patch/bar_flexwintitle.c index 8a460b2..4e2ecc9 100644 --- a/patch/bar_flexwintitle.c +++ b/patch/bar_flexwintitle.c @@ -198,7 +198,7 @@ flextitledraw(Monitor *m, Client *c, int unused, int x, int w, int tabscheme, Ar XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w, 0, 1, bh); } /* Optional tags icons */ - for (i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < NUMTAGS; i++) { if ((m->tagset[m->seltags] >> i) & 1) nviewtags++; if ((c->tags >> i) & 1) diff --git a/patch/bar_indicators.c b/patch/bar_indicators.c index 863923e..cd31929 100644 --- a/patch/bar_indicators.c +++ b/patch/bar_indicators.c @@ -50,13 +50,13 @@ drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int w, unsigned in case INDICATOR_RIGHT_TAGS: if (!c) break; - for (i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < NUMTAGS; i++) { drw_rect(drw, - ( x + w - 2 - ((LENGTH(tags) / TAGSROWS) * TAGSPX) - - (i % (LENGTH(tags)/TAGSROWS)) + ((i % (LENGTH(tags) / TAGSROWS)) * TAGSPX) + ( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX) + - (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX) ), - ( 2 + ((i / (LENGTH(tags)/TAGSROWS)) * TAGSPX) - - ((i / (LENGTH(tags)/TAGSROWS))) + ( 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX) + - ((i / (NUMTAGS/TAGSROWS))) ), TAGSPX, TAGSPX, (c->tags >> i) & 1, 0 ); diff --git a/patch/bar_powerline_tags.c b/patch/bar_powerline_tags.c index b627c8f..44acf15 100644 --- a/patch/bar_powerline_tags.c +++ b/patch/bar_powerline_tags.c @@ -10,16 +10,12 @@ width_pwrl_tags(Bar *bar, BarWidthArg *a) occ |= c->tags == 255 ? 0 : c->tags; #endif // BAR_HIDEVACANTTAGS_PATCH - for (w = 0, i = 0; i < LENGTH(tags); i++) { + for (w = 0, i = 0; i < NUMTAGS; i++) { #if BAR_HIDEVACANTTAGS_PATCH if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH - #if BAR_ALTERNATIVE_TAGS_PATCH - w += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]) + plw; - #else - w += TEXTW(tags[i]) + plw; - #endif // BAR_ALTERNATIVE_TAGS_PATCH + w += TEXTW(tagicon(bar->mon, i)) + plw; } return w + lrpad; } @@ -31,6 +27,7 @@ draw_pwrl_tags(Bar *bar, BarDrawArg *a) int invert; int plw = drw->fonts->h / 2 + 1; unsigned int i, occ = 0, urg = 0; + char *icon; Client *c; Clr *prevscheme, *nxtscheme; @@ -45,14 +42,16 @@ draw_pwrl_tags(Bar *bar, BarDrawArg *a) } x = a->x; prevscheme = scheme[SchemeNorm]; - for (i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < NUMTAGS; i++) { #if BAR_HIDEVACANTTAGS_PATCH /* do not draw vacant tags */ if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH + + icon = tagicon(bar->mon, i); invert = 0; - w = TEXTW(tags[i]); + w = TEXTW(icon); drw_settrans(drw, prevscheme, (nxtscheme = scheme[bar->mon->tagset[bar->mon->seltags] & 1 << i ? SchemeSel : SchemeNorm])); #if BAR_POWERLINE_TAGS_SLASH_PATCH drw_arrow(drw, x, 0, plw, bh, 1, 1); @@ -61,7 +60,7 @@ draw_pwrl_tags(Bar *bar, BarDrawArg *a) #endif // BAR_POWERLINE_TAGS_SLASH_PATCH x += plw; drw_setscheme(drw, nxtscheme); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], invert, False); + drw_text(drw, x, 0, w, bh, lrpad / 2, icon, invert, False); drawindicator(bar->mon, NULL, occ, x, w, i, -1, invert, tagindicatortype); x += w; prevscheme = nxtscheme; @@ -94,13 +93,9 @@ click_pwrl_tags(Bar *bar, Arg *arg, BarClickArg *a) if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH - #if BAR_ALTERNATIVE_TAGS_PATCH - x += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]) + plw; - #else - x += TEXTW(tags[i]) + plw; - #endif - } while (a->rel_x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { + x += TEXTW(tagicon(bar->mon, i)) + plw; + } while (a->rel_x >= x && ++i < NUMTAGS); + if (i < NUMTAGS) { arg->ui = 1 << i; } return ClkTagBar; diff --git a/patch/bar_tabgroups.c b/patch/bar_tabgroups.c index 798f67b..153a533 100644 --- a/patch/bar_tabgroups.c +++ b/patch/bar_tabgroups.c @@ -69,7 +69,7 @@ bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w, 0, 1, bh); } /* Optional tags icons */ - for (i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < NUMTAGS; i++) { if ((m->tagset[m->seltags] >> i) & 1) nviewtags++; if ((c->tags >> i) & 1) diff --git a/patch/bar_taggrid.c b/patch/bar_taggrid.c index 0bdf105..1c782da 100644 --- a/patch/bar_taggrid.c +++ b/patch/bar_taggrid.c @@ -1,7 +1,7 @@ int width_taggrid(Bar *bar, BarWidthArg *a) { - return (bh / 2) * (LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0)) + lrpad; + return (bh / 2) * (NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0)) + lrpad; } int @@ -17,17 +17,17 @@ draw_taggrid(Bar *bar, BarDrawArg *a) max_x = x = a->x + lrpad / 2; h = bh / tagrows; y = 0; - columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); + columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); /* Firstly we will fill the borders of squares */ XSetForeground(drw->dpy, drw->gc, scheme[SchemeTagsNorm][ColBg].pixel); XFillRectangle(dpy, drw->drawable, drw->gc, x, y, h*columns + 1, bh); - /* We will draw LENGTH(tags) squares in tagraws raws. */ + /* We will draw NUMTAGS squares in tagraws raws. */ for (j = 0, i = 0; j < tagrows; j++) { x = a->x + lrpad / 2; for (k = 0; k < columns; k++, i++) { - if (i < LENGTH(tags)) { + if (i < NUMTAGS) { invert = bar->mon->tagset[bar->mon->seltags] & 1 << i ? 0 : 1; /* Select active color for current square */ @@ -61,10 +61,10 @@ click_taggrid(Bar *bar, Arg *arg, BarClickArg *a) { unsigned int i, columns; - columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); + columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); i = (a->rel_x - lrpad / 2) / (bh / tagrows) + columns * (a->rel_y / (bh / tagrows)); - if (i >= LENGTH(tags)) { - i = LENGTH(tags) - 1; + if (i >= NUMTAGS) { + i = NUMTAGS - 1; } arg->ui = 1 << i; return ClkTagBar; @@ -79,9 +79,9 @@ switchtag(const Arg *arg) int col, row; Arg new_arg; - columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); + columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); - for (i = 0; i < LENGTH(tags); ++i) { + for (i = 0; i < NUMTAGS; ++i) { if (!(selmon->tagset[selmon->seltags] & 1 << i)) { continue; } @@ -96,7 +96,7 @@ switchtag(const Arg *arg) do { pos = row * columns + col; row --; - } while (pos >= LENGTH(tags)); + } while (pos >= NUMTAGS); } if (arg->ui & SWITCHTAG_DOWN) { /* DOWN */ row ++; @@ -104,7 +104,7 @@ switchtag(const Arg *arg) row = 0; } pos = row * columns + col; - if (pos >= LENGTH(tags)) { + if (pos >= NUMTAGS) { row = 0; } pos = row * columns + col; @@ -117,7 +117,7 @@ switchtag(const Arg *arg) do { pos = row * columns + col; col --; - } while (pos >= LENGTH(tags)); + } while (pos >= NUMTAGS); } if (arg->ui & SWITCHTAG_RIGHT) { /* RIGHT */ col ++; @@ -125,7 +125,7 @@ switchtag(const Arg *arg) col = 0; } pos = row * columns + col; - if (pos >= LENGTH(tags)) { + if (pos >= NUMTAGS) { col = 0; pos = row * columns + col; } diff --git a/patch/bar_tagicons.c b/patch/bar_tagicons.c new file mode 100644 index 0000000..d472407 --- /dev/null +++ b/patch/bar_tagicons.c @@ -0,0 +1,20 @@ +char * +tagicon(Monitor *m, int tag) +{ + #if BAR_ALTTAGSDECORATION_PATCH + Client *c; + #endif // BAR_ALTTAGSDECORATION_PATCH + int tagindex = tag + NUMTAGS * m->index; + if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) + tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]); + #if BAR_ALTTAGSDECORATION_PATCH + for (c = m->clients; c && (!(c->tags & 1 << tag) || HIDDEN(c)); c = c->next); + if (c) + return tagicons[ALT_TAGS_DECORATION][tagindex]; + #endif // BAR_ALTTAGSDECORATION_PATCH + #if BAR_ALTERNATIVE_TAGS_PATCH + if (m->alttag) + return tagicons[ALTERNATIVE_TAGS][tagindex]; + #endif // BAR_ALTERNATIVE_TAGS_PATCH + return tagicons[DEFAULT_TAGS][tagindex]; +} \ No newline at end of file diff --git a/patch/bar_tagicons.h b/patch/bar_tagicons.h new file mode 100644 index 0000000..be5d35c --- /dev/null +++ b/patch/bar_tagicons.h @@ -0,0 +1,7 @@ +enum { + DEFAULT_TAGS, + ALTERNATIVE_TAGS, + ALT_TAGS_DECORATION, +}; + +static char * tagicon(Monitor *m, int tag); \ No newline at end of file diff --git a/patch/bar_tags.c b/patch/bar_tags.c index 895d244..dd57e0b 100644 --- a/patch/bar_tags.c +++ b/patch/bar_tags.c @@ -9,16 +9,12 @@ width_tags(Bar *bar, BarWidthArg *a) occ |= c->tags == 255 ? 0 : c->tags; #endif // BAR_HIDEVACANTTAGS_PATCH - for (w = 0, i = 0; i < LENGTH(tags); i++) { + for (w = 0, i = 0; i < NUMTAGS; i++) { #if BAR_HIDEVACANTTAGS_PATCH if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH - #if BAR_ALTERNATIVE_TAGS_PATCH - w += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]); - #else - w += TEXTW(tags[i]); - #endif // BAR_ALTERNATIVE_TAGS_PATCH + w += TEXTW(tagicon(bar->mon, i)); } return w; } @@ -28,10 +24,8 @@ draw_tags(Bar *bar, BarDrawArg *a) { int invert; int w, x = a->x; - #if BAR_ALTERNATIVE_TAGS_PATCH - int wdelta; - #endif // BAR_ALTERNATIVE_TAGS_PATCH unsigned int i, occ = 0, urg = 0; + char *icon; Client *c; Monitor *m = bar->mon; @@ -44,18 +38,16 @@ draw_tags(Bar *bar, BarDrawArg *a) if (c->isurgent) urg |= c->tags; } - - for (i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < NUMTAGS; i++) { #if BAR_HIDEVACANTTAGS_PATCH /* do not draw vacant tags */ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH + + icon = tagicon(bar->mon, i); invert = 0; - w = TEXTW(tags[i]); - #if BAR_ALTERNATIVE_TAGS_PATCH - wdelta = selmon->alttag ? abs(TEXTW(tags[i]) - TEXTW(tagsalt[i])) / 2 : 0; - #endif // BAR_ALTERNATIVE_TAGS_PATCH + w = TEXTW(icon); drw_setscheme(drw, scheme[ m->tagset[m->seltags] & 1 << i ? SchemeTagsSel @@ -63,11 +55,7 @@ draw_tags(Bar *bar, BarDrawArg *a) ? SchemeUrg : SchemeTagsNorm ]); - #if BAR_ALTERNATIVE_TAGS_PATCH - drw_text(drw, x, 0, w, bh, wdelta + lrpad / 2, (selmon->alttag ? tagsalt[i] : tags[i]), invert, False); - #else - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], invert, False); - #endif // BAR_ALTERNATIVE_TAGS_PATCH + drw_text(drw, x, 0, w, bh, lrpad / 2, icon, invert, False); drawindicator(m, NULL, occ, x, w, i, -1, invert, tagindicatortype); x += w; } @@ -91,13 +79,9 @@ click_tags(Bar *bar, Arg *arg, BarClickArg *a) if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) continue; #endif // BAR_HIDEVACANTTAGS_PATCH - #if BAR_ALTERNATIVE_TAGS_PATCH - x += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]); - #else - x += TEXTW(tags[i]); - #endif - } while (a->rel_x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { + x += TEXTW(tagicon(bar->mon, i)); + } while (a->rel_x >= x && ++i < NUMTAGS); + if (i < NUMTAGS) { arg->ui = 1 << i; } return ClkTagBar; diff --git a/patch/focusurgent.c b/patch/focusurgent.c index 67d71bc..cebb5a3 100644 --- a/patch/focusurgent.c +++ b/patch/focusurgent.c @@ -5,8 +5,8 @@ focusurgent(const Arg *arg) int i; for (c=selmon->clients; c && !c->isurgent; c=c->next); if (c) { - for (i=0; i < LENGTH(tags) && !((1 << i) & c->tags); i++); - if (i < LENGTH(tags)) { + for (i=0; i < NUMTAGS && !((1 << i) & c->tags); i++); + if (i < NUMTAGS) { const Arg a = {.ui = 1 << i}; view(&a); focus(c); diff --git a/patch/include.c b/patch/include.c index b2ec79d..606377e 100644 --- a/patch/include.c +++ b/patch/include.c @@ -1,5 +1,7 @@ /* Bar functionality */ #include "bar_indicators.c" +#include "bar_tagicons.c" + #if BAR_ALPHA_PATCH #include "bar_alpha.c" #endif diff --git a/patch/include.h b/patch/include.h index 0647a64..3961d41 100644 --- a/patch/include.h +++ b/patch/include.h @@ -1,5 +1,7 @@ /* Bar functionality */ #include "bar_indicators.h" +#include "bar_tagicons.h" + #if BAR_ALPHA_PATCH #include "bar_alpha.h" #endif diff --git a/patch/pertag.c b/patch/pertag.c index cc97a6c..2889e0e 100644 --- a/patch/pertag.c +++ b/patch/pertag.c @@ -1,26 +1,26 @@ struct Pertag { unsigned int curtag, prevtag; /* current and previous tag */ - int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ + int nmasters[NUMTAGS + 1]; /* number of windows in master area */ #if FLEXTILE_DELUXE_LAYOUT - int nstacks[LENGTH(tags) + 1]; /* number of windows in primary stack area */ - int ltaxis[LENGTH(tags) + 1][LTAXIS_LAST]; - const Layout *ltidxs[LENGTH(tags) + 1][3]; /* matrix of tags and layouts indexes */ + int nstacks[NUMTAGS + 1]; /* number of windows in primary stack area */ + int ltaxis[NUMTAGS + 1][LTAXIS_LAST]; + const Layout *ltidxs[NUMTAGS + 1][3]; /* matrix of tags and layouts indexes */ #else - const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ + const Layout *ltidxs[NUMTAGS + 1][2]; /* matrix of tags and layouts indexes */ #endif // FLEXTILE_DELUXE_LAYOUT - float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ - unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ + float mfacts[NUMTAGS + 1]; /* mfacts per tag */ + unsigned int sellts[NUMTAGS + 1]; /* selected layouts */ #if PERTAGBAR_PATCH - int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ + int showbars[NUMTAGS + 1]; /* display bar for the current tag */ #endif // PERTAGBAR_PATCH #if SWAPFOCUS_PATCH - Client *prevclient[LENGTH(tags) + 1]; + Client *prevclient[NUMTAGS + 1]; #endif // SWAPFOCUS_PATCH #if ZOOMSWAP_PATCH - Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ + Client *prevzooms[NUMTAGS + 1]; /* store zoom information */ #endif // ZOOMSWAP_PATCH #if VANITYGAPS_PATCH - int enablegaps[LENGTH(tags) + 1]; + int enablegaps[NUMTAGS + 1]; #endif // VANITYGAPS_PATCH }; @@ -29,7 +29,6 @@ pertagview(const Arg *arg) { int i; unsigned int tmptag; - if (arg->ui & TAGMASK) { selmon->pertag->prevtag = selmon->pertag->curtag; selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; @@ -52,6 +51,7 @@ pertagview(const Arg *arg) selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + #if FLEXTILE_DELUXE_LAYOUT selmon->ltaxis[LAYOUT] = selmon->pertag->ltaxis[selmon->pertag->curtag][LAYOUT]; selmon->ltaxis[MASTER] = selmon->pertag->ltaxis[selmon->pertag->curtag][MASTER]; diff --git a/patch/reorganizetags.c b/patch/reorganizetags.c index 3c0211d..da27ecd 100644 --- a/patch/reorganizetags.c +++ b/patch/reorganizetags.c @@ -3,13 +3,13 @@ reorganizetags(const Arg *arg) { Client *c; unsigned int occ, unocc, i; - unsigned int tagdest[LENGTH(tags)]; + unsigned int tagdest[NUMTAGS]; occ = 0; for (c = selmon->clients; c; c = c->next) occ |= (1 << (ffs(c->tags)-1)); unocc = 0; - for (i = 0; i < LENGTH(tags); ++i) { + for (i = 0; i < NUMTAGS; ++i) { while (unocc < i && (occ & (1 << unocc))) unocc++; if (occ & (1 << i)) { diff --git a/patch/shiftview.c b/patch/shiftview.c index 65a3dd6..c4494dc 100644 --- a/patch/shiftview.c +++ b/patch/shiftview.c @@ -5,11 +5,11 @@ shiftview(const Arg *arg) if (arg->i > 0) // left circular shift shifted.ui = (selmon->tagset[selmon->seltags] << arg->i) - | (selmon->tagset[selmon->seltags] >> (LENGTH(tags) - arg->i)); + | (selmon->tagset[selmon->seltags] >> (NUMTAGS - arg->i)); else // right circular shift shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i) - | selmon->tagset[selmon->seltags] << (LENGTH(tags) + arg->i); + | selmon->tagset[selmon->seltags] << (NUMTAGS + arg->i); view(&shifted); } diff --git a/patch/shiftviewclients.c b/patch/shiftviewclients.c index 5148c11..a0b2e81 100644 --- a/patch/shiftviewclients.c +++ b/patch/shiftviewclients.c @@ -20,12 +20,12 @@ shiftviewclients(const Arg *arg) if (arg->i > 0) // left circular shift do { shifted.ui = (shifted.ui << arg->i) - | (shifted.ui >> (LENGTH(tags) - arg->i)); + | (shifted.ui >> (NUMTAGS - arg->i)); } while (tagmask && !(shifted.ui & tagmask)); else // right circular shift do { shifted.ui = (shifted.ui >> (- arg->i) - | shifted.ui << (LENGTH(tags) + arg->i)); + | shifted.ui << (NUMTAGS + arg->i)); } while (tagmask && !(shifted.ui & tagmask)); view(&shifted); diff --git a/patch/tagall.c b/patch/tagall.c index e978aaf..81f44e0 100644 --- a/patch/tagall.c +++ b/patch/tagall.c @@ -8,11 +8,11 @@ tagall(const Arg *arg) int tag = (char *)arg->v ? atoi(((char *)arg->v) + floating_only) : 0; int j; Client* c; - if (tag >= 0 && tag < LENGTH(tags)) + if (tag >= 0 && tag < NUMTAGS) for (c = selmon->clients; c; c = c->next) { if (!floating_only || c->isfloating) - for (j = 0; j < LENGTH(tags); j++) + for (j = 0; j < NUMTAGS; j++) { if (c->tags & 1 << j && selmon->tagset[selmon->seltags] & 1 << j) { diff --git a/patches.def.h b/patches.def.h index de41a9a..958d109 100644 --- a/patches.def.h +++ b/patches.def.h @@ -67,6 +67,7 @@ * https://gitlab.com/udiboy1209-suckless/dwm/-/commit/071f5063e8ac4280666828179f92788d893eea40#4b1a539194be7467cefbda22f675a3b7c19ceca7 */ #define BAR_POWERLINE_TAGS_PATCH 0 + /* Alters the tags powerline to use forward slash instead of arrows */ #define BAR_POWERLINE_TAGS_SLASH_PATCH 0 @@ -156,6 +157,12 @@ */ #define BAR_ALTERNATIVE_TAGS_PATCH 0 +/* This patches provides the ability to use alternative text for tags which contain at + * least one window. + * https://dwm.suckless.org/patches/alttagsdecoration/ + */ +#define BAR_ALTTAGSDECORATION_PATCH 0 + /* This patch changes the rectangle indicating if a tag is used by a client into a bar * above the tag name for better visibility. * Set the tagindicatortype variable in config.h to INDICATOR_TOP_BAR to enable this.