summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c6
-rw-r--r--calmwm.h94
-rw-r--r--client.c8
-rw-r--r--conf.c270
-rw-r--r--group.c2
-rw-r--r--kbfunc.c209
-rw-r--r--mousefunc.c2
-rw-r--r--screen.c31
-rw-r--r--xevents.c4
9 files changed, 347 insertions, 279 deletions
diff --git a/calmwm.c b/calmwm.c
index dc34865..fa32dbb 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -113,10 +113,14 @@ main(int argc, char **argv)
 
 	x_init(display_name);
 	cwm_status = CWM_RUNNING;
+
+	if (pledge("stdio rpath proc exec", NULL) == -1)
+		err(1, "pledge");
+
 	while (cwm_status == CWM_RUNNING)
 		xev_process();
 	x_teardown();
-	if (cwm_status == CWM_EXECWM)
+	if (cwm_status == CWM_EXEC_WM)
 		u_exec(wm_argv);
 
 	return(0);
diff --git a/calmwm.h b/calmwm.h
index 49370cf..b51b409 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -71,51 +71,46 @@ size_t strlcpy(char *, const char *, size_t);
 #define KEYMASK		(KeyPressMask | ExposureMask)
 #define IGNOREMODMASK	(LockMask | Mod2Mask | 0x2000)
 
-/* kb movement */
-#define CWM_MOVE		0x0001
-#define CWM_RESIZE		0x0002
-#define CWM_PTRMOVE		0x0004
-#define CWM_BIGMOVE		0x0008
-#define CWM_UP			0x0010
-#define CWM_DOWN		0x0020
-#define CWM_LEFT		0x0040
-#define CWM_RIGHT		0x0080
-
-/* exec */
-#define	CWM_EXEC_PROGRAM	0x0001
-#define	CWM_EXEC_WM		0x0002
-
-/* cycle */
-#define CWM_CYCLE		0x0001
-#define CWM_RCYCLE		0x0002
-#define CWM_INGROUP		0x0004
-
-/* menu */
+/* direction/amount */
+#define CWM_UP			0x0001
+#define CWM_DOWN		0x0002
+#define CWM_LEFT		0x0004
+#define CWM_RIGHT		0x0008
+#define CWM_BIGAMOUNT		0x0010
+#define DIRECTIONMASK	(CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
+
+#define CWM_CLIENT_CYCLE	0x0001
+#define CWM_CLIENT_RCYCLE	0x0002
+#define CWM_CLIENT_CYCLE_INGRP	0x0004
+
+#define CWM_CLIENT_TILE_HORIZ	0x0001
+#define CWM_CLIENT_TILE_VERT	0x0002
+
+#define CWM_MENU_EXEC		0x0001
+#define CWM_MENU_EXEC_WM	0x0002
+
 #define CWM_MENU_DUMMY		0x0001
 #define CWM_MENU_FILE		0x0002
 #define CWM_MENU_LIST		0x0004
 
-#define ARG_CHAR		0x0001
-#define ARG_INT			0x0002
-
-#define CWM_TILE_HORIZ 		0x0001
-#define CWM_TILE_VERT 		0x0002
-
 #define CWM_GAP			0x0001
 #define CWM_NOGAP		0x0002
 
-#define CWM_WIN			0x0001
-#define CWM_CMD			0x0002
+#define CWM_KBD			0x0001
+#define CWM_MOUSE		0x0002
+
+#define CWM_CONTEXT_NONE	0x0000
+#define CWM_CONTEXT_CLIENT	0x0001
+#define CWM_CONTEXT_SCREEN	0x0002
 
 #define CWM_QUIT		0x0000
 #define CWM_RUNNING		0x0001
-#define CWM_EXECWM		0x0002
+#define CWM_EXEC_WM		0x0002
 
 union arg {
 	char	*c;
 	int	 i;
 };
