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
