summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c36
-rw-r--r--calmwm.h10
-rw-r--r--conf.c8
-rw-r--r--group.c2
-rw-r--r--kbfunc.c68
-rw-r--r--parse.y11
-rw-r--r--xevents.c16
7 files changed, 88 insertions, 63 deletions
diff --git a/calmwm.c b/calmwm.c
index ed18a6a..71ee1f6 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -35,7 +35,6 @@
 
 #include "calmwm.h"
 
-char				**cwm_argv;
 Display				*X_Dpy;
 Time				 Last_Event_Time = CurrentTime;
 Atom				 cwmh[CWMH_NITEMS];
@@ -47,10 +46,12 @@ struct client_ctx_q		 Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
 int				 HasRandr, Randr_ev;
 struct conf			 Conf;
 const char			*homedir;
+volatile sig_atomic_t		 cwm_status;
 
 static void	sigchld_cb(int);
 static int	x_errorhandler(Display *, XErrorEvent *);
 static void	x_init(const char *);
+static void	x_restart(char **);
 static void	x_teardown(void);
 static int	x_wmerrorhandler(Display *, XErrorEvent *);
 
@@ -59,6 +60,7 @@ main(int argc, char **argv)
 {
 	const char	*conf_file = NULL;
 	char		*conf_path, *display_name = NULL;
+	char		**cwm_argv;
 	int		 ch;
 	struct passwd	*pw;
 
@@ -111,8 +113,12 @@ main(int argc, char **argv)
 	free(conf_path);
 
 	x_init(display_name);
-	xev_loop();
+	cwm_status = CWM_RUNNING;
+	while (cwm_status == CWM_RUNNING)
+		xev_process();
 	x_teardown();
+	if (cwm_status == CWM_RESTART)
+		x_restart(cwm_argv);
 
 	return (0);
 }
@@ -141,8 +147,34 @@ x_init(const char *dpyname)
 }
 
 static void
+x_restart(char **args)
+{
+	(void)setsid();
+	(void)execvp(args[0], args);
+}
+
+static void
 x_teardown(void)
 {
+	struct screen_ctx	*sc;
+	unsigned int		 i;
+
+	TAILQ_FOREACH(sc, &Screenq, entry) {
+		for (i = 0; i < CWM_COLOR_NITEMS; i++)
+			XftColorFree(X_Dpy, sc->visual, sc->colormap,
+			    &sc->xftcolor[i]);
+		XftDrawDestroy(sc->xftdraw);
+		XftFontClose(X_Dpy, sc->xftfont);
+		XUnmapWindow(X_Dpy, sc->menuwin);
+		XDestroyWindow(X_Dpy, sc->menuwin);
+		XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);
+	}
+	XUngrabPointer(X_Dpy, CurrentTime);
+	XUngrabKeyboard(X_Dpy, CurrentTime);
+	for (i = 0; i < CF_NITEMS; i++)
+		XFreeCursor(X_Dpy, Conf.cursor[i]);
+	XSync(X_Dpy, False);
+	XSetInputFocus(X_Dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 	XCloseDisplay(X_Dpy);
 }
 
diff --git a/calmwm.h b/calmwm.h
index 0f2bde6..e8042c1 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -97,6 +97,10 @@ size_t strlcat(char *, const char *, size_t);
 
 #define CWM_WIN			0x0001
 
+#define CWM_QUIT		0x0000
+#define CWM_RUNNING		0x0001
+#define CWM_RESTART		0x0002
+
 union arg {
 	char	*c;
 	int	 i;
@@ -339,6 +343,7 @@ extern struct client_ctx_q		 Clientq;
 extern struct conf			 Conf;
 extern const char			*homedir;
 extern int				 HasRandr, Randr_ev;
+extern volatile sig_atomic_t		 cwm_status;
 
 enum {
 	WM_STATE,
@@ -485,11 +490,10 @@ void			 kbfunc_client_search(struct client_ctx *, union arg *);
 void			 kbfunc_client_vmaximize(struct client_ctx *,
 			     union arg *);
 void			 kbfunc_cmdexec(struct client_ctx *, union arg *);
+void			 kbfunc_cwm_status(struct client_ctx *, union arg *);
 void			 kbfunc_exec(struct client_ctx *, union arg *);
 void			 kbfunc_lock(struct client_ctx *, union arg *);
 void			 kbfunc_menu_search(struct client_ctx *, union arg *);
-void			 kbfunc_quit_wm(struct client_ctx *, union arg *);
-void			 kbfunc_restart(struct client_ctx *, union arg *);
 void			 kbfunc_ssh(struct client_ctx *, union arg *);
 void			 kbfunc_term(struct client_ctx *, union arg *);
 void 			 kbfunc_tile(struct client_ctx *, union arg *);
@@ -539,7 +543,7 @@ void			 conf_init(struct conf *);
 void			 conf_ignore(struct conf *, const char *);
 void			 conf_screen(struct screen_ctx *);
 
-void			 xev_loop(void);
+void			 xev_process(void);
 
 void			 xu_btn_grab(Window, int, unsigned int);
 void			 xu_btn_ungrab(Window);
diff --git a/conf.c b/conf.c
index 142ee40..16faf30 100644
--- a/conf.c
+++ b/conf.c
@@ -120,7 +120,7 @@ conf_screen(struct screen_ctx *sc)
 			xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_FONT], xc, &xc);
 			if (!XftColorAllocValue(X_Dpy, sc->visual, sc->colormap,
 			    &xc.color, &sc->xftcolor[CWM_COLOR_MENU_FONT_SEL]))