-
 union press {
 	KeySym		 keysym;
 	unsigned int	 button;
@@ -129,7 +124,6 @@ enum cursor_font {
 	CF_RESIZE,
 	CF_NITEMS
 };
-
 enum color {
 	CWM_COLOR_BORDER_ACTIVE,
 	CWM_COLOR_BORDER_INACTIVE,
@@ -246,6 +240,8 @@ struct region_ctx {
 	TAILQ_ENTRY(region_ctx)	 entry;
 	int			 num;
 	struct geom		 area;
+	struct geom		 view; /* viewable area */
+	struct geom		 work; /* workable area, gap-applied */
 };
 TAILQ_HEAD(region_ctx_q, region_ctx);
 
@@ -277,7 +273,7 @@ struct binding {
 	union arg		 argument;
 	unsigned int		 modmask;
 	union press		 press;
-	int			 flags;
+	int			 context;
 };
 TAILQ_HEAD(keybinding_q, binding);
 TAILQ_HEAD(mousebinding_q, binding);
@@ -478,6 +474,7 @@ void			 search_print_client(struct menu *, int);
 void			 search_print_cmd(struct menu *, int);
 void			 search_print_group(struct menu *, int);
 
+struct region_ctx	*region_find(struct screen_ctx *, int, int);
 struct geom		 screen_apply_gap(struct screen_ctx *, struct geom);
 struct screen_ctx	*screen_find(Window);
 struct geom		 screen_area(struct screen_ctx *, int, int, int);
@@ -486,26 +483,19 @@ void			 screen_update_geometry(struct screen_ctx *);
 void			 screen_updatestackingorder(struct screen_ctx *);
 
 void			 kbfunc_client_cycle(struct client_ctx *, union arg *);
-void			 kbfunc_client_cyclegroup(struct client_ctx *,
-			     union arg *);
 void			 kbfunc_client_delete(struct client_ctx *, union arg *);
-void			 kbfunc_client_group(struct client_ctx *, union arg *);
-void			 kbfunc_client_grouponly(struct client_ctx *,
-			     union arg *);
 void			 kbfunc_client_grouptoggle(struct client_ctx *,
 			     union arg *);
 void			 kbfunc_client_hide(struct client_ctx *, union arg *);
 void			 kbfunc_client_label(struct client_ctx *, union arg *);
 void			 kbfunc_client_lower(struct client_ctx *, union arg *);
-void			 kbfunc_client_moveresize(struct client_ctx *,
-			     union arg *);
+void			 kbfunc_client_move(struct client_ctx *, union arg *);
 void			 kbfunc_client_movetogroup(struct client_ctx *,
 			     union arg *);
-void			 kbfunc_client_nogroup(struct client_ctx *,
-			     union arg *);
 void			 kbfunc_client_raise(struct client_ctx *, union arg *);
 void			 kbfunc_client_rcycle(struct client_ctx *, union arg *);
-void			 kbfunc_client_search(struct client_ctx *, union arg *);
+void			 kbfunc_client_resize(struct client_ctx *, union arg *);
+void 			 kbfunc_client_tile(struct client_ctx *, union arg *);
 void			 kbfunc_client_toggle_freeze(struct client_ctx *,
     			     union arg *);
 void			 kbfunc_client_toggle_fullscreen(struct client_ctx *,
@@ -518,24 +508,30 @@ void			 kbfunc_client_toggle_sticky(struct client_ctx *,
     			     union arg *);
 void			 kbfunc_client_toggle_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_exec_lock(struct client_ctx *, union arg *);
+void			 kbfunc_exec_term(struct client_ctx *, union arg *);
+void			 kbfunc_group_alltoggle(struct client_ctx *,
+			     union arg *);
+void			 kbfunc_group_cycle(struct client_ctx *, union arg *);
+void			 kbfunc_group_only(struct client_ctx *, union arg *);
+void			 kbfunc_group_toggle(struct client_ctx *, union arg *);
+void			 kbfunc_menu_exec(struct client_ctx *, union arg *);
+void			 kbfunc_menu_client(struct client_ctx *, union arg *);
 void			 kbfunc_menu_cmd(struct client_ctx *, union arg *);
 void			 kbfunc_menu_group(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 *);
+void			 kbfunc_menu_ssh(struct client_ctx *, union arg *);
+void			 kbfunc_ptrmove(struct client_ctx *, union arg *);
 
 void			 mousefunc_client_move(struct client_ctx *,
     			    union arg *);
 void			 mousefunc_client_resize(struct client_ctx *,
     			    union arg *);
+void			 mousefunc_menu_client(struct client_ctx *,
+			    union arg *);
 void			 mousefunc_menu_cmd(struct client_ctx *, union arg *);
 void			 mousefunc_menu_group(struct client_ctx *, union arg *);
-void			 mousefunc_menu_unhide(struct client_ctx *,
-    			    union arg *);
 
 struct menu  		*menu_filter(struct screen_ctx *, struct menu_q *,
 			     const char *, const char *, int,
diff --git a/client.c b/client.c
index bce2cc4..aa544ec 100644
--- a/client.c
+++ b/client.c
@@ -678,7 +678,7 @@ client_cycle(struct screen_ctx *sc, int flags)
 
 	oldcc = client_current();
 	if (oldcc == NULL)
-		oldcc = (flags & CWM_RCYCLE) ?
+		oldcc = (flags & CWM_CLIENT_RCYCLE) ?
 		    TAILQ_LAST(&sc->clientq, client_ctx_q) :
 		    TAILQ_FIRST(&sc->clientq);
 
@@ -686,12 +686,12 @@ client_cycle(struct screen_ctx *sc, int flags)
 	while (again) {
 		again = 0;
 
-		newcc = (flags & CWM_RCYCLE) ? client_prev(newcc) :
+		newcc = (flags & CWM_CLIENT_RCYCLE) ? client_prev(newcc) :
 		    client_next(newcc);
 
 		/* Only cycle visible and non-ignored windows. */
 		if ((newcc->flags & (CLIENT_HIDDEN | CLIENT_IGNORE))
-		    || ((flags & CWM_INGROUP) &&
+		    || ((flags & CWM_CLIENT_CYCLE_INGRP) &&
 			(newcc->gc != oldcc->gc)))
 			again = 1;
 
@@ -839,6 +839,8 @@ client_getsizehints(struct client_ctx *cc)
 	}
 	cc->hint.incw = MAX(1, cc->hint.incw);
 	cc->hint.inch = MAX(1, cc->hint.inch);
+	cc->hint.minw = MAX(1, cc->hint.minw);
+	cc->hint.minh = MAX(1, cc->hint.minh);
 
 	if (size.flags & PAspect) {
 		if (size.min_aspect.x > 0)
diff --git a/conf.c b/conf.c
index a709d4c..13c08d2 100644
--- a/conf.c
+++ b/conf.c
@@ -346,126 +346,148 @@ conf_client(struct client_ctx *cc)
 static const struct {
 	const char	*tag;
 	void		 (*handler)(struct client_ctx *, union arg *);
-	int		 flags;
+	int		 context;
 	union arg	 argument;
 } name_to_func[] = {
-	{ "lower", kbfunc_client_lower, CWM_WIN, {0} },
-	{ "raise", kbfunc_client_raise, CWM_WIN, {0} },
-	{ "search", kbfunc_client_search, 0, {0} },
-	{ "menusearch", kbfunc_menu_cmd, 0, {0} },
-	{ "groupsearch", kbfunc_menu_group, 0, {0} },
-	{ "hide", kbfunc_client_hide, CWM_WIN, {0} },
-	{ "cycle", kbfunc_client_cycle, 0, {.i = CWM_CYCLE} },
-	{ "rcycle", kbfunc_client_cycle, 0, {.i = CWM_RCYCLE} },
-	{ "label", kbfunc_client_label, CWM_WIN, {0} },
-	{ "delete", kbfunc_client_delete, CWM_WIN, {0} },
-	{ "group1", kbfunc_client_group, 0, {.i = 1} },
-	{ "group2", kbfunc_client_group, 0, {.i = 2} },
-	{ "group3", kbfunc_client_group, 0, {.i = 3} },
-	{ "group4", kbfunc_client_group, 0, {.i = 4} },
-	{ "group5", kbfunc_client_group, 0, {.i = 5} },
-	{ "group6", kbfunc_client_group, 0, {.i = 6} },
-	{ "group7", kbfunc_client_group, 0, {.i = 7} },
-	{ "group8", kbfunc_client_group, 0, {.i = 8} },
-	{ "group9", kbfunc_client_group, 0, {.i = 9} },
-	{ "grouponly1", kbfunc_client_grouponly, 0, {.i = 1} },
-	{ "grouponly2", kbfunc_client_grouponly, 0, {.i = 2} },
-	{ "grouponly3", kbfunc_client_grouponly, 0, {.i = 3} },
-	{ "grouponly4", kbfunc_client_grouponly, 0, {.i = 4} },
-	{ "grouponly5", kbfunc_client_grouponly, 0, {.i = 5} },
-	{ "grouponly6", kbfunc_client_grouponly, 0, {.i = 6} },
-	{ "grouponly7", kbfunc_client_grouponly, 0, {.i = 7} },
-	{ "grouponly8", kbfunc_client_grouponly, 0, {.i = 8} },
-	{ "grouponly9", kbfunc_client_grouponly, 0, {.i = 9} },
-	{ "movetogroup1", kbfunc_client_movetogroup, CWM_WIN, {.i = 1} },
-	{ "movetogroup2", kbfunc_client_movetogroup, CWM_WIN, {.i = 2} },
-	{ "movetogroup3", kbfunc_client_movetogroup, CWM_WIN, {.i = 3} },
-	{ "movetogroup4", kbfunc_client_movetogroup, CWM_WIN, {.i = 4} },
-	{ "movetogroup5", kbfunc_client_movetogroup, CWM_WIN, {.i = 5} },
-	{ "movetogroup6", kbfunc_client_movetogroup, CWM_WIN, {.i = 6} },
-	{ "movetogroup7", kbfunc_client_movetogroup, CWM_WIN, {.i = 7} },
-	{ "movetogroup8", kbfunc_client_movetogroup, CWM_WIN, {.i = 8} },
-	{ "movetogroup9", kbfunc_client_movetogroup, CWM_WIN, {.i = 9} },
-	{ "nogroup", kbfunc_client_nogroup, 0, {0} },
-	{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
-	{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
-	{ "cycleingroup", kbfunc_client_cycle, CWM_WIN,
-	    {.i = (CWM_CYCLE | CWM_INGROUP)} },
-	{ "rcycleingroup", kbfunc_client_cycle, CWM_WIN,
-	    {.i = (CWM_RCYCLE | CWM_INGROUP)} },
-	{ "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 0}},
-	{ "sticky", kbfunc_client_toggle_sticky, CWM_WIN, {0} },
-	{ "fullscreen", kbfunc_client_toggle_fullscreen, CWM_WIN, {0} },
-	{ "maximize", kbfunc_client_toggle_maximize, CWM_WIN, {0} },
-	{ "vmaximize", kbfunc_client_toggle_vmaximize, CWM_WIN, {0} },
-	{ "hmaximize", kbfunc_client_toggle_hmaximize, CWM_WIN, {0} },
-	{ "freeze", kbfunc_client_toggle_freeze, CWM_WIN, {0} },
-	{ "restart", kbfunc_cwm_status, 0, {.i = CWM_EXECWM} },
-	{ "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} },
-	{ "terminal", kbfunc_term, 0, {0} },
-	{ "lock", kbfunc_lock, 0, {0} },
-	{ "moveup", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_UP | CWM_MOVE)} },
-	{ "movedown", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_DOWN | CWM_MOVE)} },
-	{ "moveright", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_RIGHT | CWM_MOVE)} },
-	{ "moveleft", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_LEFT | CWM_MOVE)} },
-	{ "bigmoveup", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_UP | CWM_MOVE | CWM_BIGMOVE)} },
-	{ "bigmovedown", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_DOWN | CWM_MOVE | CWM_BIGMOVE)} },
-	{ "bigmoveright", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_RIGHT | CWM_MOVE | CWM_BIGMOVE)} },
-	{ "bigmoveleft", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_LEFT | CWM_MOVE | CWM_BIGMOVE)} },
-	{ "resizeup", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_UP | CWM_RESIZE)} },
-	{ "resizedown", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_DOWN | CWM_RESIZE)} },
-	{ "resizeright", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_RIGHT | CWM_RESIZE)} },
-	{ "resizeleft", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_LEFT | CWM_RESIZE)} },
-	{ "bigresizeup", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_UP | CWM_RESIZE | CWM_BIGMOVE)} },
-	{ "bigresizedown", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_DOWN | CWM_RESIZE | CWM_BIGMOVE)} },
-	{ "bigresizeright", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_RIGHT | CWM_RESIZE | CWM_BIGMOVE)} },
-	{ "bigresizeleft", kbfunc_client_moveresize, CWM_WIN,
-	    {.i = (CWM_LEFT | CWM_RESIZE | CWM_BIGMOVE)} },
-	{ "ptrmoveup", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_UP | CWM_PTRMOVE)} },
-	{ "ptrmovedown", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_DOWN | CWM_PTRMOVE)} },
-	{ "ptrmoveleft", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_LEFT | CWM_PTRMOVE)} },
-	{ "ptrmoveright", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_RIGHT | CWM_PTRMOVE)} },
-	{ "bigptrmoveup", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_UP | CWM_PTRMOVE | CWM_BIGMOVE)} },
-	{ "bigptrmovedown", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_DOWN | CWM_PTRMOVE | CWM_BIGMOVE)} },
-	{ "bigptrmoveleft", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_LEFT | CWM_PTRMOVE | CWM_BIGMOVE)} },
-	{ "bigptrmoveright", kbfunc_client_moveresize, 0,
-	    {.i = (CWM_RIGHT | CWM_PTRMOVE | CWM_BIGMOVE)} },
-	{ "htile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_HORIZ} },
-	{ "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} },
-	{ "window_lower", kbfunc_client_lower, CWM_WIN, {0} },
-	{ "window_raise", kbfunc_client_raise, CWM_WIN, {0} },
-	{ "window_hide", kbfunc_client_hide, CWM_WIN, {0} },
-	{ "window_move", mousefunc_client_move, CWM_WIN, {0} },
-	{ "window_resize", mousefunc_client_resize, CWM_WIN, {0} },
-	{ "window_grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 1} },
-	{ "menu_group", mousefunc_menu_group, 0, {0} },
-	{ "menu_unhide", mousefunc_menu_unhide, 0, {0} },
-	{ "menu_cmd", mousefunc_menu_cmd, 0, {0} },
+	{ "lower", kbfunc_client_lower, CWM_CONTEXT_CLIENT, {0} },
+	{ "raise", kbfunc_client_raise, CWM_CONTEXT_CLIENT, {0} },
+	{ "search", kbfunc_menu_client, CWM_CONTEXT_SCREEN, {0} },
+	{ "menusearch", kbfunc_menu_cmd, CWM_CONTEXT_SCREEN, {0} },
+	{ "groupsearch", kbfunc_menu_group, CWM_CONTEXT_SCREEN, {0} },
+	{ "hide", kbfunc_client_hide, CWM_CONTEXT_CLIENT, {0} },
+	{ "cycle", kbfunc_client_cycle, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_CLIENT_CYCLE} },
+	{ "rcycle", kbfunc_client_cycle, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_CLIENT_RCYCLE} },
+	{ "label", kbfunc_client_label, CWM_CONTEXT_CLIENT, {0} },
+	{ "delete", kbfunc_client_delete, CWM_CONTEXT_CLIENT, {0} },
+	{ "group1", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 1} },
+	{ "group2", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 2} },
+	{ "group3", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 3} },
+	{ "group4", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 4} },
+	{ "group5", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 5} },
+	{ "group6", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 6} },
+	{ "group7", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 7} },
+	{ "group8", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 8} },
+	{ "group9", kbfunc_group_toggle, CWM_CONTEXT_SCREEN, {.i = 9} },
+	{ "grouponly1", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 1} },
+	{ "grouponly2", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 2} },
+	{ "grouponly3", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 3} },
+	{ "grouponly4", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 4} },
+	{ "grouponly5", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 5} },
+	{ "grouponly6", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 6} },
+	{ "grouponly7", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 7} },
+	{ "grouponly8", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 8} },
+	{ "grouponly9", kbfunc_group_only, CWM_CONTEXT_SCREEN, {.i = 9} },
+	{ "movetogroup1", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 1} },
+	{ "movetogroup2", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 2} },
+	{ "movetogroup3", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 3} },
+	{ "movetogroup4", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 4} },
+	{ "movetogroup5", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 5} },
+	{ "movetogroup6", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 6} },
+	{ "movetogroup7", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 7} },
+	{ "movetogroup8", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 8} },
+	{ "movetogroup9", kbfunc_client_movetogroup, CWM_CONTEXT_CLIENT,
+	    {.i = 9} },
+	{ "nogroup", kbfunc_group_alltoggle, CWM_CONTEXT_SCREEN, {0} },
+	{ "cyclegroup", kbfunc_group_cycle, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_CLIENT_CYCLE} },
+	{ "rcyclegroup", kbfunc_group_cycle, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_CLIENT_RCYCLE} },
+	{ "cycleingroup", kbfunc_client_cycle, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_CLIENT_CYCLE | CWM_CLIENT_CYCLE_INGRP)} },
+	{ "rcycleingroup", kbfunc_client_cycle, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_CLIENT_RCYCLE | CWM_CLIENT_CYCLE_INGRP)} },
+	{ "grouptoggle", kbfunc_client_grouptoggle, CWM_CONTEXT_CLIENT,
+	    {.i = CWM_KBD}},
+	{ "sticky", kbfunc_client_toggle_sticky, CWM_CONTEXT_CLIENT, {0} },
+	{ "fullscreen", kbfunc_client_toggle_fullscreen, CWM_CONTEXT_CLIENT,
+	    {0} },
+	{ "maximize", kbfunc_client_toggle_maximize, CWM_CONTEXT_CLIENT, {0} },
+	{ "vmaximize", kbfunc_client_toggle_vmaximize, CWM_CONTEXT_CLIENT,
+	    {0} },
+	{ "hmaximize", kbfunc_client_toggle_hmaximize, CWM_CONTEXT_CLIENT,
+	    {0} },
+	{ "freeze", kbfunc_client_toggle_freeze, CWM_CONTEXT_CLIENT, {0} },
+	{ "restart", kbfunc_cwm_status, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_EXEC_WM} },
+	{ "quit", kbfunc_cwm_status, CWM_CONTEXT_SCREEN, {.i = CWM_QUIT} },
+	{ "exec", kbfunc_menu_exec, CWM_CONTEXT_SCREEN, {.i = CWM_MENU_EXEC} },
+	{ "exec_wm", kbfunc_menu_exec, CWM_CONTEXT_SCREEN,
+	    {.i = CWM_MENU_EXEC_WM} },
+	{ "ssh", kbfunc_menu_ssh, CWM_CONTEXT_SCREEN, {0} },
+	{ "terminal", kbfunc_exec_term, CWM_CONTEXT_SCREEN, {0} },
+	{ "lock", kbfunc_exec_lock, CWM_CONTEXT_SCREEN, {0} },
+	{ "moveup", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_UP)} },
+	{ "movedown", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_DOWN)} },
+	{ "moveright", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_RIGHT)} },
+	{ "moveleft", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_LEFT)} },
+	{ "bigmoveup", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_UP | CWM_BIGAMOUNT)} },
+	{ "bigmovedown", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_DOWN | CWM_BIGAMOUNT)} },
+	{ "bigmoveright", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} },
+	{ "bigmoveleft", kbfunc_client_move, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_LEFT | CWM_BIGAMOUNT)} },
+	{ "resizeup", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_UP)} },
+	{ "resizedown", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_DOWN)} },
+	{ "resizeright", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_RIGHT)} },
+	{ "resizeleft", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_LEFT)} },
+	{ "bigresizeup", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_UP | CWM_BIGAMOUNT)} },
+	{ "bigresizedown", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_DOWN | CWM_BIGAMOUNT)} },
+	{ "bigresizeright", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} },
+	{ "bigresizeleft", kbfunc_client_resize, CWM_CONTEXT_CLIENT,
+	    {.i = (CWM_LEFT | CWM_BIGAMOUNT)} },
+	{ "ptrmoveup", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_UP)} },
+	{ "ptrmovedown", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_DOWN)} },
+	{ "ptrmoveleft", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_LEFT)} },
+	{ "ptrmoveright", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_RIGHT)} },
+	{ "bigptrmoveup", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_UP | CWM_BIGAMOUNT)} },
+	{ "bigptrmovedown", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_DOWN | CWM_BIGAMOUNT)} },
+	{ "bigptrmoveleft", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_LEFT | CWM_BIGAMOUNT)} },
+	{ "bigptrmoveright", kbfunc_ptrmove, CWM_CONTEXT_SCREEN,
+	    {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} },
+	{ "htile", kbfunc_client_tile, CWM_CONTEXT_CLIENT,
+	    {.i = CWM_CLIENT_TILE_HORIZ} },
+	{ "vtile", kbfunc_client_tile, CWM_CONTEXT_CLIENT,
+	    {.i = CWM_CLIENT_TILE_VERT} },
+	{ "window_lower", kbfunc_client_lower, CWM_CONTEXT_CLIENT, {0} },
+	{ "window_raise", kbfunc_client_raise, CWM_CONTEXT_CLIENT, {0} },
+	{ "window_hide", kbfunc_client_hide, CWM_CONTEXT_CLIENT, {0} },
+	{ "window_move", mousefunc_client_move, CWM_CONTEXT_CLIENT, {0} },
+	{ "window_resize", mousefunc_client_resize, CWM_CONTEXT_CLIENT, {0} },
+	{ "window_grouptoggle", kbfunc_group_toggle, CWM_CONTEXT_CLIENT,
+	   {.i = CWM_MOUSE} },
+	{ "menu_group", mousefunc_menu_group, CWM_CONTEXT_SCREEN, {0} },
+	{ "menu_unhide", mousefunc_menu_client, CWM_CONTEXT_SCREEN, {0} },
+	{ "menu_cmd", mousefunc_menu_cmd, CWM_CONTEXT_SCREEN, {0} },
 };
 
 static const struct {
@@ -527,14 +549,14 @@ conf_bind_kbd(struct conf *c, const char *bind, const char *cmd)
 			continue;
 
 		kb->callback = name_to_func[i].handler;
-		kb->flags = name_to_func[i].flags;
+		kb->context = name_to_func[i].context;
 		kb->argument = name_to_func[i].argument;
 		TAILQ_INSERT_TAIL(&c->keybindingq, kb, entry);
 		return(1);
 	}
 
