about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.h10
-rw-r--r--client.c100
-rw-r--r--group.c6
-rw-r--r--search.c4
-rw-r--r--xevents.c6
-rw-r--r--xutil.c27
6 files changed, 73 insertions, 80 deletions
diff --git a/calmwm.h b/calmwm.h
index 349101b..e79f522 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -179,7 +179,6 @@ struct client_ctx {
 #define CLIENT_MAXFLAGS			(CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
 #define CLIENT_MAXIMIZED		(CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
 	int			 flags;
-	int			 state;
 	int			 active;
 	int			 stackingorder;
 	struct winname_q	 nameq;
@@ -189,8 +188,8 @@ struct client_ctx {
 	char			*label;
 	char			*matchname;
 	struct group_ctx	*group;
-	char			*app_class;
-	char			*app_name;
+	XClassHint		ch;
+	XWMHints		*wmh;
 };
 TAILQ_HEAD(client_ctx_q, client_ctx);
 TAILQ_HEAD(cycle_entry_q, client_ctx);
@@ -386,6 +385,7 @@ void			 client_delete(struct client_ctx *);
 void			 client_draw_border(struct client_ctx *);
 struct client_ctx	*client_find(Window);
 void			 client_freeze(struct client_ctx *);
+long			 client_get_wm_state(struct client_ctx *);
 void			 client_getsizehints(struct client_ctx *);
 void			 client_hide(struct client_ctx *);
 void			 client_hmaximize(struct client_ctx *);
@@ -401,6 +401,7 @@ void			 client_ptrwarp(struct client_ctx *);
 void			 client_raise(struct client_ctx *);
 void			 client_resize(struct client_ctx *, int);
 void			 client_send_delete(struct client_ctx *);
+void			 client_set_wm_state(struct client_ctx *, long);
 void			 client_setactive(struct client_ctx *);
 void			 client_setname(struct client_ctx *);
 int			 client_snapcalc(int, int, int, int, int);
@@ -409,6 +410,7 @@ void			 client_unhide(struct client_ctx *);
 void			 client_vmaximize(struct client_ctx *);
 void 			 client_vtile(struct client_ctx *);
 void			 client_warp(struct client_ctx *);
+void			 client_wm_hints(struct client_ctx *);
 
 void			 group_alltoggle(struct screen_ctx *);
 void			 group_autogroup(struct client_ctx *);
@@ -521,7 +523,6 @@ void			 xev_loop(void);
 void			 xu_btn_grab(Window, int, u_int);
 void			 xu_btn_ungrab(Window);
 int			 xu_getprop(Window, Atom, Atom, long, unsigned char **);
-int			 xu_get_wm_state(Window, int *);
 int			 xu_getstrprop(Window, Atom, char **);
 void			 xu_key_grab(Window, u_int, KeySym);
 void			 xu_key_ungrab(Window);
@@ -530,7 +531,6 @@ int			 xu_ptr_grab(Window, u_int, Cursor);
 int			 xu_ptr_regrab(u_int, Cursor);
 void			 xu_ptr_setpos(Window, int, int);
 void			 xu_ptr_ungrab(void);
-void			 xu_set_wm_state(Window win, int);
 void			 xu_xft_draw(struct screen_ctx *, const char *,
 			     int, int, int);
 int			 xu_xft_width(XftFont *, const char *, int);
diff --git a/client.c b/client.c
index 05b1965..71a03f2 100644
--- a/client.c
+++ b/client.c
@@ -37,7 +37,7 @@ static void			 client_mtf(struct client_ctx *);
 static void			 client_none(struct screen_ctx *);
 static void			 client_placecalc(struct client_ctx *);
 static void			 client_wm_protocols(struct client_ctx *);
-static void			 client_getmwmhints(struct client_ctx *);
+static void			 client_mwm_hints(struct client_ctx *);
 static int			 client_inbound(struct client_ctx *, int, int);
 
 struct client_ctx	*_curcc = NULL;
@@ -58,9 +58,7 @@ struct client_ctx *
 client_init(Window win, struct screen_ctx *sc, int mapped)
 {
 	struct client_ctx	*cc;
-	XClassHint		 xch;
 	XWindowAttributes	 wattr;
-	XWMHints		*wmhints;
 	int			 state;
 
 	if (win == None)
@@ -70,22 +68,19 @@ client_init(Window win, struct screen_ctx *sc, int mapped)
 
 	XGrabServer(X_Dpy);
 
-	cc->state = mapped ? NormalState : IconicState;
 	cc->sc = sc;
 	cc->win = win;
 
-	client_getsizehints(cc);
-
 	TAILQ_INIT(&cc->nameq);
 	client_setname(cc);
 
 	conf_client(cc);
 
-	if (XGetClassHint(X_Dpy, cc->win, &xch)) {
-		cc->app_name = xch.res_name;
-		cc->app_class = xch.res_class;
-	}
-	client_getmwmhints(cc);
+	XGetClassHint(X_Dpy, cc->win, &cc->ch);
+	client_wm_hints(cc);
+	client_wm_protocols(cc);
+	client_getsizehints(cc);
+	client_mwm_hints(cc);
 
 	/* Saved pointer position */
 	cc->ptr.x = -1;
@@ -98,37 +93,24 @@ client_init(Window win, struct screen_ctx *sc, int mapped)
 	cc->geom.h = wattr.height;
 	cc->colormap = wattr.colormap;
 
-	if ((wmhints = XGetWMHints(X_Dpy, cc->win)) != NULL) {
-		if (wmhints->flags & InputHint) {
-			if (wmhints->input == 1)
-				cc->flags |= CLIENT_INPUT;
-		}
-	}
 	if (wattr.map_state != IsViewable) {
 		client_placecalc(cc);
 		client_move(cc);
-		if ((wmhints) && (wmhints->flags & StateHint)) {
-			cc->state = wmhints->initial_state;
-			xu_set_wm_state(cc->win, cc->state);
-		}
+		if ((cc->wmh) && (cc->wmh->flags & StateHint))
+			client_set_wm_state(cc, cc->wmh->initial_state);
 	}
-	if (wmhints)
-		XFree(wmhints);
-	client_draw_border(cc);
-
-	if (xu_get_wm_state(cc->win, &state) < 0)
-		state = NormalState;
 
 	XSelectInput(X_Dpy, cc->win, ColormapChangeMask | EnterWindowMask |
 	    PropertyChangeMask | KeyReleaseMask);
 
-	XAddToSaveSet(X_Dpy, cc->win);
-
 	client_transient(cc);
 
 	/* Notify client of its configuration. */
 	client_config(cc);
 
+	if ((state = client_get_wm_state(cc)) < 0)
+		state = NormalState;
+
 	(state == IconicState) ? client_hide(cc) : client_unhide(cc);
 
 	TAILQ_INSERT_TAIL(&sc->mruq, cc, mru_entry);
@@ -136,7 +118,6 @@ client_init(Window win, struct screen_ctx *sc, int mapped)
 
 	xu_ewmh_net_client_list(sc);
 
-	client_wm_protocols(cc);
 	xu_ewmh_restore_net_wm_state(cc);
 
 	if (mapped)
@@ -165,17 +146,19 @@ client_delete(struct client_ctx *cc)
 	if (cc == client_current())
 		client_none(sc);
 
-	if (cc->app_name != NULL)
-		XFree(cc->app_name);
-	if (cc->app_class != NULL)
-		XFree(cc->app_class);
-
 	while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
 		TAILQ_REMOVE(&cc->nameq, wn, entry);
 		free(wn->name);
 		free(wn);
 	}
 
+	if (cc->ch.res_class)
+		XFree(cc->ch.res_class);
+	if (cc->ch.res_name)
+		XFree(cc->ch.res_name);
+	if (cc->wmh)
+		XFree(cc->wmh);
+
 	free(cc);
 }
 
