I very much like this patch. I realized right away that I would never again need to restart dwm when I work on my status script. When it dies, I can just start it up again without restarting DWM. Someone could even have multiple programs running to update the status text. It removes the need for the "readin" variable: you either set the property or you don't.
The patch removes 39 SLOC: 1546 dwm-5.3.1 ansic=1546 1585 dwm-5.3.1-orig ansic=1585 This would be 40 if the property were hard coded to XA_WM_NAME. I left in a comment to use a property named "DWM_STATUS" instead of XA_WM_NAME, so people could play with it easily, but I think XA_WM_NAME is ultimately the right way to do it. To use this, modify your status script to use "xsetroot -name" instead of "echo". For instance: while true; do xsetroot -name "$(date)" sleep 1 done You could also pipe an existing status script to an xsetroot loop like so: status | while read line; do xsetroot -name "$line"; done If you'd prefer to not use the otherwise-unused WM_NAME property of the root window, uncomment the commented "statusatom" line, and use xprop as I detailed in my previous email to the list. I decided WM_NAME was a good choice, since the default is to display "dwm-"VERSION, and since xsetroot has a nicer syntax than xprop. Neale -----8<----- cut here -----8<----- diff -ur dwm-5.3.1.orig/config.def.h dwm-5.3.1/config.def.h --- dwm-5.3.1.orig/config.def.h 2008-12-06 02:33:03.000000000 -0700 +++ dwm-5.3.1/config.def.h 2008-12-08 22:39:49.000000000 -0700 @@ -12,7 +12,6 @@ static unsigned int snap = 32; /* snap pixel */ static Bool showbar = True; /* False means no bar */ static Bool topbar = True; /* False means bottom bar */ -static Bool readin = True; /* False means do not read stdin */ static Bool usegrab = False; /* True means grabbing the X server during mouse-based resizals */ diff -ur dwm-5.3.1.orig/dwm.c dwm-5.3.1/dwm.c --- dwm-5.3.1.orig/dwm.c 2008-12-06 02:33:03.000000000 -0700 +++ dwm-5.3.1/dwm.c 2008-12-08 22:39:49.000000000 -0700 @@ -6,12 +6,9 @@ * events about window (dis-)appearance. Only one X connection at a time is * allowed to select for this event mask. * - * Calls to fetch an X event from the event queue are blocking. Due reading - * status text from standard input, a select()-driven main loop has been - * implemented which selects for reads on the X connection and STDIN_FILENO to - * handle all data smoothly. The event handlers of dwm are organized in an - * array which is accessed whenever a new event has been fetched. This allows - * event dispatching in O(1) time. + * The event handlers of dwm are organized in an array which is accessed + * whenever a new event has been fetched. This allows event dispatching + * in O(1) time. * * Each child of the root window is called a client, except windows which have * set the override_redirect flag. Clients are organized in a global @@ -30,7 +27,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <sys/select.h> #include <sys/types.h> #include <sys/wait.h> #include <X11/cursorfont.h> @@ -196,6 +192,7 @@ static void updategeom(void); static void updatenumlockmask(void); static void updatesizehints(Client *c); +static void updatestatus(void); static void updatetitle(Client *c); static void updatewmhints(Client *c); static void view(const Arg *arg); @@ -227,7 +224,7 @@ [PropertyNotify] = propertynotify, [UnmapNotify] = unmapnotify }; -static Atom wmatom[WMLast], netatom[NetLast]; +static Atom wmatom[WMLast], netatom[NetLast], statusatom; static Bool otherwm; static Bool running = True; static Client *clients = NULL; @@ -998,9 +995,11 @@ Window trans; XPropertyEvent *ev = &e->xproperty; - if(ev->state == PropertyDelete) + if((ev->window == root) && (ev->atom = statusatom)) + updatestatus(); + else if(ev->state == PropertyDelete) return; /* ignore */ - if((c = getclient(ev->window))) { + else if((c = getclient(ev->window))) { switch (ev->atom) { default: break; case XA_WM_TRANSIENT_FOR: @@ -1026,7 +1025,7 @@ void quit(const Arg *arg) { - readin = running = False; + running = False; } void @@ -1180,60 +1179,13 @@ void run(void) { - char *p; - char sbuf[sizeof stext]; - fd_set rd; - int r, xfd; - unsigned int len, offset; XEvent ev; - /* main event loop, also reads status text from stdin */ + /* main event loop */ XSync(dpy, False); - xfd = ConnectionNumber(dpy); - offset = 0; - len = sizeof stext - 1; - sbuf[len] = stext[len] = '\0'; /* 0-terminator is never touched */ - while(running) { - FD_ZERO(&rd); - if(readin) - FD_SET(STDIN_FILENO, &rd); - FD_SET(xfd, &rd); - if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) { - if(errno == EINTR) - continue; - die("select failed\n"); - } - if(FD_ISSET(STDIN_FILENO, &rd)) { - switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) { - case -1: - strncpy(stext, strerror(errno), len); - readin = False; - break; - case 0: - strncpy(stext, "EOF", 4); - readin = False; - break; - default: - for(p = sbuf + offset; r > 0; p++, r--, offset++) - if(*p == '\n' || *p == '\0') { - *p = '\0'; - strncpy(stext, sbuf, len); - p += r - 1; /* p is sbuf + offset + r - 1 */ - for(r = 0; *(p - r) && *(p - r) != '\n'; r++); - offset = r; - if(r) - memmove(sbuf, p - r + 1, r); - break; - } - break; - } - drawbar(); - } - while(XPending(dpy)) { - XNextEvent(dpy, &ev); - if(handler[ev.type]) - (handler[ev.type])(&ev); /* call handler */ - } + while(running && !XNextEvent(dpy, &ev)) { + if(handler[ev.type]) + (handler[ev.type])(&ev); /* call handler */ } } @@ -1322,6 +1274,8 @@ wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + /* statusatom = XInternAtom(dpy, "DWM_STATUS", False); */ + statusatom = XA_WM_NAME; /* init cursors */ wa.cursor = cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); @@ -1356,8 +1310,7 @@ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, barwin, cursor[CurNormal]); XMapRaised(dpy, barwin); - strcpy(stext, "dwm-"VERSION); - drawbar(); + updatestatus(); /* EWMH support per view */ XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, @@ -1365,7 +1318,8 @@ /* select for events */ wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask - |EnterWindowMask|LeaveWindowMask|StructureNotifyMask; + |EnterWindowMask|LeaveWindowMask|StructureNotifyMask + |PropertyChangeMask; XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); XSelectInput(dpy, root, wa.event_mask); @@ -1647,6 +1601,13 @@ } void +updatestatus() { + if(!gettextprop(root, statusatom, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); + drawbar(); +} + +void updatewmhints(Client *c) { XWMHints *wmh; -----8<----- cut here -----8<-----