diff --git a/README.md b/README.md index 42a3b37..dd98d9f 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 ### Changelog: +2022-08-12 - Added the nametag patch + 2022-08-02 - Added the bidi patch 2022-07-05 - Added the tagpreview patch @@ -528,6 +530,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 - [movestack](https://dwm.suckless.org/patches/movestack/) - allows you to move clients around in the stack and swap them with the master + - [nametag](https://dwm.suckless.org/patches/nametag/) + - allows the names of tags to be changed during runtime + - [netclientliststacking](https://github.com/bakkeby/patches/wiki/netclientliststacking) - adds support for the \_NET\_CLIENT\_LIST\_STACKING atom, needed by certain applications like the Zoom video conferencing application diff --git a/config.def.h b/config.def.h index 7a71119..a65e08d 100644 --- a/config.def.h +++ b/config.def.h @@ -106,6 +106,22 @@ static const unsigned int ulinevoffset = 0; /* how far above the bottom of t static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ #endif // BAR_UNDERLINETAGS_PATCH +#if NAMETAG_PATCH +#if NAMETAG_PREPEND_PATCH +/* The format in which the tag is written when named. E.g. %d: %.12s will write the tag number + * followed the first 12 characters of the given string. You can also just use "%d: %s" here. */ +#define NAMETAG_FORMAT "%d: %.12s" +#else +#define NAMETAG_FORMAT "%s" +#endif // NAMETAG_PREPEND_PATCH +/* The maximum amount of bytes reserved for each tag text. */ +#define MAX_TAGLEN 16 +/* The command to run (via popen). This can be tailored by adding a prompt, passing other command + * line arguments or providing name options. Optionally you can use other dmenu like alternatives + * like rofi -dmenu. */ +#define NAMETAG_COMMAND "dmenu < /dev/null" +#endif // NAMETAG_PATCH + /* Indicators: see patch/bar_indicators.h for options */ static int tagindicatortype = INDICATOR_TOP_LEFT_SQUARE; static int tiledindicatortype = INDICATOR_NONE; @@ -411,7 +427,12 @@ static Sp scratchpads[] = { * 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] = { +#if NAMETAG_PATCH +static char tagicons[][NUMTAGS][MAX_TAGLEN] = +#else +static char *tagicons[][NUMTAGS] = +#endif // NAMETAG_PATCH +{ [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>" }, @@ -1140,6 +1161,9 @@ static Key keys[] = { #if BAR_ALTERNATIVE_TAGS_PATCH { MODKEY, XK_n, togglealttag, {0} }, #endif // BAR_ALTERNATIVE_TAGS_PATCH + #if NAMETAG_PATCH + { MODKEY|ShiftMask, XK_n, nametag, {0} }, + #endif // NAMETAG_PATCH #if BAR_TAGGRID_PATCH { MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } }, { MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } }, @@ -1410,6 +1434,9 @@ static Signal signals[] = { #if MOVEPLACE_PATCH { "moveplace", moveplace }, #endif // MOVEPLACE_PATCH + #if NAMETAG_PATCH + { "nametag", nametag }, + #endif // NAMETAG_PATCH #if EXRESIZE_PATCH { "explace", explace }, { "togglehorizontalexpand", togglehorizontalexpand }, @@ -1624,6 +1651,9 @@ static IPCCommand ipccommands[] = { #if MOVERESIZE_PATCH IPCCOMMAND( moveresize, 1, {ARG_TYPE_STR} ), #endif // MOVERESIZE_PATCH + #if NAMETAG_PATCH + IPCCOMMAND( nametag, 1, {ARG_TYPE_NONE} ), + #endif // NAMETAG_PATCH #if RIODRAW_PATCH IPCCOMMAND( rioresize, 1, {ARG_TYPE_NONE} ), #endif // RIODRAW_PATCH diff --git a/patch/dwmc b/patch/dwmc index 9536367..763927c 100755 --- a/patch/dwmc +++ b/patch/dwmc @@ -10,6 +10,7 @@ case $# in focusurgent) ;& mirrorlayout) ;& mpdcontrol) ;& + nametag) ;& pushdown) ;& pushup) ;& self_restart) ;& diff --git a/patch/include.c b/patch/include.c index 33232cf..4263f45 100644 --- a/patch/include.c +++ b/patch/include.c @@ -193,6 +193,9 @@ #if MOVESTACK_PATCH #include "movestack.c" #endif +#if NAMETAG_PATCH +#include "nametag.c" +#endif #if NO_MOD_BUTTONS_PATCH #include "nomodbuttons.c" #endif diff --git a/patch/include.h b/patch/include.h index 2a78292..65e0eda 100644 --- a/patch/include.h +++ b/patch/include.h @@ -192,6 +192,9 @@ #if MOVESTACK_PATCH #include "movestack.h" #endif +#if NAMETAG_PATCH +#include "nametag.h" +#endif #if NO_MOD_BUTTONS_PATCH #include "nomodbuttons.h" #endif diff --git a/patch/nametag.c b/patch/nametag.c new file mode 100644 index 0000000..2b7b038 --- /dev/null +++ b/patch/nametag.c @@ -0,0 +1,61 @@ +void +nametag(const Arg *arg) +{ + char *p, name[MAX_TAGLEN]; + FILE *f; + int i, group; + int tagindex; + Monitor *m = selmon; + #if BAR_ALTTAGSDECORATION_PATCH + Client *c; + int occ = 0; + + for (c = m->clients; c; c = c->next) + occ |= c->tags == 255 ? 0 : c->tags; + #endif // BAR_ALTTAGSDECORATION_PATCH + + errno = 0; // popen(3p) says on failure it "may" set errno + if (!(f = popen(NAMETAG_COMMAND, "r"))) { + fprintf(stderr, "dwm: popen command failed%s%s\n", errno ? ": " : "", errno ? strerror(errno) : ""); + return; + } + + if (!(p = fgets(name, MAX_TAGLEN, f)) && (i = errno) && ferror(f)) + fprintf(stderr, "dwm: fgets failed: %s\n", strerror(i)); + + pclose(f); + + if (!p) + return; + if ((p = strchr(name, '\n'))) + *p = '\0'; + + for (i = 0; i < NUMTAGS; i++) { + if (m->tagset[m->seltags] & (1 << i)) { + + tagindex = i + NUMTAGS * m->num; + if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) + tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]); + + #if BAR_ALTTAGSDECORATION_PATCH + if (occ & 1 << i) + group = ALT_TAGS_DECORATION; + else + #endif // BAR_ALTTAGSDECORATION_PATCH + #if BAR_ALTERNATIVE_TAGS_PATCH + if (m->alttag) + group = ALTERNATIVE_TAGS; + else + #endif // BAR_ALTERNATIVE_TAGS_PATCH + group = DEFAULT_TAGS; + + #if NAMETAG_PREPEND_PATCH + if (snprintf(tagicons[group][i], MAX_TAGLEN, NAMETAG_FORMAT, i+1, name) < 0) + fprintf(stderr, "nametag: if statement to avoid -Wformat-truncation= warnings\n"); + #else + snprintf(tagicons[group][i], MAX_TAGLEN, NAMETAG_FORMAT, name); + #endif // NAMETAG_PREPEND_PATCH + } + } + drawbars(); +} diff --git a/patch/nametag.h b/patch/nametag.h new file mode 100644 index 0000000..3e632be --- /dev/null +++ b/patch/nametag.h @@ -0,0 +1 @@ +static void nametag(const Arg *arg); diff --git a/patches.def.h b/patches.def.h index 2338139..158da7b 100644 --- a/patches.def.h +++ b/patches.def.h @@ -782,6 +782,32 @@ */ #define MOVESTACK_PATCH 0 +/* This patch allows you to change the names of tags during runtime. + * + * This is a bespoke version implemented specifically in relation to tagicons, which is integrated + * into dwm-flexipatch. By default it uses dmenu to retrieve the new name, but this can be + * customised via config along with the maximum text length and the format string. + * + * Special behaviour: + * - if more than one tag is selected then the name change applies to all selected tags + * - if tagicons is configured to have unique tags per monitor then the change only applies + * for the current monitor + * - the name change applies to the tag set that is active for the current tag: + * * if used in combination with BAR_ALTTAGSDECORATION_PATCH and there are clients on the + * given tag then the name change only applies to the ALT_TAGS_DECORATION tag set + * * if used in combination with the BAR_ALTERNATIVE_TAGS_PATCH and alternative tags are + * shown then the name change only applies to the ALTERNATIVE_TAGS tag set + * * if used in combination with both then BAR_ALTTAGSDECORATION_PATCH takes precedence + * * otherwise the name change applies to the DEFAULT_TAGS tag set + * + * https://dwm.suckless.org/patches/nametag/ + */ +#define NAMETAG_PATCH 0 + +/* Variant of the above which prepends the tag number to the given string. + * The toggle does nothing on its own and need to be enabled in combination with the above. */ +#define NAMETAG_PREPEND_PATCH 0 + /* Adds support for the _NET_CLIENT_LIST_STACKING atom, needed by certain applications like the * Zoom video conferencing application. * https://github.com/bakkeby/patches/wiki/netclientliststacking/