diff --git a/dwm/dwm-tagicons-selected-6.2_full.diff b/dwm/dwm-tagicons-selected-6.2_full.diff new file mode 100644 index 0000000..ebb1ee9 --- /dev/null +++ b/dwm/dwm-tagicons-selected-6.2_full.diff @@ -0,0 +1,330 @@ +From 2e3edb3febae67c7325d1a1846934335403a62f4 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Fri, 4 Dec 2020 12:32:40 +0100 +Subject: [PATCH 1/2] tagicons patch + +Refer to: +https://github.com/bakkeby/patches/wiki/tagicons +--- + config.def.h | 13 +++++-- + dwm.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 99 insertions(+), 12 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..d82e4df 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -18,8 +18,13 @@ static const char *colors[][3] = { + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, + }; + +-/* tagging */ +-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; ++/* tagging: refer to https://github.com/bakkeby/patches/wiki/tagicons */ ++static const char *tags[NUMTAGS] = { NULL }; /* left for compatibility reasons, i.e. code that checks LENGTH(tags) */ ++static char *tagicons[][NUMTAGS] = { ++ [IconsDefault] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, ++ [IconsVacant] = { NULL }, ++ [IconsOccupied] = { NULL }, ++}; + + static const Rule rules[] = { + /* xprop(1): +@@ -84,6 +89,8 @@ static Key keys[] = { + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, ++// { MODKEY|ShiftMask, XK_a, seticonset, {.i = 0 } }, ++// { MODKEY|ShiftMask, XK_b, seticonset, {.i = 1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) +@@ -111,5 +118,7 @@ static Button buttons[] = { + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, ++ { ClkTagBar, 0, Button4, cycleiconset, {.i = +1 } }, ++ { ClkTagBar, 0, Button5, cycleiconset, {.i = -1 } }, + }; + +diff --git a/dwm.c b/dwm.c +index 4465af1..614a9ef 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -45,6 +45,7 @@ + #include "util.h" + + /* macros */ ++#define NUMTAGS 9 /* the number of tags per monitor */ + #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ +@@ -54,7 +55,7 @@ + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) + #define HEIGHT(X) ((X)->h + 2 * (X)->bw) +-#define TAGMASK ((1 << LENGTH(tags)) - 1) ++#define TAGMASK ((1 << NUMTAGS) - 1) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + + /* enums */ +@@ -66,6 +67,12 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ ++enum { ++ IconsDefault, ++ IconsVacant, ++ IconsOccupied, ++ IconsLast ++}; /* icon sets */ + + typedef union { + int i; +@@ -124,6 +131,7 @@ struct Monitor { + unsigned int tagset[2]; + int showbar; + int topbar; ++ int iconset; + Client *clients; + Client *sel; + Client *stack; +@@ -157,6 +165,7 @@ static void configure(Client *c); + static void configurenotify(XEvent *e); + static void configurerequest(XEvent *e); + static Monitor *createmon(void); ++static void cycleiconset(const Arg *arg); + static void destroynotify(XEvent *e); + static void detach(Client *c); + static void detachstack(Client *c); +@@ -169,6 +178,7 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static char * geticon(Monitor *m, int tag, int iconset); + static int getrootptr(int *x, int *y); + static long getstate(Window w); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +@@ -199,6 +209,7 @@ static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); + static void setfullscreen(Client *c, int fullscreen); ++static void seticonset(const Arg *arg); + static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); +@@ -207,6 +218,7 @@ static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); + static void tag(const Arg *arg); ++static char * tagicon(Monitor *m, int tag); + static void tagmon(const Arg *arg); + static void tile(Monitor *); + static void togglebar(const Arg *arg); +@@ -272,7 +284,7 @@ static Window root, wmcheckwin; + #include "config.h" + + /* compile-time check if all tags fit into an unsigned int bit array. */ +-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; ++struct NumTags { char limitexceeded[NUMTAGS > 31 ? -1 : 1]; }; + + /* function implementations */ + void +@@ -416,7 +428,7 @@ attachstack(Client *c) + void + buttonpress(XEvent *e) + { +- unsigned int i, x, click; ++ unsigned int i, x, tw, click; + Arg arg = {0}; + Client *c; + Monitor *m; +@@ -431,10 +443,13 @@ buttonpress(XEvent *e) + } + if (ev->window == selmon->barwin) { + i = x = 0; +- do +- x += TEXTW(tags[i]); +- while (ev->x >= x && ++i < LENGTH(tags)); +- if (i < LENGTH(tags)) { ++ do { ++ tw = TEXTW(tagicon(selmon, i)); ++ if (tw <= lrpad) ++ continue; ++ x += tw; ++ } while (ev->x >= x && ++i < NUMTAGS); ++ if (i < NUMTAGS) { + click = ClkTagBar; + arg.ui = 1 << i; + } else if (ev->x < x + blw) +@@ -644,6 +659,24 @@ createmon(void) + return m; + } + ++void ++cycleiconset(const Arg *arg) ++{ ++ Monitor *m = selmon; ++ if (arg->i == 0) ++ return; ++ if (arg->i > 0) { ++ for (++m->iconset; m->iconset < IconsLast && tagicons[m->iconset][0] == NULL; ++m->iconset); ++ if (m->iconset >= IconsLast) ++ m->iconset = 0; ++ } else if (arg->i < 0) { ++ for (--m->iconset; m->iconset > 0 && tagicons[m->iconset][0] == NULL; --m->iconset); ++ if (m->iconset < 0) ++ for (m->iconset = IconsLast - 1; m->iconset > 0 && tagicons[m->iconset][0] == NULL; --m->iconset); ++ } ++ drawbar(m); ++} ++ + void + destroynotify(XEvent *e) + { +@@ -699,6 +732,7 @@ drawbar(Monitor *m) + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; ++ char *icon; + Client *c; + + /* draw status first so it can be overdrawn by tags later */ +@@ -714,10 +748,13 @@ drawbar(Monitor *m) + urg |= c->tags; + } + x = 0; +- for (i = 0; i < LENGTH(tags); i++) { +- w = TEXTW(tags[i]); ++ for (i = 0; i < NUMTAGS; i++) { ++ icon = tagicon(m, i); ++ w = TEXTW(icon); ++ if (w <= lrpad) ++ continue; + 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); ++ drw_text(drw, x, 0, w, bh, lrpad / 2, icon, urg & 1 << i); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, +@@ -871,6 +908,20 @@ getatomprop(Client *c, Atom prop) + return atom; + } + ++char * ++geticon(Monitor *m, int tag, int iconset) ++{ ++ int i; ++ int tagindex = tag + NUMTAGS * m->num; ++ for (i = 0; i < LENGTH(tagicons[iconset]) && tagicons[iconset][i] != NULL; ++i); ++ if (i == 0) ++ tagindex = 0; ++ else if (tagindex >= i) ++ tagindex = tagindex % i; ++ ++ return tagicons[iconset][tagindex]; ++} ++ + int + getrootptr(int *x, int *y) + { +@@ -1497,6 +1548,15 @@ setfullscreen(Client *c, int fullscreen) + } + } + ++void ++seticonset(const Arg *arg) ++{ ++ if (arg->i >= 0 && arg->i < IconsLast) { ++ selmon->iconset = arg->i; ++ drawbar(selmon); ++ } ++} ++ + void + setlayout(const Arg *arg) + { +@@ -1662,6 +1722,24 @@ tag(const Arg *arg) + } + } + ++char * ++tagicon(Monitor *m, int tag) ++{ ++ Client *c; ++ char *icon; ++ for (c = m->clients; c && (!(c->tags & 1 << tag)); c = c->next); ++ // for (c = m->clients; c && (!(c->tags & 1 << tag) || HIDDEN(c)); c = c->next); // awesomebar / wintitleactions compatibility ++ if (c && tagicons[IconsOccupied][0] != NULL) ++ icon = geticon(m, tag, IconsOccupied); ++ else { ++ icon = geticon(m, tag, m->iconset); ++ if (TEXTW(icon) <= lrpad && m->tagset[m->seltags] & 1 << tag) ++ icon = geticon(m, tag, IconsVacant); ++ } ++ ++ return icon; ++} ++ + void + tagmon(const Arg *arg) + { +-- +2.19.1 + + +From 4c57bc449e5e5ad4d1abde2776bef35c588f023f Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Fri, 19 Feb 2021 09:53:46 +0100 +Subject: [PATCH 2/2] tagicons with separate icon for selected tags + +Example patch ref. +https://www.reddit.com/r/suckless/comments/ln0t41/use_icon_instead_of_rectangle_as/ +--- + config.def.h | 5 +++-- + dwm.c | 5 ++++- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index d82e4df..7607155 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -21,9 +21,10 @@ static const char *colors[][3] = { + /* tagging: refer to https://github.com/bakkeby/patches/wiki/tagicons */ + static const char *tags[NUMTAGS] = { NULL }; /* left for compatibility reasons, i.e. code that checks LENGTH(tags) */ + static char *tagicons[][NUMTAGS] = { +- [IconsDefault] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, ++ [IconsDefault] = { "○" }, + [IconsVacant] = { NULL }, +- [IconsOccupied] = { NULL }, ++ [IconsOccupied] = { "☉" }, ++ [IconsSelected] = { "◉" }, + }; + + static const Rule rules[] = { +diff --git a/dwm.c b/dwm.c +index 614a9ef..b28febd 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -71,6 +71,7 @@ enum { + IconsDefault, + IconsVacant, + IconsOccupied, ++ IconsSelected, + IconsLast + }; /* icon sets */ + +@@ -1729,7 +1730,9 @@ tagicon(Monitor *m, int tag) + char *icon; + for (c = m->clients; c && (!(c->tags & 1 << tag)); c = c->next); + // for (c = m->clients; c && (!(c->tags & 1 << tag) || HIDDEN(c)); c = c->next); // awesomebar / wintitleactions compatibility +- if (c && tagicons[IconsOccupied][0] != NULL) ++ if (m->tagset[m->seltags] & 1 << tag && tagicons[IconsSelected][0] != NULL) ++ icon = geticon(m, tag, IconsSelected); ++ else if (c && tagicons[IconsOccupied][0] != NULL) + icon = geticon(m, tag, IconsOccupied); + else { + icon = geticon(m, tag, m->iconset); +-- +2.19.1 +