-				warnx("XftColorAllocValue: '%s'", Conf.color[i]);
+				warnx("XftColorAllocValue: %s", Conf.color[i]);
 			break;
 		}
 		if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
@@ -128,7 +128,7 @@ conf_screen(struct screen_ctx *sc)
 			sc->xftcolor[i] = xc;
 			XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc);
 		} else {
-			warnx("XftColorAllocName: '%s'", Conf.color[i]);
+			warnx("XftColorAllocName: %s", Conf.color[i]);
 			XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
 			    color_binds[i], &sc->xftcolor[i]);
 		}
@@ -373,8 +373,8 @@ static const struct {
 	{ "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} },
 	{ "hmaximize", kbfunc_client_hmaximize, CWM_WIN, {0} },
 	{ "freeze", kbfunc_client_freeze, CWM_WIN, {0} },
-	{ "restart", kbfunc_restart, 0, {0} },
-	{ "quit", kbfunc_quit_wm, 0, {0} },
+	{ "restart", kbfunc_cwm_status, 0, {.i = CWM_RESTART} },
+	{ "quit", kbfunc_cwm_status, 0, {.i = CWM_QUIT} },
 	{ "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} },
 	{ "exec_wm", kbfunc_exec, 0, {.i = CWM_EXEC_WM} },
 	{ "ssh", kbfunc_ssh, 0, {0} },
diff --git a/group.c b/group.c
index fe5eb3a..990b914 100644
--- a/group.c
+++ b/group.c
@@ -105,7 +105,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc)
 		if (cc->stackingorder > gc->highstack)
 			gc->highstack = cc->stackingorder;
 	}
-	winlist = (Window *) xcalloc(sizeof(*winlist), (gc->highstack + 1));
+	winlist = xcalloc((gc->highstack + 1), sizeof(*winlist));
 
 	/*
 	 * Invert the stacking order as XRestackWindows() expects them
diff --git a/kbfunc.c b/kbfunc.c
index 26e6d3d..dc3f401 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -35,9 +35,6 @@
 
 #define HASH_MARKER	"|1|"
 
-extern char		**cwm_argv;
-extern sig_atomic_t	xev_quit;
-
 void
 kbfunc_client_lower(struct client_ctx *cc, union arg *arg)
 {
@@ -239,15 +236,15 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
 	int			 l, i, cmd = arg->i;
 
 	switch (cmd) {
-		case CWM_EXEC_PROGRAM:
-			label = "exec";
-			break;
-		case CWM_EXEC_WM:
-			label = "wm";
-			break;
-		default:
-			errx(1, "kbfunc_exec: invalid cmd %d", cmd);
-			/*NOTREACHED*/
+	case CWM_EXEC_PROGRAM:
+		label = "exec";
+		break;
+	case CWM_EXEC_WM:
+		label = "wm";
+		break;
+	default:
+		errx(1, "kbfunc_exec: invalid cmd %d", cmd);
+		/*NOTREACHED*/
 	}
 
 	TAILQ_INIT(&menuq);
@@ -289,16 +286,16 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
 		if (mi->text[0] == '\0')
 			goto out;
 		switch (cmd) {
-			case CWM_EXEC_PROGRAM:
-				u_spawn(mi->text);
-				break;
-			case CWM_EXEC_WM:
-				u_exec(mi->text);
-				warn("%s", mi->text);
-				break;
-			default:
-				errx(1, "kb_func: egad, cmd changed value!");
-				break;
+		case CWM_EXEC_PROGRAM:
+			u_spawn(mi->text);
+			break;
+		case CWM_EXEC_WM:
+			u_exec(mi->text);
+			warn("%s", mi->text);
+			break;
+		default:
+			errx(1, "kb_func: egad, cmd changed value!");
+			break;
 		}
 	}
 out:
