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.
This commit is contained in:
bakkeby
2020-08-25 16:27:14 +02:00
parent df57bdeb64
commit f45acf8795
22 changed files with 199 additions and 146 deletions

View File

@@ -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);
}

View File

@@ -1,5 +1,3 @@
#define TAGSLENGTH (LENGTH(tags))
static void setcurrentdesktop(void);
static void setdesktopnames(void);
static void setnumdesktops(void);

View File

@@ -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)

View File

@@ -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
);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}

20
patch/bar_tagicons.c Normal file
View File

@@ -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];
}

7
patch/bar_tagicons.h Normal file
View File

@@ -0,0 +1,7 @@
enum {
DEFAULT_TAGS,
ALTERNATIVE_TAGS,
ALT_TAGS_DECORATION,
};
static char * tagicon(Monitor *m, int tag);

View File

@@ -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;

View File

@@ -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);

View File

@@ -1,5 +1,7 @@
/* Bar functionality */
#include "bar_indicators.c"
#include "bar_tagicons.c"
#if BAR_ALPHA_PATCH
#include "bar_alpha.c"
#endif

View File

@@ -1,5 +1,7 @@
/* Bar functionality */
#include "bar_indicators.h"
#include "bar_tagicons.h"
#if BAR_ALPHA_PATCH
#include "bar_alpha.h"
#endif

View File

@@ -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];

View File

@@ -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)) {

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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)
{