summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c2
-rw-r--r--calmwm.h50
-rw-r--r--client.c20
-rw-r--r--conf.c11
-rw-r--r--cwm.14
-rw-r--r--cwmrc.56
-rw-r--r--group.c3
-rw-r--r--kbfunc.c25
-rw-r--r--menu.c25
-rw-r--r--parse.y49
-rw-r--r--screen.c1
-rw-r--r--xutil.c4
12 files changed, 136 insertions, 64 deletions
diff --git a/calmwm.c b/calmwm.c
index af1effb..f81a2f6 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -94,7 +94,7 @@ main(int argc, char **argv)
 	    signal(SIGINT, sighdlr) == SIG_ERR ||
 	    signal(SIGTERM, sighdlr) == SIG_ERR)
 		err(1, "signal");
- 
+
 	if (parse_config(Conf.conf_file, &Conf) == -1) {
 		warnx("error parsing config file");
 		if (nflag)
diff --git a/calmwm.h b/calmwm.h
index 9ae2afe..60e59f6 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -67,6 +67,7 @@
 #define CWM_CYCLE_FORWARD	0x0001
 #define CWM_CYCLE_REVERSE	0x0002
 #define CWM_CYCLE_INGROUP	0x0004
+#define CWM_CYCLE_INCLASS	0x0008
 
 enum cwm_status {
 	CWM_QUIT,
@@ -214,6 +215,7 @@ struct screen_ctx {
 	struct region_q		 regionq;
 	struct group_q		 groupq;
 	struct group_ctx	*group_active;
+	struct group_ctx	*group_last;
 	Colormap		 colormap;
 	Visual			*visual;
 	struct {
@@ -308,30 +310,39 @@ struct conf {
 
 /* MWM hints */
 struct mwm_hints {
-#define MWM_HINTS_ELEMENTS	3L
-#define MWM_FLAGS_STATUS	(1<<3)
+#define MWM_HINTS_ELEMENTS	5L
 
-#define MWM_FLAGS_FUNCTIONS	(1<<0)
-#define MWM_FLAGS_DECORATIONS	(1<<1)
-#define MWM_FLAGS_INPUT_MODE	(1<<2)
+#define MWM_HINTS_FUNCTIONS	(1L << 0)
+#define MWM_HINTS_DECORATIONS	(1L << 1)
+#define MWM_HINTS_INPUT_MODE	(1L << 2)
+#define MWM_HINTS_STATUS	(1L << 3)
 	unsigned long	flags;
 
-#define MWM_FUNCS_ALL		(1<<0)
-#define MWM_FUNCS_RESIZE	(1<<1)
-#define MWM_FUNCS_MOVE		(1<<2)
-#define MWM_FUNCS_MINIMIZE	(1<<3)
-#define MWM_FUNCS_MAXIMIZE	(1<<4)
-#define MWM_FUNCS_CLOSE		(1<<5)
+#define MWM_FUNC_ALL		(1L << 0)
+#define MWM_FUNC_RESIZE		(1L << 1)
+#define MWM_FUNC_MOVE		(1L << 2)
+#define MWM_FUNC_MINIMIZE	(1L << 3)
+#define MWM_FUNC_MAXIMIZE	(1L << 4)
+#define MWM_FUNC_CLOSE		(1L << 5)
 	unsigned long	functions;
 
-#define	MWM_DECOR_ALL		(1<<0)
-#define	MWM_DECOR_BORDER	(1<<1)
-#define MWM_DECOR_RESIZE_HANDLE	(1<<2)
-#define MWM_DECOR_TITLEBAR	(1<<3)
-#define MWM_DECOR_MENU		(1<<4)
-#define MWM_DECOR_MINIMIZE	(1<<5)
-#define MWM_DECOR_MAXIMIZE	(1<<6)
+#define	MWM_DECOR_ALL		(1L << 0)
+#define	MWM_DECOR_BORDER	(1L << 1)
+#define MWM_DECOR_RESIZEH	(1L << 2)
+#define MWM_DECOR_TITLE		(1L << 3)
+#define MWM_DECOR_MENU		(1L << 4)
+#define MWM_DECOR_MINIMIZE	(1L << 5)
+#define MWM_DECOR_MAXIMIZE	(1L << 6)
 	unsigned long	decorations;
+
+#define MWM_INPUT_MODELESS			0
+#define MWM_INPUT_PRIMARY_APPLICATION_MODAL	1
+#define MWM_INPUT_SYSTEM_MODAL			2
+#define MWM_INPUT_FULL_APPLICATION_MODAL	3
+	long		inputMode;
+
+#define MWM_TEAROFF_WINDOW	(1L << 0)
+	unsigned long	status;
 };
 
 enum cwmh {
@@ -501,6 +512,7 @@ void			 kbfunc_client_toggle_group(void *, struct cargs *);
 void			 kbfunc_client_movetogroup(void *, struct cargs *);
 void			 kbfunc_group_toggle(void *, struct cargs *);
 void			 kbfunc_group_only(void *, struct cargs *);
+void			 kbfunc_group_last(void *, struct cargs *);
 void			 kbfunc_group_close(void *, struct cargs *);
 void			 kbfunc_group_cycle(void *, struct cargs *);
 void			 kbfunc_group_toggle_all(void *, struct cargs *);
@@ -574,7 +586,7 @@ int			 xu_ewmh_get_net_wm_desktop(struct client_ctx *, long *);
 void			 xu_ewmh_set_net_wm_desktop(struct client_ctx *);
 Atom 			*xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
 void 			 xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
-			     int, Atom , Atom);
+			     int, Atom, Atom);
 void 			 xu_ewmh_set_net_wm_state(struct client_ctx *);
 void 			 xu_ewmh_restore_net_wm_state(struct client_ctx *);
 
diff --git a/client.c b/client.c
index cfdd048..e09a71d 100644
--- a/client.c
+++ b/client.c
@@ -336,6 +336,7 @@ client_toggle_fullscreen(struct client_ctx *cc)
 resize:
 	client_resize(cc, 0);
 	xu_ewmh_set_net_wm_state(cc);
+	client_ptr_inbound(cc, 1);
 }
 
 void
@@ -376,6 +377,7 @@ client_toggle_maximize(struct client_ctx *cc)
 resize:
 	client_resize(cc, 0);
 	xu_ewmh_set_net_wm_state(cc);
+	client_ptr_inbound(cc, 1);
 }
 
 void
@@ -408,6 +410,7 @@ client_toggle_vmaximize(struct client_ctx *cc)
 resize:
 	client_resize(cc, 0);
 	xu_ewmh_set_net_wm_state(cc);
+	client_ptr_inbound(cc, 1);
 }
 
 void
@@ -440,6 +443,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
 resize:
 	client_resize(cc, 0);
 	xu_ewmh_set_net_wm_state(cc);
+	client_ptr_inbound(cc, 1);
 }
 
 void
