changeset 777:3835ddb75a55

changed to status text setting through XA_WM_NAME (suggested by Neale Pickett)
author meillo@marmaro.de
date Mon, 16 Feb 2009 10:40:57 +0100 (2009-02-16)
parents a3399a8964c7
children 7ea91d4d0882
files aewl.c
diffstat 1 files changed, 81 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/aewl.c	Mon Feb 16 09:23:57 2009 +0100
+++ b/aewl.c	Mon Feb 16 10:40:57 2009 +0100
@@ -8,12 +8,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
@@ -46,7 +43,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/select.h>
 #include <sys/signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -145,7 +141,7 @@
 Window root, barwin;
 
 static int (*xerrorxlib)(Display *, XErrorEvent *);
-static Bool otherwm, readin;
+static Bool otherwm;
 static unsigned int len = 0;
 
 
@@ -160,13 +156,12 @@
 void updatetitle(Client *c);		/* update the name of c */
 void unmanage(Client *c);		/* destroy c */
 
-void drawstatus(void);			/* draw the bar */
+void drawbar(void);			/* draw the bar */
 unsigned long getcolor(const char *colstr);	/* return color of colstr */
 void setfont(const char *fontstr);	/* set the font for DC */
 unsigned int textw(const char *text);	/* return the width of text in px*/
 
 void grabkeys(void);			/* grab all keys defined in config.h */
-void procevent(void);			/* process pending X events */
 
 void sendevent(Window w, Atom a, long value);	/* send synthetic event to w */
 int xerror(Display *dsply, XErrorEvent *ee);	/* X error handler */
@@ -195,6 +190,7 @@
 void toggletag(void);		/* toggles tag of c */
 void spawn(const char* cmd);			/* forks a new subprocess with cmd */
 
+void updatestatus(void);		/* update the status text */
 
 
 RULES
@@ -374,7 +370,7 @@
 	Client *c;
 	XEvent ev;
 
-	drawstatus();
+	drawbar();
 	if(!sel)
 		return;
 	if(sel->isfloat)
@@ -722,7 +718,7 @@
 
 	if(ev->count == 0) {
 		if(barwin == ev->window)
-			drawstatus();
+			drawbar();
 	}
 }
 
@@ -783,9 +779,11 @@
 	Window trans;
 	XPropertyEvent *ev = &e->xproperty;
 
-	if(ev->state == PropertyDelete)
+	if((ev->window == root) && (ev->atom = XA_WM_NAME))
+		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:
@@ -800,7 +798,7 @@
 		if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
 			updatetitle(c);
 			if(c == sel)
-				drawstatus();
+				drawbar();
 		}
 	}
 }
@@ -850,17 +848,6 @@
 	}
 }
 
-void
-procevent(void) {
-	XEvent ev;
-
-	while(XPending(dpy)) {
-		XNextEvent(dpy, &ev);
-		if(handler[ev.type])
-			(handler[ev.type])(&ev); /* call handler */
-	}
-}
-
 /* from draw.c */
 
 unsigned int
@@ -920,7 +907,7 @@
 }
 
 void
-drawstatus(void) {
+drawbar(void) {
 	int x;
 	unsigned long black[ColLast];
 	black[ColBG] = getcolor("#000000");
@@ -1112,7 +1099,7 @@
 		grabbuttons(c, True);
 	}
 	sel = c;
-	drawstatus();
+	drawbar();
 	if(!selscreen)
 		return;
 	if(c) {
@@ -1322,26 +1309,36 @@
 
 void
 updatetitle(Client *c) {
+	if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) {
+		gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
+	}
+}
+
+
+Bool
+gettextprop(Window w, Atom atom, char* text, unsigned int size) {
 	char **list = NULL;
 	int n;
 	XTextProperty name;
 
-	name.nitems = 0;
-	c->name[0] = 0;
-	XGetTextProperty(dpy, c->win, &name, netatom[NetWMName]);
+	if (!text || size == 0) {
+		return False;
+	}
+	text[0] = '\0';
+	XGetTextProperty(dpy, w, &name, atom);
 	if(!name.nitems)
-		XGetWMName(dpy, c->win, &name);
-	if(!name.nitems)
-		return;
+		return False;
 	if(name.encoding == XA_STRING)
-		strncpy(c->name, (char *)name.value, sizeof c->name);
+		strncpy(text, (char *)name.value, size - 1);
 	else {
 		if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
-			strncpy(c->name, *list, sizeof c->name);
+			strncpy(text, *list, size - 1);
 			XFreeStringList(list);
 		}
 	}
+	text[size - 1] = '\0';
 	XFree(name.value);
+	return True;
 }
 
 void