@@ -357,8 +354,8 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
 	    search_match_exec, NULL)) != NULL) {
 		if (mi->text[0] == '\0')
 			goto out;
-		l = snprintf(cmd, sizeof(cmd), "%s -e ssh %s", Conf.termpath,
-		    mi->text);
+		l = snprintf(cmd, sizeof(cmd), "%s -T '[ssh] %s' -e ssh %s",
+		    Conf.termpath, mi->text, mi->text);
 		if (l != -1 && l < sizeof(cmd))
 			u_spawn(cmd);
 	}
@@ -464,27 +461,20 @@ kbfunc_client_freeze(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_quit_wm(struct client_ctx *cc, union arg *arg)
+kbfunc_cwm_status(struct client_ctx *cc, union arg *arg)
 {
-	xev_quit = 1;
-}
-
-void
-kbfunc_restart(struct client_ctx *cc, union arg *arg)
-{
-	(void)setsid();
-	(void)execvp(cwm_argv[0], cwm_argv);
+	cwm_status = arg->i;
 }
 
 void
 kbfunc_tile(struct client_ctx *cc, union arg *arg)
 {
 	switch (arg->i) {
-		case CWM_TILE_HORIZ:
-			client_htile(cc);
-			break;
-		case CWM_TILE_VERT:
-			client_vtile(cc);
-			break;
+	case CWM_TILE_HORIZ:
+		client_htile(cc);
+		break;
+	case CWM_TILE_VERT:
+		client_vtile(cc);
+		break;
 	}
 }
diff --git a/parse.y b/parse.y
index 188c090..6fbeb8d 100644
--- a/parse.y
+++ b/parse.y
@@ -118,21 +118,21 @@ main		: FONTNAME STRING		{
 				conf->flags |= CONF_STICKY_GROUPS;
 		}
 		| BORDERWIDTH NUMBER {
-			if ($2 < 0) {
+			if ($2 < 0 || $2 > UINT_MAX) {
 				yyerror("invalid borderwidth: %d", $2);
 				YYERROR;
 			}
 			conf->bwidth = $2;
 		}
 		| MOVEAMOUNT NUMBER {
-			if ($2 < 0) {
+			if ($2 < 0 || $2 > INT_MAX) {
 				yyerror("invalid movemount: %d", $2);
 				YYERROR;
 			}
 			conf->mamount = $2;
 		}
 		| SNAPDIST NUMBER {
-			if ($2 < 0) {
+			if ($2 < 0 || $2 > INT_MAX) {
 				yyerror("invalid snapdist: %d", $2);
 				YYERROR;
 			}
@@ -167,7 +167,10 @@ main		: FONTNAME STRING		{
 			free($3);
 		}
 		| GAP NUMBER NUMBER NUMBER NUMBER {
-			if ($2 < 0 || $3 < 0 || $4 < 0 || $5 < 0) {
+			if ($2 < 0 || $2 > INT_MAX ||
+			    $3 < 0 || $3 > INT_MAX ||
+			    $4 < 0 || $4 > INT_MAX ||
+			    $5 < 0 || $5 > INT_MAX) {
 				yyerror("invalid gap: %d %d %d %d",
 				    $2, $3, $4, $5);
 				YYERROR;
diff --git a/xevents.c b/xevents.c
index 55dabab..6844f98 100644
--- a/xevents.c
+++ b/xevents.c
@@ -400,18 +400,14 @@ xev_handle_expose(XEvent *ee)
 		client_draw_border(cc);
 }
 
-volatile sig_atomic_t	xev_quit = 0;
-
 void
-xev_loop(void)
+xev_process(void)
 {
 	XEvent		 e;
 
-	while (xev_quit == 0) {
-		XNextEvent(X_Dpy, &e);
-		if (e.type - Randr_ev == RRScreenChangeNotify)
-			xev_handle_randr(&e);
-		else if (e.type < LASTEvent && xev_handlers[e.type] != NULL)
-			(*xev_handlers[e.type])(&e);
-	}
+	XNextEvent(X_Dpy, &e);
+	if (e.type - Randr_ev == RRScreenChangeNotify)
+		xev_handle_randr(&e);
+	else if (e.type < LASTEvent && xev_handlers[e.type] != NULL)
+		(*xev_handlers[e.type])(&e);
 }