about summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2013-01-06 01:01:26 +0000
committerokan <okan>2013-01-06 01:01:26 +0000
commit104c7d5de3a92da8b0c3514ef0692ff1e5d0ef82 (patch)
tree4e3ce464112ff297402c202eee26cc2fdaa87dfa
parentf77166194f4586cb19abcb7951ca05e356ac74e1 (diff)
parentc426254da5ff69102284524ddc560cfb00c73204 (diff)
downloadcwm-104c7d5de3a92da8b0c3514ef0692ff1e5d0ef82.tar.gz
cwm-104c7d5de3a92da8b0c3514ef0692ff1e5d0ef82.tar.xz
cwm-104c7d5de3a92da8b0c3514ef0692ff1e5d0ef82.zip
cvsimport
-rw-r--r--calmwm.h26
-rw-r--r--client.c133
-rw-r--r--conf.c34
-rw-r--r--group.c16
-rw-r--r--kbfunc.c18
-rw-r--r--menu.c35
-rw-r--r--mousefunc.c8
-rw-r--r--parse.y20
-rw-r--r--screen.c50
-rw-r--r--xutil.c2
10 files changed, 140 insertions, 202 deletions
diff --git a/calmwm.h b/calmwm.h
index cf63a64..bbc96b2 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -86,8 +86,8 @@ size_t strlcat(char *, const char *, size_t);
 #define CWM_MENU_DUMMY		0x0001
 #define CWM_MENU_FILE		0x0002
 