@@ -1370,7 +1367,6 @@
 
 void
 cleanup(void) {
-	close(STDIN_FILENO);
 	while(stack) {
 		resize(stack, True);
 		unmanage(stack);
@@ -1419,6 +1415,9 @@
 	XModifierKeymap *modmap;
 	XSetWindowAttributes wa;
 
+	screen = DefaultScreen(dpy);
+	root = RootWindow(dpy, screen);
+
 	/* init atoms */
 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
@@ -1443,7 +1442,7 @@
 	XFreeModifiermap(modmap);
 	/* select for events */
 	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
-		| EnterWindowMask | LeaveWindowMask;
+		| EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
 	wa.cursor = cursor[CurNormal];
 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
 	grabkeys();
@@ -1482,6 +1481,8 @@
 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
 	/* multihead support */
 	selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
+
+	updatestatus();
 }
 
 /*
@@ -1510,7 +1511,7 @@
 
 void
 quit() {
-	readin = running = False;
+	running = False;
 }
 
 /* There's no way to check accesses to destroyed windows, thus those cases are
@@ -1533,11 +1534,44 @@
 	return xerrorxlib(dpy, ee); /* may call exit */
 }
 
+void
+checkotherwm(void) {
+	otherwm = False;
+	xerrorxlib = XSetErrorHandler(xerrorstart);
+	/* this causes an error if some other window manager is running */
+	XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
+	XSync(dpy, False);
+	if(otherwm) {
+		eprint("aewl: another window manager is already running\n");
+	}
+
+	XSetErrorHandler(xerror);
+	XSync(dpy, False);
+}
+
+void
+run(void) {
+	XEvent ev;
+
+	XSync(dpy, False);
+	/* main event loop */
+	while(running && !XNextEvent(dpy, &ev)) {
+		if(handler[ev.type]) {
+			(handler[ev.type])(&ev); /* call handler */
+		}
+	}
+}
+
+void
+updatestatus(void) {
+	if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) {
+		strcpy(stext, "aewl-"VERSION);
+	}
+	drawbar();
+}
+
 int
 main(int argc, char *argv[]) {
-	char *p;
-	int r, xfd;
-	fd_set rd;
 
 	if(argc == 2 && !strncmp("-v", argv[1], 3)) {
 		fputs("aewl-"VERSION", Copyright 2008  markus schnalke <meillo@marmaro.de>\n", stdout);
@@ -1551,63 +1585,13 @@
 	if(!dpy) {
 		eprint("aewl: cannot open display\n");
 	}
-	xfd = ConnectionNumber(dpy);
-	screen = DefaultScreen(dpy);
-	root = RootWindow(dpy, screen);
-	otherwm = False;
-	XSetErrorHandler(xerrorstart);
-	/* this causes an error if some other window manager is running */
-	XSelectInput(dpy, root, SubstructureRedirectMask);
-	XSync(dpy, False);
-	if(otherwm) {
-		eprint("aewl: another window manager is already running\n");
-	}
-
-	XSync(dpy, False);
-	XSetErrorHandler(NULL);
-	xerrorxlib = XSetErrorHandler(xerror);
-	XSync(dpy, False);
-	setup();
-	drawstatus();
-	scan();
 
-	/* main event loop, also reads status text from stdin */
-	XSync(dpy, False);
-	procevent();
-	readin = True;
-	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;
-			eprint("select failed\n");
-		}
-		if(FD_ISSET(STDIN_FILENO, &rd)) {
-			switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
-			case -1:
-				strncpy(stext, strerror(errno), sizeof stext - 1);
-				stext[sizeof stext - 1] = '\0';
-				readin = False;
-				break;
-			case 0:
-				strncpy(stext, "EOF", 4);
-				readin = False;
-				break;
-			default:
-				for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
-				for(; p >= stext && *p != '\n'; --p);
-				if(p > stext)
-					strncpy(stext, p + 1, sizeof stext);
-			}
-			drawstatus();
-		}
-		if(FD_ISSET(xfd, &rd))
-			procevent();
-	}
+	checkotherwm();
+	setup();
+	scan();
+	run();
 	cleanup();
+
 	XCloseDisplay(dpy);
 	return 0;
 }