@@ -430,7 +413,10 @@ client_ptrwarp(struct client_ctx *cc)
 		y = cc->geom.h / 2;
 	}
 
-	(cc->state == IconicState) ? client_unhide(cc) : client_raise(cc);
+	if (cc->flags & CLIENT_HIDDEN)
+		client_unhide(cc);
+	else
+		client_raise(cc);
 	xu_ptr_setpos(cc->win, x, y);
 }
 
@@ -456,8 +442,7 @@ client_hide(struct client_ctx *cc)
 
 	cc->active = 0;
 	cc->flags |= CLIENT_HIDDEN;
-	cc->state = IconicState;
-	xu_set_wm_state(cc->win, cc->state);
+	client_set_wm_state(cc, IconicState);
 
 	if (cc == client_current())
 		client_none(cc->sc);
@@ -469,8 +454,8 @@ client_unhide(struct client_ctx *cc)
 	XMapRaised(X_Dpy, cc->win);
 
 	cc->flags &= ~CLIENT_HIDDEN;
-	cc->state = NormalState;
-	xu_set_wm_state(cc->win, cc->state);
+	client_set_wm_state(cc, NormalState);
+	client_draw_border(cc);
 }
 
 void
@@ -516,6 +501,16 @@ client_wm_protocols(struct client_ctx *cc)
 }
 
 void
