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..dcd1767 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,19 @@ 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 = NULL; + + for (i = 0; i <= LENGTH(tags); i++) { + if (m->tags == NULL) + m->tags = malloc(LENGTH(tags) * i); + else + m->tags = realloc(m->tags, LENGTH(tags) * i); + + m->tags[i] = NULL; + m->tags[i] = malloc(LENGTH(tags)); + memset(m->tags[i], 0, LENGTH(tags)); + memcpy(m->tags[i], tags[i], LENGTH(tags)); + } return m; } @@ -720,9 +742,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 +1223,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) {