This patch allows you to dynamically change the names of tags in dwm. This is implemented via a new command system that reads changes to the DWM_COMMAND property of the root window. The format of this property is a single letter command followed directly by a string argument. The only command currently recognised is N, which sets the name of all currently selected tags to n(str) where n is the tag number, and str is the argument to the command. I also wrote a little program to set a named property of the root window (also attached). E.g.
xsetatom DWM_COMMAND Nmusic will set the names of the selected tags to 'n(music)'. A little dmenu script is handy for this. New commands are easily implemented (see runcommand()). Patch is against mercurial tip. Apologies for the repeat, this is a fixed version of the patch I posted on the XComposite thread (now tag numbers start at one). Tom -- Thomas Spurden
diff -r 440dda47ae5b -r ee53845416ae config.def.h --- a/config.def.h Fri May 29 09:29:22 2009 +0100 +++ b/config.def.h Fri Jun 05 13:52:15 2009 +0100 @@ -14,7 +14,7 @@ static Bool topbar = True; /* False means bottom bar */ /* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +static char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */ static Rule rules[] = { diff -r 440dda47ae5b -r ee53845416ae dwm.c --- a/dwm.c Fri May 29 09:29:22 2009 +0100 +++ b/dwm.c Fri Jun 05 13:52:15 2009 +0100 @@ -54,6 +54,8 @@ #define TAGMASK ((int)((1LL << LENGTH(tags)) - 1)) #define TEXTW(x) (textnw(x, strlen(x)) + dc.font.height) +#define MAXTAGLEN 64 + /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ @@ -202,6 +204,7 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); static void zoom(const Arg *arg); +static void runcommand(void); /* variables */ static char stext[256]; @@ -226,7 +229,7 @@ [PropertyNotify] = propertynotify, [UnmapNotify] = unmapnotify }; -static Atom wmatom[WMLast], netatom[NetLast]; +static Atom wmatom[WMLast], netatom[NetLast], commandatom; static Bool otherwm; static Bool running = True; static Client *clients = NULL; @@ -1063,8 +1066,13 @@ Window trans; XPropertyEvent *ev = &e->xproperty; - if((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); + if(ev->window == root) { + if (ev->atom == XA_WM_NAME) { + updatestatus(); + } else if(ev->atom == commandatom) { + runcommand(); + } + } else if(ev->state == PropertyDelete) return; /* ignore */ else if((c = getclient(ev->window))) { @@ -1279,6 +1287,7 @@ wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + commandatom = XInternAtom(dpy, "DWM_COMMAND", False); /* init cursors */ wa.cursor = cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); @@ -1614,6 +1623,45 @@ } void +runcommand(void) { + char cmd[256]; + if(!gettextprop(root, commandatom, cmd, sizeof(cmd))) { + /* Ignore empty commands, also prevents infinite loop */ + return; + } + switch(cmd[0]) { + case 'N': + { + unsigned int ts = tagset[seltags]; + unsigned int i; + for(i = 0; ts != 0; i++, ts >>= 1) { + if(ts & 1) { + if(cmd[1] == '\0') { + snprintf(tags[i], MAXTAGLEN, "%u", i); + } else { + snprintf(tags[i], MAXTAGLEN, "%u(%s)", i + 1, cmd + 1); + } + } + } + drawbar(); + } + break; + default: + fprintf(stderr, "dwm: Unknown command '%c'\n", cmd[0]); + break; + } + { /* Clear the command */ + XTextProperty prop = { + .value = NULL, + .encoding = XA_STRING, + .format = 8, + .nitems = 0 + }; + XSetTextProperty(dpy, root, &prop, commandatom); + } +} + +void updatewmhints(Client *c) { XWMHints *wmh;
/* * Set an XAtom to a single text value. * gcc xsetatom.c -lX11 -o xsetatom */ #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { Display* dpy; Window root; Atom atom; XTextProperty prop; if(argc < 3) { printf("Usage: xsetatom <name> <value>\n"); exit(EXIT_FAILURE); } dpy = XOpenDisplay(0); if(dpy == None) { fprintf(stderr, "Could not open display\n"); exit(EXIT_FAILURE); } root = DefaultRootWindow(dpy); atom = XInternAtom(dpy, argv[1], False); XStringListToTextProperty(&argv[2], 1, &prop); XSetTextProperty(dpy, root, &prop, atom); XSync(dpy, False); XCloseDisplay(dpy); exit(EXIT_SUCCESS); }
pgpskCFZ6w29T.pgp
Description: PGP signature