-#define KBTOGROUP(X) ((X) - 1)
-
+#define ARG_CHAR		0x0001
+#define ARG_INT			0x0002
 union arg {
 	char	*c;
 	int	 i;
@@ -101,17 +101,12 @@ enum menucolor {
 	CWM_COLOR_MENU_MAX
 };
 
-enum cwmcolor {
+enum bordercolor {
 	CWM_COLOR_BORDER_ACTIVE,
 	CWM_COLOR_BORDER_INACTIVE,
 	CWM_COLOR_BORDER_GROUP,
 	CWM_COLOR_BORDER_UNGROUP,
-	CWM_COLOR_MAX
-};
-
-struct color {
-	char		*name;
-	unsigned long	 pixel;
+	CWM_COLOR_BORDER_MAX
 };
 
 struct geom {
@@ -223,7 +218,7 @@ struct screen_ctx {
 	Colormap		 colormap;
 	Window			 rootwin;
 	Window			 menuwin;
-	struct color		 color[CWM_COLOR_MAX];
+	unsigned long		 color[CWM_COLOR_BORDER_MAX];
 	int			 cycling;
 	struct geom		 view; /* viewable area */
 	struct geom		 work; /* workable area, gap-applied */
@@ -234,7 +229,7 @@ struct screen_ctx {
 	XftFont			*xftfont;
 	int			 xinerama_no;
 	XineramaScreenInfo	*xinerama;
-#define CALMWM_NGROUPS		 9
+#define CALMWM_NGROUPS		 10
 	struct group_ctx	 groups[CALMWM_NGROUPS];
 	struct group_ctx_q	 groupq;
 	int			 group_hideall;
@@ -253,6 +248,7 @@ struct keybinding {
 	int			 keycode;
 #define KBFLAG_NEEDCLIENT	 0x0001
 	int			 flags;
+	int			 argtype;
 };
 TAILQ_HEAD(keybinding_q, keybinding);
 
@@ -302,7 +298,7 @@ struct conf {
 #define	CONF_SNAPDIST			0
 	int			 snapdist;
 	struct gap		 gap;
-	struct color		 color[CWM_COLOR_MAX];
+	char			*color[CWM_COLOR_BORDER_MAX];
 	char		 	*menucolor[CWM_COLOR_MENU_MAX];
 	char			 termpath[MAXPATHLEN];
 	char			 lockpath[MAXPATHLEN];
@@ -336,7 +332,7 @@ struct client_ctx	*client_find(Window);
 void			 client_freeze(struct client_ctx *);
 void			 client_getsizehints(struct client_ctx *);
 void			 client_hide(struct client_ctx *);
-void			 client_horizmaximize(struct client_ctx *);
+void			 client_hmaximize(struct client_ctx *);
 void			 client_leave(struct client_ctx *);
 void			 client_lower(struct client_ctx *);
 void			 client_map(struct client_ctx *);
@@ -353,7 +349,7 @@ void			 client_setname(struct client_ctx *);
 int			 client_snapcalc(int, int, int, int, int);
 void			 client_transient(struct client_ctx *);
 void			 client_unhide(struct client_ctx *);
-void			 client_vertmaximize(struct client_ctx *);
+void			 client_vmaximize(struct client_ctx *);
 void			 client_warp(struct client_ctx *);
 
 void			 group_alltoggle(struct screen_ctx *);
@@ -383,7 +379,7 @@ void			 search_match_text(struct menu_q *, struct menu_q *,
 			     char *);
 void			 search_print_client(struct menu *, int);
 
-XineramaScreenInfo	*screen_find_xinerama(struct screen_ctx *, int, int);
+struct geom		 screen_find_xinerama(struct screen_ctx *, int, int);
 struct screen_ctx	*screen_fromroot(Window);
 void			 screen_init(struct screen_ctx *, u_int);
 void			 screen_update_geometry(struct screen_ctx *);
diff --git a/client.c b/client.c
index 2394d2d..a72ecfb 100644
--- a/client.c
+++ b/client.c
@@ -41,7 +41,6 @@ static void			 client_gethints(struct client_ctx *);
 static void			 client_freehints(struct client_ctx *);
 static int			 client_inbound(struct client_ctx *, int, int);
 
-static char		 emptystring[] = "";
 struct client_ctx	*_curcc = NULL;
 
 struct client_ctx *
@@ -166,8 +165,7 @@ client_delete(struct client_ctx *cc)
 
 	while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
 		TAILQ_REMOVE(&cc->nameq, wn, entry);
-		if (wn->name != emptystring)
-			free(wn->name);
+		free(wn->name);
 		free(wn);
 	}
 
@@ -257,8 +255,7 @@ void
 client_maximize(struct client_ctx *cc)
 {
 	struct screen_ctx	*sc = cc->sc;
-	int			 x_org, y_org, xmax, ymax;
-	XineramaScreenInfo	*xine;
+	struct geom		 xine;
 
 	if (cc->flags & CLIENT_FREEZE)
 		return;
@@ -288,21 +285,11 @@ client_maximize(struct client_ctx *cc)
 	xine = screen_find_xinerama(sc,
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
-	if (xine) {
-		x_org = xine->x_org;
-		y_org = xine->y_org;
-		xmax = xine->width;
-		ymax = xine->height;
-	} else {
-		x_org = y_org = 0;
-		xmax = sc->view.w;
-		ymax = sc->view.h;
-	}
 
-	cc->geom.x = x_org + sc->gap.left;
-	cc->geom.y = y_org + sc->gap.top;
-	cc->geom.h = ymax - (sc->gap.top + sc->gap.bottom);
-	cc->geom.w = xmax - (sc->gap.left + sc->gap.right);
+	cc->geom.x = xine.x + sc->gap.left;
+	cc->geom.y = xine.y + sc->gap.top;
+	cc->geom.h = xine.h - (sc->gap.top + sc->gap.bottom);
+	cc->geom.w = xine.w - (sc->gap.left + sc->gap.right);
 	cc->bwidth = 0;
 	cc->flags |= CLIENT_MAXIMIZED;
 
@@ -311,11 +298,10 @@ resize:
 }
 
 void
-client_vertmaximize(struct client_ctx *cc)
+client_vmaximize(struct client_ctx *cc)
 {
 	struct screen_ctx	*sc = cc->sc;
-	int			 y_org, ymax;
-	XineramaScreenInfo	*xine;
+	struct geom		 xine;
 
 	if (cc->flags & CLIENT_FREEZE)
 		return;
@@ -335,23 +321,16 @@ client_vertmaximize(struct client_ctx *cc)
 
 	/* if this will make us fully maximized then remove boundary */
 	if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) {
-		cc->geom.w += Conf.bwidth * 2;
+		cc->geom.w += cc->bwidth * 2;
 		cc->bwidth = 0;
 	}
 
 	xine = screen_find_xinerama(sc,
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
-	if (xine) {
-		y_org = xine->y_org;
-		ymax = xine->height;
-	} else {
-		y_org = 0;
-		ymax = sc->view.h;
-	}
 
-	cc->geom.y = y_org + sc->gap.top;
-	cc->geom.h = ymax - (cc->bwidth * 2) - (sc->gap.top +
+	cc->geom.y = xine.y + sc->gap.top;
+	cc->geom.h = xine.h - (cc->bwidth * 2) - (sc->gap.top +
 	    sc->gap.bottom);
 	cc->flags |= CLIENT_VMAXIMIZED;
 
@@ -360,11 +339,10 @@ resize:
 }
 
 void
-client_horizmaximize(struct client_ctx *cc)
+client_hmaximize(struct client_ctx *cc)
 {
 	struct screen_ctx	*sc = cc->sc;
-	int			 x_org, xmax;
-	XineramaScreenInfo	*xine;
+	struct geom		 xine;
 
 	if (cc->flags & CLIENT_FREEZE)
 		return;
@@ -391,16 +369,9 @@ client_horizmaximize(struct client_ctx *cc)
 	xine = screen_find_xinerama(sc,
 	    cc->geom.x + cc->geom.w / 2,
 	    cc->geom.y + cc->geom.h / 2);
-	if (xine) {
-		x_org = xine->x_org;
-		xmax = xine->width;
-	} else {
-		x_org = 0;
-		xmax = sc->view.w;
-	}
 
-	cc->geom.x = x_org + sc->gap.left;
-	cc->geom.w = xmax - (cc->bwidth * 2) - (sc->gap.left +
+	cc->geom.x = xine.x + sc->gap.left;
+	cc->geom.w = xine.w - (cc->bwidth * 2) - (sc->gap.left +
 	    sc->gap.right);
 	cc->flags |= CLIENT_HMAXIMIZED;
 
@@ -504,17 +475,17 @@ client_draw_border(struct client_ctx *cc)
 	if (cc->active)
 		switch (cc->flags & CLIENT_HIGHLIGHT) {
 		case CLIENT_GROUP:
-			pixel = sc->color[CWM_COLOR_BORDER_GROUP].pixel;
+			pixel = sc->color[CWM_COLOR_BORDER_GROUP];
 			break;
 		case CLIENT_UNGROUP:
-			pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel;
+			pixel = sc->color[CWM_COLOR_BORDER_UNGROUP];
 			break;
 		default:
-			pixel = sc->color[CWM_COLOR_BORDER_ACTIVE].pixel;
+			pixel = sc->color[CWM_COLOR_BORDER_ACTIVE];
 			break;
 		}
 	else
-		pixel = sc->color[CWM_COLOR_BORDER_INACTIVE].pixel;
+		pixel = sc->color[CWM_COLOR_BORDER_INACTIVE];
 
 	XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth);
 	XSetWindowBorder(X_Dpy, cc->win, pixel);
@@ -558,7 +529,7 @@ client_setname(struct client_ctx *cc)
 
 	if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME].atom, &newname))
 		if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname))
-			newname = emptystring;
+			newname = xstrdup("");
 
 	TAILQ_FOREACH(wn, &cc->nameq, entry)
 		if (strcmp(wn->name, newname) == 0) {
@@ -581,8 +552,7 @@ match:
 		wn = TAILQ_FIRST(&cc->nameq);
 		assert(wn != NULL);
 		TAILQ_REMOVE(&cc->nameq, wn, entry);
-		if (wn->name != emptystring)
-			free(wn->name);
+		free(wn->name);
 		free(wn);
 		cc->nameqlen--;
 	}
@@ -685,48 +655,37 @@ client_placecalc(struct client_ctx *cc)
 		if (cc->size->y > 0)
 			cc->geom.y = MIN(cc->size->y, yslack);
 	} else {
-		XineramaScreenInfo	*info;
-		int			 xmouse, ymouse, xorig, yorig;
-		int			 xmax, ymax;
+		struct geom		 xine;
+		int			 xmouse, ymouse;
 
 		xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
-		info = screen_find_xinerama(sc, xmouse, ymouse);
-		if (info) {
-			xorig = info->x_org;
-			yorig = info->y_org;
-			xmax = xorig + info->width;
-			ymax = yorig + info->height;
-		} else {
-			xorig = yorig = 0;
-			xmax = sc->view.w;
-			ymax = sc->view.h;
-		}
-		xmouse = MAX(xmouse, xorig) - cc->geom.w / 2;
-		ymouse = MAX(ymouse, yorig) - cc->geom.h / 2;
+		xine = screen_find_xinerama(sc, xmouse, ymouse);
+		xmouse = MAX(xmouse, xine.x) - cc->geom.w / 2;
+		ymouse = MAX(ymouse, xine.y) - cc->geom.h / 2;
 
-		xmouse = MAX(xmouse, xorig);
-		ymouse = MAX(ymouse, yorig);
+		xmouse = MAX(xmouse, xine.x);
+		ymouse = MAX(ymouse, xine.y);
 
-		xslack = xmax - cc->geom.w - cc->bwidth * 2;
-		yslack = ymax - cc->geom.h - cc->bwidth * 2;
+		xslack = xine.w - cc->geom.w - cc->bwidth * 2;
+		yslack = xine.h - cc->geom.h - cc->bwidth * 2;
 
-		if (xslack >= xorig) {
+		if (xslack >= xine.x) {
 			cc->geom.x = MAX(MIN(xmouse, xslack),
-			    xorig + sc->gap.left);
+			    xine.x + sc->gap.left);
 			if (cc->geom.x > (xslack - sc->gap.right))
 				cc->geom.x -= sc->gap.right;
 		} else {
-			cc->geom.x = xorig + sc->gap.left;
-			cc->geom.w = xmax - sc->gap.left;
+			cc->geom.x = xine.x + sc->gap.left;
+			cc->geom.w = xine.w - sc->gap.left;
 		}
-		if (yslack >= yorig) {
+		if (yslack >= xine.y) {
 			cc->geom.y = MAX(MIN(ymouse, yslack),
-			    yorig + sc->gap.top);
+			    xine.y + sc->gap.top);
 			if (cc->geom.y > (yslack - sc->gap.bottom))
 				cc->geom.y -= sc->gap.bottom;
 		} else {
-			cc->geom.y = yorig + sc->gap.top;
-			cc->geom.h = ymax - sc->gap.top;
+			cc->geom.y = xine.y + sc->gap.top;
+			cc->geom.h = xine.h - sc->gap.top;
 		}
 	}
 }
@@ -876,7 +835,7 @@ client_transient(struct client_ctx *cc)
 
 	if (XGetTransientForHint(X_Dpy, cc->win, &trans)) {
 		if ((tc = client_find(trans)) && tc->group) {
-			group_movetogroup(cc, tc->group->shortcut - 1);
+			group_movetogroup(cc, tc->group->shortcut);
 			if (tc->flags & CLIENT_IGNORE)
 				cc->flags |= CLIENT_IGNORE;
 		}
@@ -891,19 +850,17 @@ client_inbound(struct client_ctx *cc, int x, int y)
 }
 
 int
-client_snapcalc(int n, int dn, int nmax, int bwidth, int snapdist)
+client_snapcalc(int n0, int n1, int e0, int e1, int snapdist)
 {
-	int	 n0, n1, s0, s1;
+	int	 s0, s1;
 
 	s0 = s1 = 0;
-	n0 = n;
-	n1 = n + dn + (bwidth * 2);
 
-	if (abs(n0) <= snapdist)
-		s0 = -n0;
+	if (abs(e0 - n0) <= snapdist)
+		s0 = e0 - n0;
 
-	if (nmax - snapdist <= n1 && n1 <= nmax + snapdist)
-		s1 = nmax - n1;
+	if (abs(e1 - n1) <= snapdist)
+		s1 = e1 - n1;
 
 	/* possible to snap in both directions */
 	if (s0 != 0 && s1 != 0)
diff --git a/conf.c b/conf.c
index 88c5fd9..17c10b9 100644
--- a/conf.c
+++ b/conf.c
@@ -65,17 +65,17 @@ conf_font(struct conf *c, struct screen_ctx *sc)
 }
 
 static char *menu_color_binds[CWM_COLOR_MENU_MAX] = {
-	"black", /* CWM_COLOR_MENU_FG */
-	"white", /* CWM_COLOR_MENU_BG */
-	"black", /* CWM_COLOR_MENU_FONT */
-	"",  	 /* CWM_COLOR_MENU_FONT_SEL */
+	"black",	/* CWM_COLOR_MENU_FG */
+	"white",	/* CWM_COLOR_MENU_BG */
+	"black",	/* CWM_COLOR_MENU_FONT */
+	"",		/* CWM_COLOR_MENU_FONT_SEL */
 };
 
-static struct color color_binds[CWM_COLOR_MAX] = {
-	{ "#CCCCCC",	0 }, /* CWM_COLOR_BORDER_ACTIVE */
-	{ "#666666",	0 }, /* CWM_COLOR_BORDER_INACTIVE */
-	{ "blue",	0 }, /* CWM_COLOR_BORDER_GROUP */
-	{ "red",	0 }, /* CWM_COLOR_BORDER_UNGROUP */
+static char *color_binds[CWM_COLOR_BORDER_MAX] = {
+	"#CCCCCC",	/* CWM_COLOR_BORDER_ACTIVE */
+	"#666666",	/* CWM_COLOR_BORDER_INACTIVE */
+	"blue",		/* CWM_COLOR_BORDER_GROUP */
+	"red",		/* CWM_COLOR_BORDER_UNGROUP */
 };
 
 void
@@ -83,8 +83,8 @@ conf_color(struct conf *c, struct screen_ctx *sc)
 {
 	int	 i;
 
-	for (i = 0; i < CWM_COLOR_MAX; i++)
-		sc->color[i].pixel = xu_getcolor(sc, c->color[i].name);
+	for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
+		sc->color[i] = xu_getcolor(sc, c->color[i]);
 }
 
 static struct {
@@ -184,7 +184,7 @@ conf_init(struct conf *c)
 		conf_mousebind(c, m_binds[i].key, m_binds[i].func);
 
 	for (i = 0; i < nitems(color_binds); i++)
-		c->color[i].name = xstrdup(color_binds[i].name);
+		c->color[i] = xstrdup(color_binds[i]);
 
 	for (i = 0; i < nitems(menu_color_binds); i++)
 		c->menucolor[i] = xstrdup(menu_color_binds[i]);
@@ -236,8 +236,8 @@ conf_clear(struct conf *c)
 		free(mb);
 	}
 
-	for (i = 0; i < CWM_COLOR_MAX; i++)
-		free(c->color[i].name);
+	for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
+		free(c->color[i]);
 
 	free(c->font);
 }
@@ -470,14 +470,16 @@ conf_bindname(struct conf *c, char *name, char *binding)
 		current_binding->callback = name_to_kbfunc[i].handler;
 		current_binding->flags = name_to_kbfunc[i].flags;
 		current_binding->argument = name_to_kbfunc[i].argument;
+		current_binding->argtype |= ARG_INT;
 		conf_grab(c, current_binding);
 		TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
 		return;
 	}
 
 	current_binding->callback = kbfunc_cmdexec;
