summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c9
-rw-r--r--calmwm.h7
-rw-r--r--conf.c20
-rw-r--r--cwmrc.516
-rw-r--r--kbfunc.c50
-rw-r--r--search.c188
6 files changed, 192 insertions, 98 deletions
diff --git a/calmwm.c b/calmwm.c
index 7988273..c3943c4 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -42,7 +42,6 @@ Atom			 cwmh[CWMH_NITEMS];
 Atom			 ewmh[EWMH_NITEMS];
 struct screen_q		 Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
 struct conf		 Conf;
-const char		*homedir;
 volatile sig_atomic_t	 cwm_status;
 
 static void	sighdlr(int);
@@ -82,16 +81,16 @@ main(int argc, char **argv)
 	if (signal(SIGCHLD, sighdlr) == SIG_ERR)
 		err(1, "signal");
 
-	if ((homedir = getenv("HOME")) == NULL || *homedir == '\0') {
+	if ((Conf.homedir = getenv("HOME")) == NULL || Conf.homedir[0] == '\0') {
 		pw = getpwuid(getuid());
 		if (pw != NULL && pw->pw_dir != NULL && *pw->pw_dir != '\0')
-			homedir = pw->pw_dir;
+			Conf.homedir = pw->pw_dir;
 		else
-			homedir = "/";
+			Conf.homedir = "/";
 	}
 
 	if (conf_file == NULL)
-		xasprintf(&conf_path, "%s/%s", homedir, CONFFILE);
+		xasprintf(&conf_path, "%s/%s", Conf.homedir, CONFFILE);
 	else
 		conf_path = xstrdup(conf_file);
 
diff --git a/calmwm.h b/calmwm.h
index 9ac69a4..26d8189 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -314,6 +314,7 @@ struct conf {
 	Cursor			 cursor[CF_NITEMS];
 	int			 xrandr;
 	int			 xrandr_event_base;
+	char			*homedir;
 	char			*wm_argv;
 };
 
@@ -395,7 +396,6 @@ extern Atom				 cwmh[CWMH_NITEMS];
 extern Atom				 ewmh[EWMH_NITEMS];
 extern struct screen_q			 Screenq;
 extern struct conf			 Conf;
-extern const char			*homedir;
 
 void			 usage(void);
 
@@ -465,6 +465,10 @@ void			 search_match_path(struct menu_q *, struct menu_q *,
 			     char *);
 void			 search_match_text(struct menu_q *, struct menu_q *,
 			     char *);
+void			 search_match_cmd(struct menu_q *, struct menu_q *,
+			     char *);
+void			 search_match_group(struct menu_q *, struct menu_q *,
+			     char *);
 void			 search_print_client(struct menu *, int);
 void			 search_print_cmd(struct menu *, int);
 void			 search_print_group(struct menu *, int);
@@ -482,6 +486,7 @@ void			 screen_assert_clients_within(struct screen_ctx *);
 
 void			 kbfunc_cwm_status(void *, struct cargs *);
 void			 kbfunc_ptrmove(void *, struct cargs *);
+void			 kbfunc_client_snap(void *, struct cargs *);
 void			 kbfunc_client_move(void *, struct cargs *);
 void			 kbfunc_client_resize(void *, struct cargs *);
 void			 kbfunc_client_delete(void *, struct cargs *);
diff --git a/conf.c b/conf.c
index d750c42..0234f48 100644
--- a/conf.c
+++ b/conf.c
@@ -92,6 +92,24 @@ static const struct {
 	{ "window-movetogroup-8", kbfunc_client_movetogroup, CWM_CONTEXT_CC, 8 },
 	{ "window-movetogroup-9", kbfunc_client_movetogroup, CWM_CONTEXT_CC, 9 },
 
+	{ "window-snap-up", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_UP) },
+	{ "window-snap-down", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_DOWN) },
+	{ "window-snap-left", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_LEFT) },
+	{ "window-snap-right", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_RIGHT) },
+
+	{ "window-snap-up-right", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_UP|CWM_RIGHT) },
+	{ "window-snap-up-left", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_UP|CWM_LEFT) },
+	{ "window-snap-down-right", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_DOWN|CWM_RIGHT) },
+	{ "window-snap-down-left", kbfunc_client_snap, CWM_CONTEXT_CC,
+	    (CWM_DOWN|CWM_LEFT) },
+
 	{ "window-move", kbfunc_client_move, CWM_CONTEXT_CC, 0 },
 	{ "window-move-up", kbfunc_client_move, CWM_CONTEXT_CC,
 	    (CWM_UP) },