@@ -592,7 +596,7 @@ client_draw_border(struct client_ctx *cc)
 		pixel = sc->xftcolor[CWM_COLOR_BORDER_URGENCY].pixel;
 
 	XSetWindowBorderWidth(X_Dpy, cc->win, (unsigned int)cc->bwidth);
-	XSetWindowBorder(X_Dpy, cc->win, pixel);
+	XSetWindowBorder(X_Dpy, cc->win, pixel | (0xffu << 24));
 }
 
 static void
@@ -633,7 +637,7 @@ void
 client_wm_hints(struct client_ctx *cc)
 {
 	XWMHints	*wmh;
- 
+
 	if ((wmh = XGetWMHints(X_Dpy, cc->win)) != NULL) {
 		if ((wmh->flags & InputHint) && (wmh->input))
 			cc->flags |= CLIENT_INPUT;
@@ -845,13 +849,15 @@ client_mwm_hints(struct client_ctx *cc)
 
 	if (xu_get_prop(cc->win, cwmh[_MOTIF_WM_HINTS],
 	    cwmh[_MOTIF_WM_HINTS], MWM_HINTS_ELEMENTS,
-	    (unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) {
-		if (mwmh->flags & MWM_FLAGS_DECORATIONS &&
-		    !(mwmh->decorations & MWM_DECOR_ALL) &&
-		    !(mwmh->decorations & MWM_DECOR_BORDER))
+	    (unsigned char **)&mwmh) <= 0)
+		return;
+
+	if ((mwmh->flags & MWM_HINTS_DECORATIONS) &&
+	    !(mwmh->decorations & MWM_DECOR_ALL)) {
+		if (!(mwmh->decorations & MWM_DECOR_BORDER))
 			cc->bwidth = 0;
-		XFree(mwmh);
 	}
+	XFree(mwmh);
 }
 
 void
diff --git a/conf.c b/conf.c
index a3026cf..39f0406 100644
--- a/conf.c
+++ b/conf.c
@@ -136,9 +136,14 @@ static const struct {
 		(CWM_CYCLE_FORWARD | CWM_CYCLE_INGROUP)) },
 	{ FUNC_SC(window-rcycle-ingroup, client_cycle,
 		(CWM_CYCLE_REVERSE | CWM_CYCLE_INGROUP)) },
+	{ FUNC_SC(window-cycle-inclass, client_cycle,
+		(CWM_CYCLE_FORWARD | CWM_CYCLE_INCLASS)) },
+	{ FUNC_SC(window-rcycle-inclass, client_cycle,
+		(CWM_CYCLE_REVERSE | CWM_CYCLE_INCLASS)) },
 
 	{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
 	{ FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) },
+	{ FUNC_SC(group-last, group_last, 0) },
 	{ FUNC_SC(group-toggle-all, group_toggle_all, 0) },
 	{ FUNC_SC(group-toggle-1, group_toggle, 1) },
 	{ FUNC_SC(group-toggle-2, group_toggle, 2) },
@@ -219,6 +224,8 @@ static const struct {
 	{ "C-slash",	"menu-cmd" },
 	{ "M-Tab",	"window-cycle" },
 	{ "MS-Tab",	"window-rcycle" },
+	{ "M-grave",	"window-cycle-inclass" },
+	{ "MS-grave",	"window-rcycle-inclass" },
 	{ "CM-n",	"window-menu-label" },
 	{ "CM-x",	"window-close" },
 	{ "CM-a",	"group-toggle-all" },
@@ -647,7 +654,7 @@ conf_unbind_mouse(struct conf *c, struct bind_ctx *unbind)
 	struct bind_ctx		*mb = NULL, *mbnxt;
 
 	TAILQ_FOREACH_SAFE(mb, &c->mousebindq, entry, mbnxt) {
-		if ((unbind == NULL) || 
+		if ((unbind == NULL) ||
 		    ((mb->modmask == unbind->modmask) &&
 		     (mb->press.button == unbind->press.button))) {
 			TAILQ_REMOVE(&c->mousebindq, mb, entry);
@@ -669,6 +676,8 @@ conf_grab_kbd(Window win)
 
 	TAILQ_FOREACH(kb, &Conf.keybindq, entry) {
 		kc = XKeysymToKeycode(X_Dpy, kb->press.keysym);
+		if (kc == 0)
+			continue;
 		if ((XkbKeycodeToKeysym(X_Dpy, kc, 0, 0) != kb->press.keysym) &&
 		    (XkbKeycodeToKeysym(X_Dpy, kc, 0, 1) == kb->press.keysym))
 			kb->modmask |= ShiftMask;
diff --git a/cwm.1 b/cwm.1
index e0a892e..d70d856 100644
--- a/cwm.1
+++ b/cwm.1
@@ -102,6 +102,10 @@ Label current window.
 Cycle through currently visible windows.
 .It Ic MS-Tab
 Reverse cycle through currently visible windows.
+.It Ic M-grave
+Cycle through currently visible windows of the same window class.
+.It Ic MS-grave
+Reverse cycle through currently visible windows of the same window class.
 .It Ic CM-x
 Close current window.
 .It Ic CM-[n]
diff --git a/cwmrc.5 b/cwmrc.5
index ab70d25..7d5f1f8 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -273,6 +273,8 @@ menu.
 Toggle visibility of group n, where n is 1-9.
 .It group-only-[n]
 Show only group n, where n is 1-9, hiding other groups.
+.It group-last
+Show only the previously active group.
 .It group-close-[n]
 Close all windows in group n, where n is 1-9.
 .It group-toggle-all
@@ -293,6 +295,10 @@ Reverse cycle through windows.
 Forward cycle through windows in current group.
 .It window-rcycle-ingroup
 Reverse cycle through windows in current group.
+.It window-cycle-inclass
+Forward cycle through windows of the current window class.
+.It window-rcycle-inclass
+Reverse cycle through windows of the current window class.
 .It window-close
 Close current window.
 .It window-hide
diff --git a/group.c b/group.c
index de55211..3246936 100644
--- a/group.c
+++ b/group.c
@@ -215,6 +215,9 @@ group_only(struct screen_ctx *sc, int idx)
 {
 	struct group_ctx	*gc;
 
+	if (sc->group_last != sc->group_active)
+		sc->group_last = sc->group_active;
+
 	TAILQ_FOREACH(gc, &sc->groupq, entry) {
 		if (gc->num == idx)
 			group_show(gc);
diff --git a/kbfunc.c b/kbfunc.c
index cbccc56..d858b7b 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -430,7 +430,9 @@ kbfunc_client_cycle(void *ctx, struct cargs *cargs)
 		/* Only cycle visible and non-ignored windows. */
 		if ((newcc->flags & (CLIENT_SKIP_CYCLE)) ||
 		    ((flags & CWM_CYCLE_INGROUP) &&
-		    (newcc->gc != oldcc->gc)))
+		    (newcc->gc != oldcc->gc)) ||
+		    ((flags & CWM_CYCLE_INCLASS) &&
+		    strcmp(newcc->res_class, oldcc->res_class) != 0))
 			again = 1;
 
 		/* Is oldcc the only non-hidden window? */
@@ -450,7 +452,16 @@ kbfunc_client_cycle(void *ctx, struct cargs *cargs)
 		newcc->ptr.x = newcc->geom.w / 2;
 		newcc->ptr.y = newcc->geom.h / 2;
 	}
-	client_ptr_warp(newcc);
+
+	/* When no client is active, warp pointer to last active. */
+	if (oldcc->flags & (CLIENT_ACTIVE))
+		client_ptr_warp(newcc);
+	else if (oldcc->flags & (CLIENT_SKIP_CYCLE))
+		client_ptr_warp(newcc);
+	else {
+		client_raise(oldcc);
+		client_ptr_warp(oldcc);
+	}
 }
 
 void
@@ -479,6 +490,14 @@ kbfunc_group_only(void *ctx, struct cargs *cargs)
 }
 
 void
+kbfunc_group_last(void *ctx, struct cargs *cargs)
+{
+	struct screen_ctx	*sc = ctx;
+
+	group_only(ctx, sc->group_last->num);
+}
+
+void
 kbfunc_group_toggle(void *ctx, struct cargs *cargs)
 {
 	group_toggle(ctx, cargs->flag);
@@ -660,7 +679,7 @@ kbfunc_menu_exec(void *ctx, struct cargs *cargs)
 				/* lstat(2) in case d_type isn't supported. */
 				if (lstat(tpath, &sb) == -1)
 					continue;
-				if (!S_ISREG(sb.st_mode) && 
+				if (!S_ISREG(sb.st_mode) &&
 				    !S_ISLNK(sb.st_mode))
 					continue;
 			}
diff --git a/menu.c b/menu.c
index 43b5de8..2279f12 100644
--- a/menu.c
+++ b/menu.c
@@ -355,7 +355,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
 	XftTextExtentsUtf8(X_Dpy, sc->xftfont,
 	    (const FcChar8*)mc->dispstr, strlen(mc->dispstr), &extents);
 	mc->geom.w = extents.xOff;
-	mc->geom.h = sc->xftfont->height + 1;
+	mc->geom.h = sc->xftfont->ascent + sc->xftfont->descent;
 	mc->num = 1;
 
 	TAILQ_FOREACH(mi, resultq, resultentry) {
@@ -364,7 +364,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
 		    (const FcChar8*)mi->print,
 		    MIN(strlen(mi->print), MENU_MAXENTRY), &extents);
 		mc->geom.w = MAX(mc->geom.w, extents.xOff);
-		mc->geom.h += sc->xftfont->height + 1;
+		mc->geom.h += sc->xftfont->ascent + sc->xftfont->descent;
 		mc->num++;
 	}
 
@@ -403,15 +403,15 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
 	    (const FcChar8*)mc->dispstr, strlen(mc->dispstr));
 
 	TAILQ_FOREACH(mi, resultq, resultentry) {
-		int y = n * (sc->xftfont->height + 1) + sc->xftfont->ascent + 1;
+		int y = n * (sc->xftfont->ascent + sc->xftfont->descent);
 
 		/* Stop drawing when menu doesn't fit inside the screen. */
-		if (mc->geom.y + y > area.h)
+		if (mc->geom.y + y >= area.h)
 			break;
 
 		XftDrawStringUtf8(mc->xftdraw,
 		    &sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
-		    0, y,
+		    0, y + sc->xftfont->ascent,
 		    (const FcChar8*)mi->print, strlen(mi->print));
 		n++;
 	}
@@ -425,7 +425,7 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
 {
 	struct screen_ctx	*sc = mc->sc;
 	struct menu		*mi;
-	int			 color, i = 1;
+	int			 color, i = 1, y;
 
 	TAILQ_FOREACH(mi, resultq, resultentry)
 		if (entry == i++)
@@ -433,14 +433,13 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
 	if (mi == NULL)
 		return;
 
+	y = entry * (sc->xftfont->ascent + sc->xftfont->descent);
 	color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
-	XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
-	    (sc->xftfont->height + 1) * entry, mc->geom.w,
-	    (sc->xftfont->height + 1) + sc->xftfont->descent);
+	XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0, y,
+	    mc->geom.w, sc->xftfont->ascent + sc->xftfont->descent);
 	color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
 	XftDrawStringUtf8(mc->xftdraw,
-	    &sc->xftcolor[color], sc->xftfont,
-	    0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
+	    &sc->xftcolor[color], sc->xftfont, 0, y + sc->xftfont->ascent,
 	    (const FcChar8*)mi->print, strlen(mi->print));
 }
 
