URI: 
       Changes to dwm mmnametags patch - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit 8350820566a1bd3129e1fdb8fc115a3a2d2e6161
   DIR parent 962561aa3fc9a8b0fb6c40df8e1e0b82a25013cb
  HTML Author: A-Larsen <austin.larsen@mailfence.com>
       Date:   Thu, 18 Dec 2025 00:48:59 -0500
       
       Changes to dwm mmnametags patch
       
       Better memory management for tagnames in createmon function
       
       Diffstat:
         A dwm.suckless.org/patches/mmnametag… |     155 +++++++++++++++++++++++++++++++
         A dwm.suckless.org/patches/mmnametag… |     157 +++++++++++++++++++++++++++++++
         M dwm.suckless.org/patches/mmnametag… |      11 ++++++++---
       
       3 files changed, 320 insertions(+), 3 deletions(-)
       ---
   DIR diff --git a/dwm.suckless.org/patches/mmnametags/dwm-mmnametags-20251218-7c3abae.diff b/dwm.suckless.org/patches/mmnametags/dwm-mmnametags-20251218-7c3abae.diff
       @@ -0,0 +1,155 @@
       +diff --git a/config.def.h b/config.def.h
       +index 81c3fc0..28daa84 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -19,7 +19,8 @@ static const char *colors[][3]      = {
       + };
       + 
       + /* tagging */
       +-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
       ++#define MAX_TAGLEN 16                        /* altogether */
       ++static char tags[][MAX_TAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
       + 
       + static const Rule rules[] = {
       +         /* xprop(1):
       +@@ -86,6 +87,7 @@ static const Key keys[] = {
       +         { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
       +         { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
       +         { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
       ++        { MODKEY,                       XK_n,      nametag,        {0} },
       +         TAGKEYS(                        XK_1,                      0)
       +         TAGKEYS(                        XK_2,                      1)
       +         TAGKEYS(                        XK_3,                      2)
       +diff --git a/dwm.c b/dwm.c
       +index 4f345ee..1a014be 100644
       +--- a/dwm.c
       ++++ b/dwm.c
       +@@ -47,6 +47,7 @@
       + /* macros */
       + #define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
       + #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
       ++#define SETDMENUMON(m)          m[0] = '0' + selmon->num
       + #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
       +                                * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
       + #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
       +@@ -129,6 +130,7 @@ struct Monitor {
       +         Monitor *next;
       +         Window barwin;
       +         const Layout *lt[2];
       ++        char **tags;
       + };
       + 
       + typedef struct {
       +@@ -183,6 +185,7 @@ static void maprequest(XEvent *e);
       + static void monocle(Monitor *m);
       + static void motionnotify(XEvent *e);
       + static void movemouse(const Arg *arg);
       ++static void nametag(const Arg *arg);
       + static Client *nexttiled(Client *c);
       + static void pop(Client *c);
       + static void propertynotify(XEvent *e);
       +@@ -433,7 +436,7 @@ buttonpress(XEvent *e)
       +         if (ev->window == selmon->barwin) {
       +                 i = x = 0;
       +                 do
       +-                        x += TEXTW(tags[i]);
       ++                        x += TEXTW(m->tags[i]);
       +                 while (ev->x >= x && ++i < LENGTH(tags));
       +                 if (i < LENGTH(tags)) {
       +                         click = ClkTagBar;
       +@@ -499,6 +502,7 @@ void
       + cleanupmon(Monitor *mon)
       + {
       +         Monitor *m;
       ++        unsigned int i;
       + 
       +         if (mon == mons)
       +                 mons = mons->next;
       +@@ -508,6 +512,10 @@ cleanupmon(Monitor *mon)
       +         }
       +         XUnmapWindow(dpy, mon->barwin);
       +         XDestroyWindow(dpy, mon->barwin);
       ++        for (i = 0; i <= LENGTH(tags); i++) {
       ++                free(mon->tags[i]);
       ++        }
       ++        free(mon->tags);
       +         free(mon);
       + }
       + 
       +@@ -633,6 +641,7 @@ Monitor *
       + createmon(void)
       + {
       +         Monitor *m;
       ++        unsigned int i;
       + 
       +         m = ecalloc(1, sizeof(Monitor));
       +         m->tagset[0] = m->tagset[1] = 1;
       +@@ -643,6 +652,16 @@ createmon(void)
       +         m->lt[0] = &layouts[0];
       +         m->lt[1] = &layouts[1 % LENGTH(layouts)];
       +         strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
       ++
       ++        m->tags = ecalloc(LENGTH(tags), sizeof(char) * (MAX_TAGLEN + 1));
       ++
       ++        for (i = 0; i <= LENGTH(tags); i++) {
       ++                m->tags[i] = ecalloc(1, sizeof(char) * (MAX_TAGLEN + 1));
       ++                memset(m->tags[i], 0, MAX_TAGLEN);
       ++                unsigned char slen = strlen(tags[i]);
       ++                unsigned char len = slen >= MAX_TAGLEN ? MAX_TAGLEN : slen;
       ++                memcpy(m->tags[i], tags[i], sizeof(char) * len);
       ++        }
       +         return m;
       + }
       + 
       +@@ -720,9 +739,9 @@ drawbar(Monitor *m)
       +         }
       +         x = 0;
       +         for (i = 0; i < LENGTH(tags); i++) {
       +-                w = TEXTW(tags[i]);
       ++                w = TEXTW(m->tags[i]);
       +                 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, m->tags[i], urg & 1 << i);
       +                 if (occ & 1 << i)
       +                         drw_rect(drw, x + boxs, boxs, boxw, boxw,
       +                                 m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
       +@@ -1201,6 +1220,39 @@ movemouse(const Arg *arg)
       +         }
       + }
       + 
       ++void
       ++nametag(const Arg *arg) {
       ++        char *p, name[MAX_TAGLEN];
       ++        FILE *f;
       ++        int i;
       ++        char dmenumon[2];
       ++        char cmd[25];
       ++
       ++        SETDMENUMON(dmenumon);
       ++        memset(cmd, 0, 25);
       ++        sprintf(cmd, "dmenu -m %s < /dev/null", dmenumon);
       ++        errno = 0; // popen(3p) says on failure it "may" set errno
       ++
       ++        if(!(f = popen(cmd, "r"))) {
       ++                fprintf(stderr, "dwm: popen 'dmenu < /dev/null' 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));
       ++        if (pclose(f) < 0)
       ++                fprintf(stderr, "dwm: pclose failed: %s\n", strerror(errno));
       ++        if(!p)
       ++                return;
       ++        if((p = strchr(name, '\n')))
       ++                *p = '\0';
       ++
       ++        for(i = 0; i < LENGTH(tags); i++)
       ++                if(selmon->tagset[selmon->seltags] & (1 << i)) {
       ++                        strcpy(selmon->tags[i], name);
       ++                }
       ++        drawbars();
       ++}
       ++
       + Client *
       + nexttiled(Client *c)
       + {
   DIR diff --git a/dwm.suckless.org/patches/mmnametags/dwm-mmnametags-prepend-20251218-7c3abae.diff b/dwm.suckless.org/patches/mmnametags/dwm-mmnametags-prepend-20251218-7c3abae.diff
       @@ -0,0 +1,157 @@
       +diff --git a/config.def.h b/config.def.h
       +index 81c3fc0..7492c0f 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -19,7 +19,9 @@ static const char *colors[][3]      = {
       + };
       + 
       + /* tagging */
       +-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
       ++#define MAX_TAGLEN 16                        /* altogether */
       ++#define TAG_PREPEND "%1i:"                /* formatted as 2 chars */
       ++static char tags[][MAX_TAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
       + 
       + static const Rule rules[] = {
       +         /* xprop(1):
       +@@ -86,6 +88,7 @@ static const Key keys[] = {
       +         { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
       +         { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
       +         { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
       ++        { MODKEY,                       XK_n,      nametag,        {0} },
       +         TAGKEYS(                        XK_1,                      0)
       +         TAGKEYS(                        XK_2,                      1)
       +         TAGKEYS(                        XK_3,                      2)
       +diff --git a/dwm.c b/dwm.c
       +index 4f345ee..3c33b17 100644
       +--- a/dwm.c
       ++++ b/dwm.c
       +@@ -47,6 +47,7 @@
       + /* macros */
       + #define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
       + #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
       ++#define SETDMENUMON(m)          m[0] = '0' + selmon->num
       + #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
       +                                * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
       + #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
       +@@ -129,6 +130,7 @@ struct Monitor {
       +         Monitor *next;
       +         Window barwin;
       +         const Layout *lt[2];
       ++        char **tags;
       + };
       + 
       + typedef struct {
       +@@ -183,6 +185,7 @@ static void maprequest(XEvent *e);
       + static void monocle(Monitor *m);
       + static void motionnotify(XEvent *e);
       + static void movemouse(const Arg *arg);
       ++static void nametag(const Arg *arg);
       + static Client *nexttiled(Client *c);
       + static void pop(Client *c);
       + static void propertynotify(XEvent *e);
       +@@ -433,7 +436,7 @@ buttonpress(XEvent *e)
       +         if (ev->window == selmon->barwin) {
       +                 i = x = 0;
       +                 do
       +-                        x += TEXTW(tags[i]);
       ++                        x += TEXTW(m->tags[i]);
       +                 while (ev->x >= x && ++i < LENGTH(tags));
       +                 if (i < LENGTH(tags)) {
       +                         click = ClkTagBar;
       +@@ -499,6 +502,7 @@ void
       + cleanupmon(Monitor *mon)
       + {
       +         Monitor *m;
       ++        unsigned int i;
       + 
       +         if (mon == mons)
       +                 mons = mons->next;
       +@@ -508,6 +512,10 @@ cleanupmon(Monitor *mon)
       +         }
       +         XUnmapWindow(dpy, mon->barwin);
       +         XDestroyWindow(dpy, mon->barwin);
       ++        for (i = 0; i <= LENGTH(tags); i++) {
       ++                free(mon->tags[i]);
       ++        }
       ++        free(mon->tags);
       +         free(mon);
       + }
       + 
       +@@ -633,6 +641,7 @@ Monitor *
       + createmon(void)
       + {
       +         Monitor *m;
       ++        unsigned int i;
       + 
       +         m = ecalloc(1, sizeof(Monitor));
       +         m->tagset[0] = m->tagset[1] = 1;
       +@@ -643,6 +652,16 @@ createmon(void)
       +         m->lt[0] = &layouts[0];
       +         m->lt[1] = &layouts[1 % LENGTH(layouts)];
       +         strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
       ++
       ++        m->tags = ecalloc(LENGTH(tags), sizeof(char) * (MAX_TAGLEN + 1));
       ++
       ++        for (i = 0; i <= LENGTH(tags); i++) {
       ++                m->tags[i] = ecalloc(1, sizeof(char) * (MAX_TAGLEN + 1));
       ++                memset(m->tags[i], 0, MAX_TAGLEN);
       ++                unsigned char slen = strlen(tags[i]);
       ++                unsigned char len = slen >= MAX_TAGLEN ? MAX_TAGLEN : slen;
       ++                memcpy(m->tags[i], tags[i], sizeof(char) * len);
       ++        }
       +         return m;
       + }
       + 
       +@@ -720,9 +739,9 @@ drawbar(Monitor *m)
       +         }
       +         x = 0;
       +         for (i = 0; i < LENGTH(tags); i++) {
       +-                w = TEXTW(tags[i]);
       ++                w = TEXTW(m->tags[i]);
       +                 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, m->tags[i], urg & 1 << i);
       +                 if (occ & 1 << i)
       +                         drw_rect(drw, x + boxs, boxs, boxw, boxw,
       +                                 m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
       +@@ -1201,6 +1220,40 @@ movemouse(const Arg *arg)
       +         }
       + }
       + 
       ++void
       ++nametag(const Arg *arg) {
       ++        char *p, name[MAX_TAGLEN];
       ++        FILE *f;
       ++        int i;
       ++        char dmenumon[2];
       ++        char cmd[25];
       ++
       ++        SETDMENUMON(dmenumon);
       ++        memset(cmd, 0, 25);
       ++        sprintf(cmd, "dmenu -m %s < /dev/null", dmenumon);
       ++        errno = 0; // popen(3p) says on failure it "may" set errno
       ++
       ++        if(!(f = popen(cmd, "r"))) {
       ++                fprintf(stderr, "dwm: popen 'dmenu < /dev/null' 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));
       ++        if (pclose(f) < 0)
       ++                fprintf(stderr, "dwm: pclose failed: %s\n", strerror(errno));
       ++        if(!p)
       ++                return;
       ++        if((p = strchr(name, '\n')))
       ++                *p = '\0';
       ++
       ++        for(i = 0; i < LENGTH(tags); i++)
       ++                if(selmon->tagset[selmon->seltags] & (1 << i)) {
       ++                        sprintf(selmon->tags[i], TAG_PREPEND, i+1);
       ++                        strcat(selmon->tags[i], name);
       ++                }
       ++        drawbars();
       ++}
       ++
       + Client *
       + nexttiled(Client *c)
       + {
   DIR diff --git a/dwm.suckless.org/patches/mmnametags/index.md b/dwm.suckless.org/patches/mmnametags/index.md
       @@ -3,12 +3,17 @@ mmnametags
        
        Description
        -----------
       -This patch builds upon the [nametag](https://dwm.suckless.org/patches/nametag/) patch,
       -but allows each monitor to have its own unique set of nametags. You don’t need
       -to install the original nametag patch beforehand.
       +This patch builds upon the [nametag](https://dwm.suckless.org/patches/nametag/)
       +patch, but allows each monitor to have its own unique set of nametags. You don’t
       +need to install the original nametag patch beforehand.
       +
       +The latest update fixes memory management issues, it has the shorthash of
       +7c3abae. It is recommended to use this version.
        
        Download
        --------
       +* [dwm-mmnametags-20251218-7c3abae.diff](dwm-mmnametags-20251218-7c3abae.diff)
       +* [dwm-mmnametags-prepend-20251218-7c3abae.diff](dwm-mmnametags-prepend-20251218-7c3abae.diff)
        * [dwm-mmnametags-6.6.diff](dwm-mmnametags-6.6.diff)
        * [dwm-mmnametags-prepend-6.6.diff](dwm-mmnametags-prepend-6.6.diff)