@@ -297,7 +315,7 @@ conf_init(struct conf *c)
 	conf_cmd_add(c, "term", "xterm");
 
 	(void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s",
-	    homedir, ".ssh/known_hosts");
+	    c->homedir, ".ssh/known_hosts");
 
 	c->font = xstrdup("sans-serif:pixelsize=14:bold");
 	c->wmname = xstrdup("CWM");
diff --git a/cwmrc.5 b/cwmrc.5
index a29fd12..6851faa 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -398,6 +398,22 @@ pixels right.
 Resize window 10 times
 .Ar moveamount
 pixels left.
+.It window-snap-up
+Snap window to top edge.
+.It window-snap-down
+Snap window to bottom edge.
+.It window-snap-right
+Snap window to right edge.
+.It window-snap-left
+Snap window to left edge.
+.It window-snap-up-right
+Snap window to top-right corner.
+.It window-snap-up-left
+Snap window to top-left corner.
+.It window-snap-down-right
+Snap window to bottom-right corner.
+.It window-snap-down-left
+Snap window to bottom-left corner.
 .It pointer-move-up
 Move pointer
 .Ar moveamount
diff --git a/kbfunc.c b/kbfunc.c
index 01d45b0..e2a125b 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -290,6 +290,42 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
 }
 
 void
+kbfunc_client_snap(void *ctx, struct cargs *cargs)
+{
+	struct client_ctx	*cc = ctx;
+	struct screen_ctx	*sc = cc->sc;
+	struct geom		 area;
+	int			 flags;
+
+	area = screen_area(sc,
+	    cc->geom.x + cc->geom.w / 2,
+	    cc->geom.y + cc->geom.h / 2, CWM_GAP);
+
+	flags = cargs->flag;
+	while (flags) {
+		if (flags & CWM_UP) {
+			cc->geom.y = area.y;
+			flags &= ~CWM_UP;
+		}
+		if (flags & CWM_LEFT) {
+			cc->geom.x = area.x;
+			flags &= ~CWM_LEFT;
+		}
+		if (flags & CWM_RIGHT) {
+			cc->geom.x = area.x + area.w - cc->geom.w -
+			    (cc->bwidth * 2);
+			flags &= ~CWM_RIGHT;
+		}
+		if (flags & CWM_DOWN) {
+			cc->geom.y = area.y + area.h - cc->geom.h -
+			    (cc->bwidth * 2);
+			flags &= ~CWM_DOWN;
+		}
+	}
+	client_move(cc);
+}
+
+void
 kbfunc_client_delete(void *ctx, struct cargs *cargs)
 {
 	client_send_delete(ctx);
@@ -463,14 +499,13 @@ kbfunc_menu_cmd(void *ctx, struct cargs *cargs)
 		if ((strcmp(cmd->name, "lock") == 0) ||
 		    (strcmp(cmd->name, "term") == 0))
 			continue;
-		/* search_match_text() needs mi->text */
-		menuq_add(&menuq, cmd, "%s", cmd->name);
+		menuq_add(&menuq, cmd, NULL);
 	}
 
 	if ((mi = menu_filter(sc, &menuq,
 	    (m) ? NULL : "application", NULL,
 	    ((m) ? CWM_MENU_LIST : 0),
-	    search_match_text, search_print_cmd)) != NULL) {
+	    search_match_cmd, search_print_cmd)) != NULL) {
 		cmd = (struct cmd_ctx *)mi->ctx;
 		u_spawn(cmd->path);
 	}