-	current_binding->argument.c = xstrdup(binding);
 	current_binding->flags = 0;
+	current_binding->argument.c = xstrdup(binding);
+	current_binding->argtype |= ARG_CHAR;
 	conf_grab(c, current_binding);
 	TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
 }
@@ -496,6 +498,8 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
 		    key->keysym == unbind->keysym) {
 			conf_ungrab(c, key);
 			TAILQ_REMOVE(&c->keybindingq, key, entry);
+			if (key->argtype & ARG_CHAR)
+				free(key->argument.c);
 			free(key);
 		}
 	}
diff --git a/group.c b/group.c
index ab72eef..8b8823c 100644
--- a/group.c
+++ b/group.c
@@ -132,7 +132,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc)
 	free(winlist);
 
 	gc->hidden = 0;
-	group_setactive(sc, gc->shortcut - 1);
+	group_setactive(sc, gc->shortcut);
 }
 
 void
@@ -151,7 +151,7 @@ group_init(struct screen_ctx *sc)
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
 		TAILQ_INIT(&sc->groups[i].clients);
 		sc->groups[i].hidden = 0;
-		sc->groups[i].shortcut = i + 1;
+		sc->groups[i].shortcut = i;
 		TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
 	}
 
@@ -269,12 +269,8 @@ group_hidetoggle(struct screen_ctx *sc, int idx)
 
 	if (gc->hidden)
 		group_show(sc, gc);