-	kb->callback = kbfunc_cmdexec;
-	kb->flags = CWM_CMD;
+	kb->callback = kbfunc_exec;
+	kb->context = CWM_CONTEXT_NONE;
 	kb->argument.c = xstrdup(cmd);
 	TAILQ_INSERT_TAIL(&c->keybindingq, kb, entry);
 	return(1);
@@ -551,7 +573,7 @@ conf_unbind_kbd(struct conf *c, struct binding *unbind)
 
 		if (key->press.keysym == unbind->press.keysym) {
 			TAILQ_REMOVE(&c->keybindingq, key, entry);
-			if (key->flags & CWM_CMD)
+			if (key->context == CWM_CONTEXT_NONE)
 				free(key->argument.c);
 			free(key);
 		}
@@ -588,7 +610,7 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
 			continue;
 
 		mb->callback = name_to_func[i].handler;
-		mb->flags = name_to_func[i].flags;
+		mb->context = name_to_func[i].context;
 		mb->argument = name_to_func[i].argument;
 		TAILQ_INSERT_TAIL(&c->mousebindingq, mb, entry);
 		return(1);
@@ -638,7 +660,7 @@ conf_grab_mouse(Window win)
 	xu_btn_ungrab(win);
 
 	TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) {
-		if (mb->flags & CWM_WIN)
+		if (mb->context == CWM_CONTEXT_CLIENT)
 			xu_btn_grab(win, mb->modmask, mb->press.button);
 	}
 }
