summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2015-11-12 21:28:03 +0000
committerokan <okan>2015-11-12 21:28:03 +0000
commit4e51ce57a7b773f66304072f7c369f58e0a62159 (patch)
tree9ad7cbe078aac6879cba972d04d1781025b8b5b3
parentcd21e166754c24e9bbcde1ee3a689079a073cc5b (diff)
parent323672ace778a61f6f51032453f781d50701e349 (diff)
downloadcwm-4e51ce57a7b773f66304072f7c369f58e0a62159.tar.gz
cwm-4e51ce57a7b773f66304072f7c369f58e0a62159.tar.xz
cwm-4e51ce57a7b773f66304072f7c369f58e0a62159.zip
cvsimport
* refs/heads/master:
  more client vs screen context differences
  If a client sets hints, honor them for kb resize requests, just like we do for mouse based resize requests.
  Move kb pointer movement out of the kbfunc_client_moveresize since it's got nothing to do with clients, thus doing flags work causes lots of waste and almost useless jumpy pointer movements; while here, split out move and resize since they share almost no code, just like mouse client move/resize; factor out amount and factor. Still wonder why this is here, but it works now.
  pledge "stdio rpath proc exec" cwm before main event loop, after init/setup - mostly for menu building.
  Partial revert of replacing screen_area() with region_find(); until a fix for a regression is found; this bug has been around for a long time it seems, but this change exposed it. Likely need to track clients in to and out of regions.
  Use position on root to figure out region.
  Start cleaning up name vs function differences; replace magic numbers.
  Clean up unused defines.
  Extend region to include both view and work areas; switch to region_find() which no longer needs to recalculate gap each time a client (or menu) is created or altered. If no RandR, fall back to display dimensions while building regions instead of during execution.
-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;