-	else {
+	else
 		group_hide(sc, gc);
-		/* XXX wtf? */
-		if (TAILQ_EMPTY(&gc->clients))
-			group_setactive(sc, idx);
-	}
 }
 
 void
@@ -327,7 +323,7 @@ group_cycle(struct screen_ctx *sc, int flags)
 	if (showgroup->hidden)
 		group_show(sc, showgroup);
 	else
-		group_setactive(sc, showgroup->shortcut - 1);
+		group_setactive(sc, showgroup->shortcut);
 }
 
 /* called when a client is deleted */
@@ -420,7 +416,7 @@ group_autogroup(struct client_ctx *cc)
 		else if (*grpno > CALMWM_NGROUPS || *grpno < 0)
 			no = CALMWM_NGROUPS - 1;
 		else
-			no = *grpno + 1;
+			no = *grpno;
 		XFree(grpno);
 	} else {
 		TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
@@ -480,7 +476,7 @@ group_update_names(struct screen_ctx *sc)
 	 */
 	if (n < CALMWM_NGROUPS) {
 		setnames = 1;
-		i = 1;
+		i = 0;
 		while (n < CALMWM_NGROUPS)
 			strings[n++] = xstrdup(shortcut_to_name[i++]);
 	}
diff --git a/kbfunc.c b/kbfunc.c
index d574878..eda9a39 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -101,11 +101,11 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
 			cc->geom.x = sc->view.w - 1;
 
 		cc->geom.x += client_snapcalc(cc->geom.x,
-		    cc->geom.w, sc->view.w,
-		    cc->bwidth, Conf.snapdist);
+		    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
+		    sc->work.x, sc->work.w, Conf.snapdist);
 		cc->geom.y += client_snapcalc(cc->geom.y,
-		    cc->geom.h, sc->view.h,
-		    cc->bwidth, Conf.snapdist);
+		    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
+		    sc->work.y, sc->work.h, Conf.snapdist);
 
 		client_move(cc);
 		xu_ptr_getpos(cc->win, &x, &y);