@@ -491,12 +526,12 @@ kbfunc_menu_group(void *ctx, struct cargs *cargs)
 	TAILQ_FOREACH(gc, &sc->groupq, entry) {
 		if (group_holds_only_sticky(gc))
 			continue;
-		menuq_add(&menuq, gc, "%d %s", gc->num, gc->name);
+		menuq_add(&menuq, gc, NULL);
 	}
 
 	if ((mi = menu_filter(sc, &menuq,
 	    (m) ? NULL : "group", NULL, (CWM_MENU_LIST),
-	    search_match_text, search_print_group)) != NULL) {
+	    search_match_group, search_print_group)) != NULL) {
 		gc = (struct group_ctx *)mi->ctx;
 		(group_holds_only_hidden(gc)) ?
 		    group_show(gc) : group_hide(gc);
@@ -631,9 +666,8 @@ kbfunc_menu_ssh(void *ctx, struct cargs *cargs)
 		/* skip hashed hosts */
 		if (strncmp(buf, HASH_MARKER, strlen(HASH_MARKER)) == 0)
 			continue;
-		for (p = buf; *p != ',' && *p != ' ' && p != buf + slen; p++) {
-			/* do nothing */
-		}
+		for (p = buf; *p != ',' && *p != ' ' && p != buf + slen; p++)
+			;
 		/* ignore badness */
 		if (p - buf + 1 > sizeof(hostbuf))
 			continue;
diff --git a/search.c b/search.c
index 7d32291..68c064e 100644
--- a/search.c
+++ b/search.c
@@ -36,9 +36,35 @@
 #define PATH_ANY 	0x0001
 #define PATH_EXEC 	0x0002
 
-static void	search_match_path_type(struct menu_q *, struct menu_q *,
-		    char *, int);
-static int	strsubmatch(char *, char *, int);
+static void	match_path_type(struct menu_q *, char *, int);
+static int	match_substr(char *, char *, int);
+
+static int
+match_substr(char *sub, char *str, int zeroidx)
+{
+	size_t		 len, sublen;
+	unsigned int	 n, flen;
+
+	if (sub == NULL || str == NULL)
+		return(0);
+
+	len = strlen(str);
+	sublen = strlen(sub);
+
+	if (sublen > len)
+		return(0);
+
+	if (zeroidx)
+		flen = 0;
+	else
+		flen = len - sublen;
+
+	for (n = 0; n <= flen; n++)
+		if (strncasecmp(sub, str + n, sublen) == 0)
+			return(1);
+
+	return(0);
+}
 
 void
 search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
@@ -46,29 +72,28 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
 	struct winname	*wn;
 	struct menu	*mi, *tierp[4], *before = NULL;
 
-	TAILQ_INIT(resultq);
-
 	(void)memset(tierp, 0, sizeof(tierp));
 
+	TAILQ_INIT(resultq);
 	TAILQ_FOREACH(mi, menuq, entry) {
 		int tier = -1, t;
 		struct client_ctx *cc = (struct client_ctx *)mi->ctx;
 
 		/* Match on label. */
-		if (strsubmatch(search, cc->label, 0))
+		if (match_substr(search, cc->label, 0))
 			tier = 0;
 
 		/* Match on window name history, from present to past. */
 		if (tier < 0) {
 			TAILQ_FOREACH_REVERSE(wn, &cc->nameq, name_q, entry)
-				if (strsubmatch(search, wn->name, 0)) {
+				if (match_substr(search, wn->name, 0)) {
 					tier = 2;
 					break;
 				}
 		}
 
 		/* Match on window resource class. */
-		if ((tier < 0) && strsubmatch(search, cc->ch.res_class, 0))
+		if ((tier < 0) && match_substr(search, cc->ch.res_class, 0))
 			tier = 3;
 
 		if (tier < 0)
@@ -105,48 +130,36 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
 }
 
 void
-search_print_text(struct menu *mi, int listing)
-{
-	(void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text);
-}
-
-void
-search_print_cmd(struct menu *mi, int listing)
-{
-	struct cmd_ctx	*cmd = (struct cmd_ctx *)mi->ctx;
-
-	(void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name);
-}
-
-void
-search_print_group(struct menu *mi, int listing)
+search_match_cmd(struct menu_q *menuq, struct menu_q *resultq, char *search)
 {
-	struct group_ctx	*gc = (struct group_ctx *)mi->ctx;
+	struct menu	*mi;
 
-	(void)snprintf(mi->print, sizeof(mi->print),
-	    (group_holds_only_hidden(gc)) ? "%d: [%s]" : "%d: %s",
-	    gc->num, gc->name);
+	TAILQ_INIT(resultq);
+	TAILQ_FOREACH(mi, menuq, entry) {
+		struct cmd_ctx *cmd = (struct cmd_ctx *)mi->ctx;
+		if (match_substr(search, cmd->name, 0))
+			TAILQ_INSERT_TAIL(resultq, mi, resultentry);
+	}
 }
 
 void
-search_print_client(struct menu *mi, int listing)
+search_match_group(struct menu_q *menuq, struct menu_q *resultq, char *search)
 {
-	struct client_ctx	*cc = (struct client_ctx *)mi->ctx;
-	char			 flag = ' ';
-
-	if (cc->flags & CLIENT_ACTIVE)
-		flag = '!';
-	else if (cc->flags & CLIENT_HIDDEN)
-		flag = '&';
+	struct menu	*mi;
+	char		*s;
 
-	(void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s",
-	    (cc->gc) ? cc->gc->num : 0, flag,
-	    (cc->label) ? cc->label : "", cc->name);
+	TAILQ_INIT(resultq);
+	TAILQ_FOREACH(mi, menuq, entry) {
+		struct group_ctx *gc = (struct group_ctx *)mi->ctx;
+		xasprintf(&s, "%d %s", gc->num, gc->name);
+		if (match_substr(search, s, 0))
+			TAILQ_INSERT_TAIL(resultq, mi, resultentry);
+		free(s);
+	}
 }
 
 static void
-search_match_path_type(struct menu_q *menuq, struct menu_q *resultq,
-    char *search, int flag)
+match_path_type(struct menu_q *resultq, char *search, int flag)
 {
 	struct menu     *mi;
 	char 		 pattern[PATH_MAX];
@@ -155,7 +168,6 @@ search_match_path_type(struct menu_q *menuq, struct menu_q *resultq,
 
 	(void)strlcpy(pattern, search, sizeof(pattern));
 	(void)strlcat(pattern, "*", sizeof(pattern));
-
 	if (glob(pattern, GLOB_MARK, NULL, &g) != 0)
 		return;
 	for (i = 0; i < g.gl_pathc; i++) {
@@ -169,35 +181,14 @@ search_match_path_type(struct menu_q *menuq, struct menu_q *resultq,
 }
 
 void
-search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search)
-{
-	TAILQ_INIT(resultq);
-
-	search_match_path_type(menuq, resultq, search, PATH_ANY);
-}
-
-void
-search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
-{
-	struct menu	*mi;
-
-	TAILQ_INIT(resultq);
-
-	TAILQ_FOREACH(mi, menuq, entry)
-		if (strsubmatch(search, mi->text, 0))
-			TAILQ_INSERT_TAIL(resultq, mi, resultentry);
-}
-
-void
 search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
 {
 	struct menu	*mi, *mj;
 	int		 r;
 
 	TAILQ_INIT(resultq);
-
 	TAILQ_FOREACH(mi, menuq, entry) {
-		if (strsubmatch(search, mi->text, 1) == 0 &&
+		if (match_substr(search, mi->text, 1) == 0 &&
 		    fnmatch(search, mi->text, 0) == FNM_NOMATCH)
 			continue;
 		TAILQ_FOREACH(mj, resultq, resultentry) {
@@ -210,34 +201,65 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
 		if (mj == NULL)
 			TAILQ_INSERT_TAIL(resultq, mi, resultentry);
 	}
-
 	if (TAILQ_EMPTY(resultq))
-		search_match_path_type(menuq, resultq, search, PATH_EXEC);
+		match_path_type(resultq, search, PATH_EXEC);
 }
 
-static int
-strsubmatch(char *sub, char *str, int zeroidx)
+void
+search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search)
 {
-	size_t		 len, sublen;
-	unsigned int	 n, flen;
+	TAILQ_INIT(resultq);
+	match_path_type(resultq, search, PATH_ANY);
+}
 
-	if (sub == NULL || str == NULL)
-		return(0);
+void
+search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
+{
+	struct menu	*mi;
 
-	len = strlen(str);
-	sublen = strlen(sub);
+	TAILQ_INIT(resultq);
+	TAILQ_FOREACH(mi, menuq, entry) {
+		if (match_substr(search, mi->text, 0))
+			TAILQ_INSERT_TAIL(resultq, mi, resultentry);
+	}
+}
 
-	if (sublen > len)
-		return(0);
+void
+search_print_client(struct menu *mi, int listing)
+{
+	struct client_ctx	*cc = (struct client_ctx *)mi->ctx;
+	char			 flag = ' ';
 
-	if (!zeroidx)
-		flen = len - sublen;
-	else
-		flen = 0;
+	if (cc->flags & CLIENT_ACTIVE)
+		flag = '!';
+	else if (cc->flags & CLIENT_HIDDEN)
+		flag = '&';
 
-	for (n = 0; n <= flen; n++)
-		if (strncasecmp(sub, str + n, sublen) == 0)
-			return(1);
+	(void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s",
+	    (cc->gc) ? cc->gc->num : 0, flag,
+	    (cc->label) ? cc->label : "", cc->name);
+}
 
-	return(0);
+void
+search_print_cmd(struct menu *mi, int listing)
+{
+	struct cmd_ctx	*cmd = (struct cmd_ctx *)mi->ctx;
+
+	(void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name);
+}
+
+void
+search_print_group(struct menu *mi, int listing)
+{
+	struct group_ctx	*gc = (struct group_ctx *)mi->ctx;
+
+	(void)snprintf(mi->print, sizeof(mi->print),
+	    (group_holds_only_hidden(gc)) ? "%d: [%s]" : "%d: %s",
+	    gc->num, gc->name);
+}
+
+void
+search_print_text(struct menu *mi, int listing)
+{
+	(void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text);
 }