@@ -487,11 +486,11 @@ menu_calc_entry(struct menu_ctx *mc, int x, int y)
 	struct screen_ctx	*sc = mc->sc;
 	int			 entry;
 
-	entry = y / (sc->xftfont->height + 1);
+	entry = y / (sc->xftfont->ascent + sc->xftfont->descent);
 
 	/* in bounds? */
 	if (x < 0 || x > mc->geom.w || y < 0 ||
-	    y > (sc->xftfont->height + 1) * mc->num ||
+	    y > (sc->xftfont->ascent + sc->xftfont->descent) * mc->num ||
 	    entry < 0 || entry >= mc->num)
 		entry = -1;
 
diff --git a/parse.y b/parse.y
index 0138fdb..a451da5 100644
--- a/parse.y
+++ b/parse.y
@@ -81,7 +81,7 @@ typedef struct {
 %token	<v.string>		STRING
 %token	<v.number>		NUMBER
 %type	<v.number>		yesno
-%type	<v.string>		string
+%type	<v.string>		string numberstring
 %%
 
 grammar		: /* empty */
@@ -104,6 +104,17 @@ string		: string STRING			{
 		| STRING
 		;
 
+numberstring	: NUMBER				{
+			char	*s;
+			if (asprintf(&s, "%lld", $1) == -1) {
+				yyerror("string: asprintf");
+				YYERROR;
+			}
+			$$ = s;
+		}
+		| STRING
+		;
+
 yesno		: YES				{ $$ = 1; }
 		| NO				{ $$ = 0; }
 		;
@@ -209,7 +220,7 @@ main		: FONTNAME STRING		{
 			conf->gap.left = $4;
 			conf->gap.right = $5;
 		}
-		| BINDKEY STRING string {
+		| BINDKEY numberstring string {
 			if (!conf_bind_key(conf, $2, $3)) {
 				yyerror("invalid bind-key: %s %s", $2, $3);
 				free($2);
@@ -219,7 +230,7 @@ main		: FONTNAME STRING		{
 			free($2);
 			free($3);
 		}
-		| UNBINDKEY STRING {
+		| UNBINDKEY numberstring {
 			if (!conf_bind_key(conf, $2, NULL)) {
 				yyerror("invalid unbind-key: %s", $2);
 				free($2);
@@ -227,7 +238,7 @@ main		: FONTNAME STRING		{
 			}
 			free($2);
 		}
-		| BINDMOUSE STRING string {
+		| BINDMOUSE numberstring string {
 			if (!conf_bind_mouse(conf, $2, $3)) {
 				yyerror("invalid bind-mouse: %s %s", $2, $3);
 				free($2);
@@ -237,7 +248,7 @@ main		: FONTNAME STRING		{
 			free($2);
 			free($3);
 		}
-		| UNBINDMOUSE STRING {
+		| UNBINDMOUSE numberstring {
 			if (!conf_bind_mouse(conf, $2, NULL)) {
 				yyerror("invalid unbind-mouse: %s", $2);
 				free($2);
@@ -361,9 +372,9 @@ lookup(char *s)
 
 #define MAXPUSHBACK	128
 
-u_char	*parsebuf;
+char	*parsebuf;
 int	 parseindex;
-u_char	 pushback_buffer[MAXPUSHBACK];
+char	 pushback_buffer[MAXPUSHBACK];
 int	 pushback_index = 0;
 
 int
@@ -374,7 +385,7 @@ lgetc(int quotec)
 	if (parsebuf) {
 		/* Read character from the parsebuffer instead of input. */
 		if (parseindex >= 0) {
-			c = parsebuf[parseindex++];
+			c = (unsigned char)parsebuf[parseindex++];
 			if (c != '\0')
 				return (c);
 			parsebuf = NULL;
@@ -383,7 +394,7 @@ lgetc(int quotec)
 	}
 
 	if (pushback_index)
-		return (pushback_buffer[--pushback_index]);
+		return ((unsigned char)pushback_buffer[--pushback_index]);
 
 	if (quotec) {
 		if ((c = getc(file->stream)) == EOF) {
@@ -424,10 +435,10 @@ lungetc(int c)
 		if (parseindex >= 0)
 			return (c);
 	}
-	if (pushback_index < MAXPUSHBACK-1)
-		return (pushback_buffer[pushback_index++] = c);
-	else
+	if (pushback_index + 1 >= MAXPUSHBACK)
 		return (EOF);
+	pushback_buffer[pushback_index++] = c;
+	return (c);
 }
 
 int
@@ -440,7 +451,7 @@ findeol(void)
 	/* skip to either EOF or the first real EOL */
 	while (1) {
 		if (pushback_index)
-			c = pushback_buffer[--pushback_index];
+			c = (unsigned char)pushback_buffer[--pushback_index];
 		else
 			c = lgetc(0);
 		if (c == '\n') {
@@ -456,8 +467,8 @@ findeol(void)
 int
 yylex(void)
 {
-	u_char	 buf[8096];
-	u_char	*p;
+	char	 buf[8096];
+	char	*p;
 	int	 quotec, next, c;
 	int	 token;
 
@@ -514,7 +525,7 @@ yylex(void)
 	if (c == '-' || isdigit(c)) {
 		do {
 			*p++ = c;
-			if ((unsigned)(p-buf) >= sizeof(buf)) {
+			if ((size_t)(p-buf) >= sizeof(buf)) {
 				yyerror("string too long");
 				return (findeol());
 			}
@@ -537,8 +548,8 @@ yylex(void)
 		} else {
 nodigits:
 			while (p > buf + 1)
-				lungetc(*--p);
-			c = *--p;
+				lungetc((unsigned char)*--p);
+			c = (unsigned char)*--p;
 			if (c == '-')
 				return (c);
 		}
@@ -553,7 +564,7 @@ nodigits:
 	if (isalnum(c) || c == ':' || c == '_' || c == '*' || c == '/') {
 		do {
 			*p++ = c;
-			if ((unsigned)(p-buf) >= sizeof(buf)) {
+			if ((size_t)(p-buf) >= sizeof(buf)) {
 				yyerror("string too long");
 				return (findeol());
 			}
diff --git a/screen.c b/screen.c
index 373ff71..e880e97 100644
--- a/screen.c
+++ b/screen.c
@@ -60,6 +60,7 @@ screen_init(int which)
 	xu_ewmh_net_supported_wm_check(sc);
 
 	conf_group(sc);
+	sc->group_last = sc->group_active;
 	screen_update_geometry(sc);
 
 	xu_ewmh_net_desktop_names(sc);
diff --git a/xutil.c b/xutil.c
index 37af7db..230a2c5 100644
--- a/xutil.c
+++ b/xutil.c
@@ -73,8 +73,10 @@ xu_get_strprop(Window win, Atom atm, char **text) {
 	*text = NULL;
 
 	XGetTextProperty(X_Dpy, win, &prop, atm);
-	if (!prop.nitems)
+	if (!prop.nitems) {
+		XFree(prop.value);
 		return 0;
+	}
 
 	if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list,
 	    &nitems) == Success && nitems > 0 && *list) {