@@ -406,13 +406,13 @@ kbfunc_client_delete(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_group(struct client_ctx *cc, union arg *arg)
 {
-	group_hidetoggle(cc->sc, KBTOGROUP(arg->i));
+	group_hidetoggle(cc->sc, arg->i);
 }
 
 void
 kbfunc_client_grouponly(struct client_ctx *cc, union arg *arg)
 {
-	group_only(cc->sc, KBTOGROUP(arg->i));
+	group_only(cc->sc, arg->i);
 }
 
 void
@@ -440,7 +440,7 @@ kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg)
 {
-	group_movetogroup(cc, KBTOGROUP(arg->i));
+	group_movetogroup(cc, arg->i);
 }
 
 void
@@ -452,13 +452,13 @@ kbfunc_client_maximize(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_vmaximize(struct client_ctx *cc, union arg *arg)
 {
-	client_vertmaximize(cc);
+	client_vmaximize(cc);
 }
 
 void
 kbfunc_client_hmaximize(struct client_ctx *cc, union arg *arg)
 {
-	client_horizmaximize(cc);
+	client_hmaximize(cc);
 }
 
 void
diff --git a/menu.c b/menu.c
index 87c04d6..9f152fb 100644
--- a/menu.c
+++ b/menu.c
@@ -350,8 +350,7 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
     struct menu_q *resultq)
 {
 	struct menu		*mi;
-	XineramaScreenInfo	*xine;
-	int			 xmin, xmax, ymin, ymax;
+	struct geom		 xine;
 	int			 n, xsave, ysave;
 
 	if (mc->list) {
@@ -395,32 +394,22 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
 	}
 
 	xine = screen_find_xinerama(sc, mc->x, mc->y);
-	if (xine) {
-		xmin = xine->x_org;
-		xmax = xine->x_org + xine->width;
-		ymin = xine->y_org;
-		ymax = xine->y_org + xine->height;
-	} else {
-		xmin = ymin = 0;
-		xmax = sc->view.w;
-		ymax = sc->view.h;
-	}
 
 	xsave = mc->x;
 	ysave = mc->y;
 
 	/* Never hide the top, or left side, of the menu. */
-	if (mc->x + mc->width >= xmax)
-		mc->x = xmax - mc->width;
-	if (mc->x < xmin) {
-		mc->x = xmin;
-		mc->width = xmax - xmin;
+	if (mc->x + mc->width >= xine.w)
+		mc->x = xine.w - mc->width;
+	if (mc->x < xine.x) {
+		mc->x = xine.x;
+		mc->width = xine.w - xine.x;
 	}
-	if (mc->y + mc->height >= ymax)
-		mc->y = ymax - mc->height;
-	if (mc->y < ymin) {
-		mc->y = ymin;
-		mc->height = ymax - ymin;
+	if (mc->y + mc->height >= xine.h)
+		mc->y = xine.h - mc->height;
+	if (mc->y < xine.y) {
+		mc->y = xine.y;
+		mc->height = xine.h - xine.y;
 	}
 
 	if (mc->x != xsave || mc->y != ysave)
@@ -443,7 +432,7 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
 		int y = n * font_height(sc) + font_ascent(sc) + 1;
 
 		/* Stop drawing when menu doesn't fit inside the screen. */
-		if (mc->y + y > ymax)
+		if (mc->y + y > xine.h)
 			break;
 
 		font_draw(sc, text, MIN(strlen(text), MENU_MAXENTRY),
diff --git a/mousefunc.c b/mousefunc.c
index 7c07a36..d604a34 100644
--- a/mousefunc.c
+++ b/mousefunc.c
@@ -162,11 +162,11 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
 			cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;
 
 			cc->geom.x += client_snapcalc(cc->geom.x,
-			    cc->geom.w, sc->view.w,
-			    cc->bwidth, Conf.snapdist);
+			    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
+			    sc->work.x, sc->work.w, Conf.snapdist);
 			cc->geom.y += client_snapcalc(cc->geom.y,
-			    cc->geom.h, sc->view.h,
-			    cc->bwidth, Conf.snapdist);
+			    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
+			    sc->work.y, sc->work.h, Conf.snapdist);
 
 			/* don't move more than 60 times / second */
 			if ((ev.xmotion.time - ltime) > (1000 / 60)) {
diff --git a/parse.y b/parse.y
index aae8f3c..4188418 100644
--- a/parse.y
+++ b/parse.y
@@ -173,20 +173,20 @@ color		: COLOR colors
 		;
 
 colors		: ACTIVEBORDER STRING {
-			free(conf->color[CWM_COLOR_BORDER_ACTIVE].name);
-			conf->color[CWM_COLOR_BORDER_ACTIVE].name = $2;
+			free(conf->color[CWM_COLOR_BORDER_ACTIVE]);
+			conf->color[CWM_COLOR_BORDER_ACTIVE] = $2;
 		}
 		| INACTIVEBORDER STRING {
-			free(conf->color[CWM_COLOR_BORDER_INACTIVE].name);
-			conf->color[CWM_COLOR_BORDER_INACTIVE].name = $2;
+			free(conf->color[CWM_COLOR_BORDER_INACTIVE]);
+			conf->color[CWM_COLOR_BORDER_INACTIVE] = $2;
 		}
 		| GROUPBORDER STRING {
-			free(conf->color[CWM_COLOR_BORDER_GROUP].name);
-			conf->color[CWM_COLOR_BORDER_GROUP].name = $2;
+			free(conf->color[CWM_COLOR_BORDER_GROUP]);
+			conf->color[CWM_COLOR_BORDER_GROUP] = $2;
 		}
 		| UNGROUPBORDER STRING {
-			free(conf->color[CWM_COLOR_BORDER_UNGROUP].name);
-			conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2;
+			free(conf->color[CWM_COLOR_BORDER_UNGROUP]);
+			conf->color[CWM_COLOR_BORDER_UNGROUP] = $2;
 		}
 		| MENUBG STRING {
 			free(conf->menucolor[CWM_COLOR_MENU_BG]);
@@ -580,8 +580,8 @@ parse_config(const char *filename, struct conf *xconf)
 		(void)strlcpy(xconf->lockpath, conf->lockpath,
 		    sizeof(xconf->lockpath));
 
-		for (i = 0; i < CWM_COLOR_MAX; i++)
-			xconf->color[i].name = conf->color[i].name;
+		for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
+			xconf->color[i] = conf->color[i];
 
 		for (i = 0; i < CWM_COLOR_MENU_MAX; i++)
 			xconf->menucolor[i] = conf->menucolor[i];
diff --git a/screen.c b/screen.c
index 92ff9a4..5f7af56 100644
--- a/screen.c
+++ b/screen.c
@@ -30,8 +30,6 @@
 
 #include "calmwm.h"
 
-static void	 screen_init_xinerama(struct screen_ctx *);
-
 void
 screen_init(struct screen_ctx *sc, u_int which)
 {
@@ -125,48 +123,40 @@ screen_updatestackingorder(struct screen_ctx *sc)
 }
 
 /*
- * If we're using RandR then we'll redo this whenever the screen
- * changes since a CTRC may have been added or removed
- */
-void
-screen_init_xinerama(struct screen_ctx *sc)
-{
-	XineramaScreenInfo	*info = NULL;
-	int			 no = 0;
-
-	if (XineramaIsActive(X_Dpy))
-		info = XineramaQueryScreens(X_Dpy, &no);
-
-	if (sc->xinerama != NULL)
-		XFree(sc->xinerama);
-	sc->xinerama = info;
-	sc->xinerama_no = no;
-}
-
-/*
  * Find which xinerama screen the coordinates (x,y) is on.
  */
-XineramaScreenInfo *
+struct geom
 screen_find_xinerama(struct screen_ctx *sc, int x, int y)
 {
 	XineramaScreenInfo	*info;
+	struct geom		 geom;
 	int			 i;
 
+	geom = sc->view;
+
 	if (sc->xinerama == NULL)
-		return (NULL);
+		return (geom);
 
 	for (i = 0; i < sc->xinerama_no; i++) {
 		info = &sc->xinerama[i];
 		if (x >= info->x_org && x < info->x_org + info->width &&
-		    y >= info->y_org && y < info->y_org + info->height)
-			return (info);
+		    y >= info->y_org && y < info->y_org + info->height) {
+			geom.x = info->x_org;
+			geom.y = info->y_org;
+			geom.w = info->width;
+			geom.h = info->height;
+			break;
+		}
 	}
-	return (NULL);
+	return (geom);
 }
 
 void
 screen_update_geometry(struct screen_ctx *sc)
 {
+	XineramaScreenInfo	*info = NULL;
+	int			 info_no = 0;
+
 	sc->view.x = 0;
 	sc->view.y = 0;
 	sc->view.w = DisplayWidth(X_Dpy, sc->which);
@@ -177,7 +167,13 @@ screen_update_geometry(struct screen_ctx *sc)
 	sc->work.w = sc->view.w - (sc->gap.left + sc->gap.right);
 	sc->work.h = sc->view.h - (sc->gap.top + sc->gap.bottom);
 
-	screen_init_xinerama(sc);
+	/* RandR event may have a CTRC added or removed. */
+	if (XineramaIsActive(X_Dpy))
+		info = XineramaQueryScreens(X_Dpy, &info_no);
+	if (sc->xinerama != NULL)
+		XFree(sc->xinerama);
+	sc->xinerama = info;
+	sc->xinerama_no = info_no;
 
 	xu_ewmh_net_desktop_geometry(sc);
 	xu_ewmh_net_workarea(sc);
diff --git a/xutil.c b/xutil.c
index d141766..cb8b3fc 100644
--- a/xutil.c
+++ b/xutil.c
@@ -411,7 +411,7 @@ xu_ewmh_net_wm_desktop(struct client_ctx *cc)
 	long			 no = 0xffffffff;
 
 	if (gc)
-		no = gc->shortcut - 1;
+		no = gc->shortcut;
 
 	XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP].atom,
 	    XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1);