+client_wm_hints(struct client_ctx *cc)
+{
+	if ((cc->wmh = XGetWMHints(X_Dpy, cc->win)) == NULL)
+		return;
+
+	if ((cc->wmh->flags & InputHint) && (cc->wmh->input))
+		cc->flags |= CLIENT_INPUT;
+}
+
+void
 client_msg(struct client_ctx *cc, Atom proto)
 {
 	XClientMessageEvent	 cm;
@@ -808,7 +803,7 @@ client_applysizehints(struct client_ctx *cc)
 }
 
 static void
-client_getmwmhints(struct client_ctx *cc)
+client_mwm_hints(struct client_ctx *cc)
 {
 	struct mwm_hints	*mwmh;
 
@@ -986,3 +981,26 @@ client_vtile(struct client_ctx *cc)
 		i++;
 	}
 }
+
+long
+client_get_wm_state(struct client_ctx *cc)
+{
+	long	*p, state = -1;
+
+	if (xu_getprop(cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 2L,
+	    (unsigned char **)&p) > 0) {
+		state = *p;
+		XFree(p);
+	}
+	return(state);
+}
+
+void
+client_set_wm_state(struct client_ctx *cc, long state)
+{
+	long	 data[] = { state, None };
+
+	XChangeProperty(X_Dpy, cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 32,
+	    PropModeReplace, (unsigned char *)data, 2);
+}
+
diff --git a/group.c b/group.c
index 85fc921..12a30e1 100644
--- a/group.c
+++ b/group.c
@@ -371,7 +371,7 @@ group_autogroup(struct client_ctx *cc)
 	int			 no = -1, both_match = 0;
 	long			*grpno;
 
-	if (cc->app_class == NULL || cc->app_name == NULL)
+	if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
 		return;
 
 	if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP],
@@ -385,9 +385,9 @@ group_autogroup(struct client_ctx *cc)
 		XFree(grpno);
 	} else {
 		TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
-			if (strcmp(aw->class, cc->app_class) == 0) {
+			if (strcmp(aw->class, cc->ch.res_class) == 0) {
 				if ((aw->name != NULL) &&
-				    (strcmp(aw->name, cc->app_name) == 0)) {
+				    (strcmp(aw->name, cc->ch.res_name) == 0)) {
 					no = aw->num;
 					both_match = 1;
 				} else if (aw->name == NULL && !both_match)
diff --git a/search.c b/search.c
index b1621f9..bde8319 100644
--- a/search.c
+++ b/search.c
@@ -85,8 +85,8 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
 		}
 
 		/* Then if there is a match on the window class name. */
-		if (tier < 0 && strsubmatch(search, cc->app_class, 0)) {
-			cc->matchname = cc->app_class;
+		if (tier < 0 && strsubmatch(search, cc->ch.res_class, 0)) {
+			cc->matchname = cc->ch.res_class;
 			tier = 3;
 		}
 
diff --git a/xevents.c b/xevents.c
index cff5f0f..fe6192d 100644
--- a/xevents.c
+++ b/xevents.c
@@ -99,8 +99,7 @@ xev_handle_unmapnotify(XEvent *ee)
 
 	if ((cc = client_find(e->window)) != NULL) {
 		if (e->send_event) {
-			cc->state = WithdrawnState;
-			xu_set_wm_state(cc->win, cc->state);
+			client_set_wm_state(cc, WithdrawnState);
 		} else {
 			if (!(cc->flags & CLIENT_HIDDEN))
 				client_delete(cc);
@@ -187,6 +186,9 @@ xev_handle_propertynotify(XEvent *ee)
 		case XA_WM_NAME:
 			client_setname(cc);
 			break;
+		case XA_WM_HINTS:
+			client_wm_hints(cc);
+			break;
 		case XA_WM_TRANSIENT_FOR:
 			client_transient(cc);
 			break;
diff --git a/xutil.c b/xutil.c
index ca07cae..d14a981 100644
--- a/xutil.c
+++ b/xutil.c
@@ -157,33 +157,6 @@ xu_getstrprop(Window win, Atom atm, char **text) {
 	return (nitems);
 }
 
-int
-xu_get_wm_state(Window win, int *state)
-{
-	long	*p = NULL;
-
-	if (xu_getprop(win, cwmh[WM_STATE], cwmh[WM_STATE], 2L,
-	    (unsigned char **)&p) <= 0)
-		return (-1);
-
-	*state = (int)*p;
-	XFree((char *)p);
-
-	return (0);
-}
-
-void
-xu_set_wm_state(Window win, int state)
-{
-	long	 dat[2];
-
-	dat[0] = state;
-	dat[1] = None;
-
-	XChangeProperty(X_Dpy, win, cwmh[WM_STATE], cwmh[WM_STATE], 32,
-	    PropModeReplace, (unsigned char *)dat, 2);
-}
-
 /* Root Window Properties */
 void
 xu_ewmh_net_supported(struct screen_ctx *sc)