commit 214992a9baa64b6b2733273d507111e70f36477e
parent d1716bda6b8890d268358901d03e1f4748956ba2
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Fri,  6 May 2011 21:40:53 +0100
added generic client support (thanks Stephen)
Diffstat:
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -12,7 +12,7 @@ static const Bool foreground   = False;
 static Key keys[] = { \
 	/* modifier                     key        function        argument */
 	{ MODKEY|ShiftMask,             XK_Return, focusonce,      { 0 } },
-	{ MODKEY|ShiftMask,             XK_Return, spawn,          { .v = (char*[]){ "surf", "-e", winid, NULL} } },
+	{ MODKEY|ShiftMask,             XK_Return, spawn,          { 0 } },
 	{ MODKEY|ShiftMask,             XK_l,      rotate,         { .i = +1 } },
 	{ MODKEY|ShiftMask,             XK_h,      rotate,         { .i = -1 } },
 	{ MODKEY,                       XK_Tab,    rotate,         { .i = 0 } },
diff --git a/tabbed.c b/tabbed.c
@@ -39,7 +39,7 @@
 /* Macros */
 #define MAX(a, b)                ((a) > (b) ? (a) : (b))
 #define MIN(a, b)                ((a) < (b) ? (a) : (b))
-#define LENGTH(x)                (sizeof x / sizeof x[0])
+#define LENGTH(x)                (sizeof (x) / sizeof *(x))
 #define CLEANMASK(mask)          (mask & ~(numlockmask|LockMask))
 #define TEXTW(x)                 (textnw(x, strlen(x)) + dc.font.height)
 
@@ -116,6 +116,7 @@ static void rotate(const Arg *arg);
 static void run(void);
 static void sendxembed(Client *c, long msg, long detail, long d1, long d2);
 static void setup(void);
+static void setcmd(int argc, char *argv[]);
 static void sigchld(int unused);
 static void spawn(const Arg *arg);
 static int textnw(const char *text, unsigned int len);
@@ -150,6 +151,7 @@ static Window root, win;
 static Client *clients = NULL, *sel = NULL, *lastsel = NULL;
 static int (*xerrorxlib)(Display *, XErrorEvent *);
 static char winid[64];
+static char **cmd = NULL;
 /* configuration, allows nested code to access above variables */
 #include "config.h"
 
@@ -189,8 +191,8 @@ cleanup(void) {
 	Client *c, *n;
 
 	for(c = clients; c; c = n) {
-		killclient(NULL);
 		focus(c);
+		killclient(NULL);
 		XReparentWindow(dpy, c->win, root, 0, 0);
 		n = c->next;
 		unmanage(c);
@@ -203,6 +205,7 @@ cleanup(void) {
 	XFreeGC(dpy, dc.gc);
 	XDestroyWindow(dpy, win);
 	XSync(dpy, False);
+	free(cmd);
 }
 
 void
@@ -360,7 +363,7 @@ emallocz(size_t size) {
 	void *p;
 
 	if(!(p = calloc(1, size)))
-		die(0, "tabbed: cannot malloc");
+		die("tabbed: cannot malloc\n");
 	return p;
 }
 
@@ -423,7 +426,7 @@ getcolor(const char *colstr) {
 	XColor color;
 
 	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
-		die("error, cannot allocate color '%s'\n", colstr);
+		die("tabbed: cannot allocate color '%s'\n", colstr);
 	return color.pixel;
 }
 
@@ -502,7 +505,7 @@ initfont(const char *fontstr) {
 		dc.font.xfont = NULL;
 		if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))
 		&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed")))
-			die("error, cannot load font: '%s'\n", fontstr);
+			die("tabbed: cannot load font: '%s'\n", fontstr);
 		dc.font.ascent = dc.font.xfont->ascent;
 		dc.font.descent = dc.font.xfont->descent;
 	}
@@ -578,7 +581,7 @@ manage(Window w) {
 					XGrabKey(dpy, code, keys[i].mod | modifiers[j], w,
 						 True, GrabModeAsync, GrabModeAsync);
 		}
-		c = emallocz(sizeof(Client));
+		c = emallocz(sizeof *c);
 		c->next = clients;
 		c->win = w;
 		clients = c;
@@ -703,6 +706,17 @@ sendxembed(Client *c, long msg, long detail, long d1, long d2) {
 }
 
 void
+setcmd(int argc, char *argv[]) {
+	int i;
+
+	cmd = emallocz((argc+2) * sizeof *cmd);
+	for(i = 0; i < argc; i++)
+		cmd[i] = argv[i];
+	cmd[argc] = winid;
+	cmd[argc+1] = NULL;
+}
+
+void
 setup(void) {
 	/* clean up any zombies immediately */
 	sigchld(0);
@@ -740,7 +754,7 @@ setup(void) {
 	class_hint.res_class = "Tabbed";
 	XSetClassHint(dpy, win, &class_hint);
 	XSetWMProtocols(dpy, win, &wmatom[WMDelete], 1);
-	snprintf(winid, LENGTH(winid), "%u", (int)win);
+	snprintf(winid, sizeof winid, "%lu", win);
 	nextfocus = foreground;
 	focus(clients);
 }
@@ -748,7 +762,7 @@ setup(void) {
 void
 sigchld(int unused) {
 	if(signal(SIGCHLD, sigchld) == SIG_ERR)
-		die("Can't install SIGCHLD handler");
+		die("tabbed: cannot install SIGCHLD handler");
 	while(0 < waitpid(-1, NULL, WNOHANG));
 }
 
@@ -758,8 +772,8 @@ spawn(const Arg *arg) {
 		if(dpy)
 			close(ConnectionNumber(dpy));
 		setsid();
-		execvp(((char **)arg->v)[0], (char **)arg->v);
-		fprintf(stderr, "tabbed: execvp %s", ((char **)arg->v)[0]);
+		execvp(cmd[0], cmd);
+		fprintf(stderr, "tabbed: execvp %s", cmd[0]);
 		perror(" failed");
 		exit(0);
 	}
@@ -844,16 +858,20 @@ xerror(Display *dpy, XErrorEvent *ee) {
 
 int
 main(int argc, char *argv[]) {
-	int detach = 0;
-
-	if(argc == 2 && !strcmp("-v", argv[1]))
-		die("tabbed-"VERSION", © 2009-2010 tabbed engineers, see LICENSE for details\n");
-	else if(argc == 2 && strcmp("-d", argv[1]) == 0)
-		detach = 1;
-	else if(argc != 1)
-		die("usage: tabbed [-d] [-v]\n");
+	int i, detach = 0;
+
+	for(i = 1; i < argc && !cmd; i++) {
+		if(!strcmp("-v", argv[i]))
+			die("tabbed-"VERSION", © 2009-2011 tabbed engineers, see LICENSE for details\n");
+		else if(!strcmp("-d", argv[i]))
+			detach = 1;
+		else
+			setcmd(argc-i, argv+i);
+	}
+	if(!cmd)
+		die("usage: tabbed [-d] [-v] command\n");
 	if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
-		fprintf(stderr, "warning: no locale support\n");
+		fprintf(stderr, "tabbed: no locale support\n");
 	if(!(dpy = XOpenDisplay(NULL)))
 		die("tabbed: cannot open display\n");
 	setup();