summary refs log tree commit diff
path: root/calmwm.c
diff options
context:
space:
mode:
authorokan <okan>2018-02-06 15:05:20 +0000
committerokan <okan>2018-02-06 15:05:20 +0000
commit63ebc0cd8b65300104929d3463fed431996f4374 (patch)
treef547800ff23c62896ad849d2148ec7adf3f08f0d /calmwm.c
parenta0774f4777a4a94ea4bbc867c16cde3167075f80 (diff)
parentf3211427c16b755db20bc71ce4074e9fb9aae8af (diff)
downloadcwm-63ebc0cd8b65300104929d3463fed431996f4374.tar.gz
cwm-63ebc0cd8b65300104929d3463fed431996f4374.tar.xz
cwm-63ebc0cd8b65300104929d3463fed431996f4374.zip
cvsimport
* refs/heads/master: (28 commits)
  Use screen's saved view instead of re-querying the server.
  Slightly expand and expose verbose debugging.
  add debugging for x events
  Add a simple debug logging mechanism.
  Simplification; use asprintf where appropriate now.
  Use func attributes where appropriate.
  Fix wins comparison declaration since it's unsigned from XQueryTree().
  Generate name_to_func[] in a clean and readable fashion.
  Shrink tier[] by one after removing matchname in r1.55.
  If the requested group number is invalid, bail but don't kill cwm.
  Quick fix: exit after a failed execvp in u_spawn instead; previously we did in u_exec, but the introduction of re-exec'ing the previous invocation of cwm if 'exec_wm' failed missed the 'exec' failing path. Will likely split out as a proper fix.
  Only exec the fallback when in CWM_EXEC_WM state.
  Typo, from Julien Steinhauser.
  Convert menu-exec-wm from an abritrary exec menu, into a config-based menu from which one may configure (wm <name> <path_and_args>) (and choose) specific window managers to replace the running one. 'wm cwm cwm' is included by default.
  As done for buttonrelease, work specific un-cycling and un-highlighting actions into the keyrelease event, only performing what's actually needed for each; should result in much fewer events against keyreleases. No intended behaviour change.
  Merge group_toggle_membership_leave into the buttonrelease event and only do border work for a group/ungroup action.
  add helper function client_show to bring together like actions for unhide/raise
  Add support for re-exec'ing with SIGHUP; equivalent to the already built-in 'restart' function.
  Use poll and XNextEvent to replace XNextEvent blocking inside the x11 event handler.
  zap stray that snuck in
  ...
Diffstat (limited to 'calmwm.c')
-rw-r--r--calmwm.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/calmwm.c b/calmwm.c
index c3943c4..51b6a87 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -27,6 +27,7 @@
 #include <getopt.h>
 #include <limits.h>
 #include <locale.h>
+#include <poll.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdio.h>
@@ -46,7 +47,7 @@ volatile sig_atomic_t	 cwm_status;
 
 static void	sighdlr(int);
 static int	x_errorhandler(Display *, XErrorEvent *);
-static void	x_init(const char *);
+static int	x_init(const char *);
 static void	x_teardown(void);
 static int	x_wmerrorhandler(Display *, XErrorEvent *);
 
@@ -55,15 +56,18 @@ main(int argc, char **argv)
 {
 	const char	*conf_file = NULL;
 	char		*conf_path, *display_name = NULL;
-	int		 ch;
+	char		*fallback;
+	int		 ch, xfd;
+	struct pollfd	 pfd[1];
 	struct passwd	*pw;
 
 	if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
 		warnx("no locale support");
 	mbtowc(NULL, NULL, MB_CUR_MAX);
 
+	fallback = u_argv(argv);
 	Conf.wm_argv = u_argv(argv);
-	while ((ch = getopt(argc, argv, "c:d:")) != -1) {
+	while ((ch = getopt(argc, argv, "c:d:v")) != -1) {
 		switch (ch) {
 		case 'c':
 			conf_file = optarg;
@@ -71,6 +75,9 @@ main(int argc, char **argv)
 		case 'd':
 			display_name = optarg;
 			break;
+		case 'v':
+			Conf.debug++;
+			break;
 		default:
 			usage();
 		}
@@ -80,8 +87,11 @@ main(int argc, char **argv)
 
 	if (signal(SIGCHLD, sighdlr) == SIG_ERR)
 		err(1, "signal");
+	if (signal(SIGHUP, sighdlr) == SIG_ERR)
+		err(1, "signal");
 
-	if ((Conf.homedir = getenv("HOME")) == NULL || Conf.homedir[0] == '\0') {
+	Conf.homedir = getenv("HOME");
+	if ((Conf.homedir == NULL) || (Conf.homedir[0] == '\0')) {
 		pw = getpwuid(getuid());
 		if (pw != NULL && pw->pw_dir != NULL && *pw->pw_dir != '\0')
 			Conf.homedir = pw->pw_dir;
@@ -107,7 +117,7 @@ main(int argc, char **argv)
 		warnx("config file %s has errors", conf_path);
 	free(conf_path);
 
-	x_init(display_name);
+	xfd = x_init(display_name);
 	cwm_status = CWM_RUNNING;
 
 #ifdef __OpenBSD__
@@ -115,16 +125,27 @@ main(int argc, char **argv)
 		err(1, "pledge");
 #endif
 
-	while (cwm_status == CWM_RUNNING)
+	memset(&pfd, 0, sizeof(pfd));
+	pfd[0].fd = xfd;
+	pfd[0].events = POLLIN;
+	while (cwm_status == CWM_RUNNING) {
 		xev_process();
+		if (poll(pfd, 1, INFTIM) == -1) {
+			if (errno != EINTR)
+				warn("poll");
+		}
+	}
 	x_teardown();
-	if (cwm_status == CWM_EXEC_WM)
+	if (cwm_status == CWM_EXEC_WM) {
 		u_exec(Conf.wm_argv);
+		warnx("'%s' failed to start, restarting fallback", Conf.wm_argv);
+		u_exec(fallback);
+	}
 
 	return(0);
 }
 
-static void
+static int
 x_init(const char *dpyname)
 {
 	int	i;
@@ -144,6 +165,8 @@ x_init(const char *dpyname)
 
 	for (i = 0; i < ScreenCount(X_Dpy); i++)
 		screen_init(i);
+
+	return ConnectionNumber(X_Dpy);
 }
 
 static void
@@ -210,6 +233,9 @@ sighdlr(int sig)
 		    (pid < 0 && errno == EINTR))
 			;
 		break;
+	case SIGHUP:
+		cwm_status = CWM_EXEC_WM;
+		break;
 	}
 
 	errno = save_errno;
@@ -220,7 +246,7 @@ usage(void)
 {
 	extern char	*__progname;
 
-	(void)fprintf(stderr, "usage: %s [-c file] [-d display]\n",
+	(void)fprintf(stderr, "usage: %s [-v] [-c file] [-d display]\n",
 	    __progname);
 	exit(1);
 }