summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.h4
-rw-r--r--conf.c4
-rw-r--r--cwm.16
-rw-r--r--kbfunc.c29
-rw-r--r--util.c16
5 files changed, 56 insertions, 3 deletions
diff --git a/calmwm.h b/calmwm.h
index 9f45265..da30b5d 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -209,6 +209,10 @@ enum directions {
 	CWM_UP=0, CWM_DOWN, CWM_LEFT, CWM_RIGHT,
 };
 
+/* for cwm_exec */
+#define	CWM_EXEC_PROGRAM	0x1
+#define	CWM_EXEC_WM		0x2
+
 #define KBFLAG_NEEDCLIENT 0x01
 #define KBFLAG_FINDCLIENT 0x02
 
diff --git a/conf.c b/conf.c
index 0dc5ed7..3e1edcf 100644
--- a/conf.c
+++ b/conf.c
@@ -185,6 +185,7 @@ conf_setup(struct conf *c)
 	conf_bindname(c, "CM-Return", "terminal");
 	conf_bindname(c, "CM-Delete", "lock");
 	conf_bindname(c, "M-question", "exec");
+	conf_bindname(c, "CM-q", "exec_wm");
 	conf_bindname(c, "M-period", "ssh");
 	conf_bindname(c, "M-Return", "hide");
 	conf_bindname(c, "M-Down", "lower");
@@ -373,7 +374,8 @@ struct {
 	{ "prevgroup", kbfunc_client_prevgroup, 0, 0 },
 	{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, 0 },
 	{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, 0 },
-	{ "exec", kbfunc_exec, 0, 0 },
+	{ "exec", kbfunc_exec, 0, CWM_EXEC_PROGRAM },
+	{ "exec_wm", kbfunc_exec, 0, CWM_EXEC_WM },
 	{ "ssh", kbfunc_ssh, 0, 0 },
 	{ "terminal", kbfunc_term, 0, 0 },
 	{ "lock", kbfunc_lock, 0, 0 },
diff --git a/cwm.1 b/cwm.1
index 7350132..d8ad033 100644
--- a/cwm.1
+++ b/cwm.1
@@ -98,6 +98,12 @@ This parses
 to provide host auto-completion.
 .Xr ssh 1
 will be executed via the configured terminal emulator.
+.It Ic CM-q
+Spawn
+.Dq Exec WindowManager
+dialog; allows you to switch from
+.Nm
+to another window manager without restarting the X server.
 .El
 .Pp
 The mouse bindings are also important, they are:
diff --git a/kbfunc.c b/kbfunc.c
index 1275a83..ae9d9ad 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -263,6 +263,20 @@ kbfunc_exec(struct client_ctx *scratch, void *arg)
 	struct stat sb;
 	struct menu_q menuq;
 	struct menu *mi;
+	char *label;
+
+	int cmd = (int)arg;
+	switch(cmd) {
+		case CWM_EXEC_PROGRAM:
+			label = "exec";
+			break;
+		case CWM_EXEC_WM:
+			label = "wm";
+			break;
+		default:
+			err(1, "kbfunc_exec: invalid cmd %d", cmd);
+			/*NOTREACHED*/
+	}
 
 	if (getgroups(0, mygroups) == -1)
 		err(1, "getgroups failure");
@@ -320,8 +334,19 @@ kbfunc_exec(struct client_ctx *scratch, void *arg)
 	}
 
 	if ((mi = search_start(&menuq,
-		    search_match_exec, NULL, NULL, "exec", 1)) != NULL)
-		u_spawn(mi->text);
+		    search_match_exec, NULL, NULL, label, 1)) != NULL) {
+		switch (cmd) {
+			case CWM_EXEC_PROGRAM:
+				u_spawn(mi->text);
+				break;
+			case CWM_EXEC_WM:
+				exec_wm(mi->text);
+				break;
+			default:
+				err(1, "kb_func: egad, cmd changed value!");
+				break;
+		}
+	}
 
 	if (mi != NULL && mi->dummy)
 		xfree(mi);
diff --git a/util.c b/util.c
index 4214ce6..9c570c5 100644
--- a/util.c
+++ b/util.c
@@ -39,6 +39,22 @@ u_spawn(char *argstr)
 	return (0);
 }
 
+void
+exec_wm(char *argstr)
+{
+	char *args[MAXARGLEN], **ap = args;
+	char **end = &args[MAXARGLEN - 1];
+
+	while (ap < end && (*ap = strsep(&argstr, " \t")) != NULL)
+		ap++;
+
+	*ap = NULL;
+	setsid();
+	execvp(args[0], args);
+	err(1, args[0]);
+}
+
+
 int dirent_exists(char *filename) {
        struct stat buffer;