diff --git a/group.c b/group.c
index 10130f4..b5c1c34 100644
--- a/group.c
+++ b/group.c
@@ -272,7 +272,7 @@ group_cycle(struct screen_ctx *sc, int flags)
 
 	newgc = oldgc;
 	for (;;) {
-		newgc = (flags & CWM_RCYCLE) ? group_prev(newgc) :
+		newgc = (flags & CWM_CLIENT_RCYCLE) ? group_prev(newgc) :
 		    group_next(newgc);
 
 		if (newgc == oldgc)
diff --git a/kbfunc.c b/kbfunc.c
index 1dfa59f..da647b3 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -38,6 +38,8 @@
 
 extern sig_atomic_t	 cwm_status;
 
+static void kbfunc_amount(int, unsigned int *, unsigned int *);
+
 void
 kbfunc_client_lower(struct client_ctx *cc, union arg *arg)
 {
@@ -51,98 +53,113 @@ kbfunc_client_raise(struct client_ctx *cc, union arg *arg)
 	client_raise(cc);
 }
 
-#define TYPEMASK	(CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE)
-#define MOVEMASK	(CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
-void
-kbfunc_client_moveresize(struct client_ctx *cc, union arg *arg)
+static void
+kbfunc_amount(int flags, unsigned int *mx, unsigned int *my)
 {
-	struct screen_ctx	*sc = cc->sc;
-	struct geom		 area;
-	int			 x, y, flags, amt;
-	unsigned int		 mx, my;
+#define CWM_FACTOR 10
+	int	amt;
 
-	if (cc->flags & CLIENT_FREEZE)
-		return;
-
-	mx = my = 0;
-
-	flags = arg->i;
 	amt = Conf.mamount;
+	if (flags & CWM_BIGAMOUNT)
+		amt *= CWM_FACTOR;
 
-	if (flags & CWM_BIGMOVE) {
-		flags -= CWM_BIGMOVE;
-		amt = amt * 10;
-	}
-
-	switch (flags & MOVEMASK) {
+	switch (flags & DIRECTIONMASK) {
 	case CWM_UP:
-		my -= amt;
+		*my -= amt;
 		break;
 	case CWM_DOWN:
-		my += amt;
+		*my += amt;
 		break;
 	case CWM_RIGHT:
-		mx += amt;
+		*mx += amt;
 		break;
 	case CWM_LEFT:
-		mx -= amt;
-		break;
-	}
-	switch (flags & TYPEMASK) {
-	case CWM_MOVE:
-		cc->geom.x += mx;
-		if (cc->geom.x + cc->geom.w < 0)
-			cc->geom.x = -cc->geom.w;
-		if (cc->geom.x > sc->view.w - 1)
-			cc->geom.x = sc->view.w - 1;
-		cc->geom.y += my;
-		if (cc->geom.y + cc->geom.h < 0)
-			cc->geom.y = -cc->geom.h;
-		if (cc->geom.y > sc->view.h - 1)
-			cc->geom.y = sc->view.h - 1;
-
-		area = screen_area(sc,
-		    cc->geom.x + cc->geom.w / 2,
-		    cc->geom.y + cc->geom.h / 2, CWM_GAP);
-		cc->geom.x += client_snapcalc(cc->geom.x,
-		    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
-		    area.x, area.x + area.w, sc->snapdist);
-		cc->geom.y += client_snapcalc(cc->geom.y,
-		    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
-		    area.y, area.y + area.h, sc->snapdist);
-
-		client_move(cc);
-		xu_ptr_getpos(cc->win, &x, &y);
-		cc->ptr.x = x + mx;
-		cc->ptr.y = y + my;
-		client_ptrwarp(cc);
-		break;
-	case CWM_RESIZE:
-		if ((cc->geom.w += mx) < 1)
-			cc->geom.w = 1;
-		if ((cc->geom.h += my) < 1)
-			cc->geom.h = 1;
-		client_resize(cc, 1);
-
-		/* Make sure the pointer stays within the window. */
-		xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
-		if (cc->ptr.x > cc->geom.w)
-			cc->ptr.x = cc->geom.w - cc->bwidth;
-		if (cc->ptr.y > cc->geom.h)
-			cc->ptr.y = cc->geom.h - cc->bwidth;
-		client_ptrwarp(cc);
-		break;
-	case CWM_PTRMOVE:
-		xu_ptr_getpos(sc->rootwin, &x, &y);
-		xu_ptr_setpos(sc->rootwin, x + mx, y + my);
+		*mx -= amt;
 		break;
-	default:
-		warnx("invalid flags passed to kbfunc_client_moveresize");
 	}
 }
 
 void
-kbfunc_client_search(struct client_ctx *cc, union arg *arg)
+kbfunc_ptrmove(struct client_ctx *cc, union arg *arg)
+{
+	struct screen_ctx	*sc = cc->sc;
+	int			 x, y;
+	unsigned int		 mx = 0, my = 0;
+
+	kbfunc_amount(arg->i, &mx, &my);
+
+	xu_ptr_getpos(sc->rootwin, &x, &y);
+	xu_ptr_setpos(sc->rootwin, x + mx, y + my);
+}
+
+void
+kbfunc_client_move(struct client_ctx *cc, union arg *arg)
+{
+	struct screen_ctx	*sc = cc->sc;
+	struct geom		 area;
+	int			 x, y;
+	unsigned int		 mx = 0, my = 0;
+
+	if (cc->flags & CLIENT_FREEZE)
+		return;
+
+	kbfunc_amount(arg->i, &mx, &my);
+
+	cc->geom.x += mx;
+	if (cc->geom.x + cc->geom.w < 0)
+		cc->geom.x = -cc->geom.w;
+	if (cc->geom.x > sc->view.w - 1)
+		cc->geom.x = sc->view.w - 1;
+	cc->geom.y += my;
+	if (cc->geom.y + cc->geom.h < 0)
+		cc->geom.y = -cc->geom.h;
+	if (cc->geom.y > sc->view.h - 1)
+		cc->geom.y = sc->view.h - 1;
+
+	area = screen_area(sc,
+	    cc->geom.x + cc->geom.w / 2,
+	    cc->geom.y + cc->geom.h / 2, CWM_GAP);
+	cc->geom.x += client_snapcalc(cc->geom.x,
+	    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
+	    area.x, area.x + area.w, sc->snapdist);
+	cc->geom.y += client_snapcalc(cc->geom.y,
+	    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
+	    area.y, area.y + area.h, sc->snapdist);
+	client_move(cc);
+
+	xu_ptr_getpos(cc->win, &x, &y);
+	cc->ptr.x = x + mx;
+	cc->ptr.y = y + my;
+	client_ptrwarp(cc);
+}
+
+void
+kbfunc_client_resize(struct client_ctx *cc, union arg *arg)
+{
+	unsigned int		 mx = 0, my = 0;
+
+	if (cc->flags & CLIENT_FREEZE)
+		return;
+
+	kbfunc_amount(arg->i, &mx, &my);
+
+	if ((cc->geom.w += mx * cc->hint.incw) < cc->hint.minw)
+		cc->geom.w = cc->hint.minw;
+	if ((cc->geom.h += my * cc->hint.inch) < cc->hint.minh)
+		cc->geom.h = cc->hint.minh;
+	client_resize(cc, 1);
+
+	/* Make sure the pointer stays within the window. */
+	xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
+	if (cc->ptr.x > cc->geom.w)
+		cc->ptr.x = cc->geom.w - cc->bwidth;
+	if (cc->ptr.y > cc->geom.h)
+		cc->ptr.y = cc->geom.h - cc->bwidth;
+	client_ptrwarp(cc);
+}
+
+void
+kbfunc_menu_client(struct client_ctx *cc, union arg *arg)
 {
 	struct screen_ctx	*sc = cc->sc;
 	struct client_ctx	*old_cc;
@@ -230,13 +247,13 @@ kbfunc_client_hide(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_cmdexec(struct client_ctx *cc, union arg *arg)
+kbfunc_exec(struct client_ctx *cc, union arg *arg)
 {
 	u_spawn(arg->c);
 }
 
 void
-kbfunc_term(struct client_ctx *cc, union arg *arg)
+kbfunc_exec_term(struct client_ctx *cc, union arg *arg)
 {
 	struct cmd *cmd;
 
@@ -247,7 +264,7 @@ kbfunc_term(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_lock(struct client_ctx *cc, union arg *arg)
+kbfunc_exec_lock(struct client_ctx *cc, union arg *arg)
 {
 	struct cmd *cmd;
 
@@ -258,7 +275,7 @@ kbfunc_lock(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_exec(struct client_ctx *cc, union arg *arg)
+kbfunc_menu_exec(struct client_ctx *cc, union arg *arg)
 {
 #define NPATHS 256
 	struct screen_ctx	*sc = cc->sc;
@@ -273,14 +290,14 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
 	struct stat		 sb;
 
 	switch (cmd) {
-	case CWM_EXEC_PROGRAM:
+	case CWM_MENU_EXEC:
 		label = "exec";
 		break;
-	case CWM_EXEC_WM:
+	case CWM_MENU_EXEC_WM:
 		label = "wm";
 		break;
 	default:
-		errx(1, "kbfunc_exec: invalid cmd %d", cmd);
+		errx(1, "kbfunc_menu_exec: invalid cmd %d", cmd);
 		/*NOTREACHED*/
 	}
 
@@ -327,11 +344,11 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
 		if (mi->text[0] == '\0')
 			goto out;
 		switch (cmd) {
-		case CWM_EXEC_PROGRAM:
+		case CWM_MENU_EXEC:
 			u_spawn(mi->text);
 			break;
-		case CWM_EXEC_WM:
-			cwm_status = CWM_EXECWM;
+		case CWM_MENU_EXEC_WM:
+			cwm_status = CWM_EXEC_WM;
 			free(wm_argv);
 			wm_argv = xstrdup(mi->text);
 			break;
@@ -347,7 +364,7 @@ out:
 }
 
 void
-kbfunc_ssh(struct client_ctx *cc, union arg *arg)
+kbfunc_menu_ssh(struct client_ctx *cc, union arg *arg)
 {
 	struct screen_ctx	*sc = cc->sc;
 	struct cmd		*cmd;
@@ -367,7 +384,7 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
 	TAILQ_INIT(&menuq);
 
 	if ((fp = fopen(Conf.known_hosts, "r")) == NULL) {
-		warn("kbfunc_ssh: %s", Conf.known_hosts);
+		warn("kbfunc_menu_ssh: %s", Conf.known_hosts);
 		goto menu;
 	}
 
@@ -439,25 +456,25 @@ kbfunc_client_delete(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_client_group(struct client_ctx *cc, union arg *arg)
+kbfunc_group_toggle(struct client_ctx *cc, union arg *arg)
 {
 	group_hidetoggle(cc->sc, arg->i);
 }
 
 void
-kbfunc_client_grouponly(struct client_ctx *cc, union arg *arg)
+kbfunc_group_only(struct client_ctx *cc, union arg *arg)
 {
 	group_only(cc->sc, arg->i);
 }
 
 void
-kbfunc_client_cyclegroup(struct client_ctx *cc, union arg *arg)
+kbfunc_group_cycle(struct client_ctx *cc, union arg *arg)
 {
 	group_cycle(cc->sc, arg->i);
 }
 
 void
-kbfunc_client_nogroup(struct client_ctx *cc, union arg *arg)
+kbfunc_group_alltoggle(struct client_ctx *cc, union arg *arg)
 {
 	group_alltoggle(cc->sc);
 }
@@ -465,7 +482,7 @@ kbfunc_client_nogroup(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
 {
-	if (arg->i == 0) {
+	if (arg->i == CWM_KBD) {
 		/* For X apps that steal events. */
 		XGrabKeyboard(X_Dpy, cc->win, True,
 		    GrabModeAsync, GrabModeAsync, CurrentTime);
@@ -523,13 +540,13 @@ kbfunc_cwm_status(struct client_ctx *cc, union arg *arg)
 }
 
 void
-kbfunc_tile(struct client_ctx *cc, union arg *arg)
+kbfunc_client_tile(struct client_ctx *cc, union arg *arg)
 {
 	switch (arg->i) {
-	case CWM_TILE_HORIZ:
+	case CWM_CLIENT_TILE_HORIZ:
 		client_htile(cc);
 		break;
-	case CWM_TILE_VERT:
+	case CWM_CLIENT_TILE_VERT:
 		client_vtile(cc);
 		break;
 	}
diff --git a/mousefunc.c b/mousefunc.c
index e38de9a..d0011cd 100644
--- a/mousefunc.c
+++ b/mousefunc.c
@@ -196,7 +196,7 @@ mousefunc_menu_group(struct client_ctx *cc, union arg *arg)
 }
 
 void
-mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg)
+mousefunc_menu_client(struct client_ctx *cc, union arg *arg)
 {
 	struct screen_ctx	*sc = cc->sc;
 	struct client_ctx	*old_cc;
diff --git a/screen.c b/screen.c
index c51082b..37bb292 100644
--- a/screen.c
+++ b/screen.c
@@ -124,6 +124,20 @@ screen_updatestackingorder(struct screen_ctx *sc)
 	}
 }
 
+struct region_ctx *
+region_find(struct screen_ctx *sc, int x, int y)
+{
+	struct region_ctx	*rc;
+
+	TAILQ_FOREACH(rc, &sc->regionq, entry) {
+		if ((x >= rc->view.x) && (x < (rc->view.x + rc->view.w)) &&
+		    (y >= rc->view.y) && (y < (rc->view.y + rc->view.h))) {
+			break;
+		}
+	}
+	return(rc);
+}
+
 struct geom
 screen_area(struct screen_ctx *sc, int x, int y, int flags)
 {
@@ -146,13 +160,11 @@ void
 screen_update_geometry(struct screen_ctx *sc)
 {
 	struct region_ctx	*rc;
-	int			 i;
 
 	sc->view.x = 0;
 	sc->view.y = 0;
 	sc->view.w = DisplayWidth(X_Dpy, sc->which);
 	sc->view.h = DisplayHeight(X_Dpy, sc->which);
-
 	sc->work = screen_apply_gap(sc, sc->view);
 
 	while ((rc = TAILQ_FIRST(&sc->regionq)) != NULL) {
@@ -163,6 +175,7 @@ screen_update_geometry(struct screen_ctx *sc)
 	if (HasRandr) {
 		XRRScreenResources *sr;
 		XRRCrtcInfo *ci;
+		int i;
 
 		sr = XRRGetScreenResources(X_Dpy, sc->rootwin);
 		for (i = 0, ci = NULL; i < sr->ncrtc; i++) {
@@ -180,11 +193,25 @@ screen_update_geometry(struct screen_ctx *sc)
 			rc->area.y = ci->y;
 			rc->area.w = ci->width;
 			rc->area.h = ci->height;
+			rc->view.x = ci->x;
+			rc->view.y = ci->y;
+			rc->view.w = ci->width;
+			rc->view.h = ci->height;
+			rc->work = screen_apply_gap(sc, rc->view);
 			TAILQ_INSERT_TAIL(&sc->regionq, rc, entry);
 
 			XRRFreeCrtcInfo(ci);
 		}
 		XRRFreeScreenResources(sr);
+	} else {
+		rc = xmalloc(sizeof(*rc));
+		rc->num = 0;
+		rc->view.x = 0;
+		rc->view.y = 0;
+		rc->view.w = DisplayWidth(X_Dpy, sc->which);
+		rc->view.h = DisplayHeight(X_Dpy, sc->which);
+		rc->work = screen_apply_gap(sc, rc->view);
+		TAILQ_INSERT_TAIL(&sc->regionq, rc, entry);
 	}
 
 	xu_ewmh_net_desktop_geometry(sc);
diff --git a/xevents.c b/xevents.c
index 8cea6a5..7fe0c43 100644
--- a/xevents.c
+++ b/xevents.c
@@ -232,7 +232,7 @@ xev_handle_buttonpress(XEvent *ee)
 
 	if (mb == NULL)
 		return;
-	if (mb->flags & CWM_WIN) {
+	if (mb->context == CWM_CONTEXT_CLIENT) {
 		if (((cc = client_find(e->window)) == NULL) &&
 		    (cc = client_current()) == NULL)
 			return;
@@ -285,7 +285,7 @@ xev_handle_keypress(XEvent *ee)
 
 	if (kb == NULL)
 		return;
-	if (kb->flags & CWM_WIN) {
+	if (kb->context == CWM_CONTEXT_CLIENT) {
 		if (((cc = client_find(e->window)) == NULL) &&
 		    (cc = client_current()) == NULL)
 			return;