summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2013-11-12 21:25:00 +0000
committerokan <okan>2013-11-12 21:25:00 +0000
commit2937b2066f005ccb6f89bfe6480284874a398feb (patch)
tree27be895b7112ac1bd77976eb4a84008ff96b514b
parentbda68b09244bc2130839e6a828158cf1a9f0839b (diff)
downloadcwm-2937b2066f005ccb6f89bfe6480284874a398feb.tar.gz
cwm-2937b2066f005ccb6f89bfe6480284874a398feb.tar.xz
cwm-2937b2066f005ccb6f89bfe6480284874a398feb.zip
Alter the r1.35 of event.c race fix. Remove the forward looking event
queue check (removing the need for a server grab/ungrab) - if the client
is going away, let it fall all the way through to a DestroyNotify event.
There's no longer a need for us to manually destroy a client ourselves
(removing yet another server grab/ungrab).  Instead, when the
UnmapNotify event is synthetic, simply set the state to Withdrawn (as
per ICCCM), else Iconic (in our case 'hidden').

Verified with test case from the 2009 race which was the original reason
for r1.35 of event.c.
-rw-r--r--calmwm.h2
-rw-r--r--client.c11
-rw-r--r--xevents.c20
3 files changed, 6 insertions, 27 deletions
diff --git a/calmwm.h b/calmwm.h
index bedfde0..d65b437 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -370,7 +370,7 @@ struct client_ctx	*client_current(void);
 void			 client_cycle(struct screen_ctx *, int);
 void			 client_cycle_leave(struct screen_ctx *,
 			     struct client_ctx *);
-void			 client_delete(struct client_ctx *, int);
+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 *);
diff --git a/client.c b/client.c
index 1c559d4..173c0f5 100644
--- a/client.c
+++ b/client.c
@@ -149,20 +149,11 @@ client_init(Window win, struct screen_ctx *sc, int mapped)
 }
 
 void
-client_delete(struct client_ctx *cc, int destroy)
+client_delete(struct client_ctx *cc)
 {
 	struct screen_ctx	*sc = cc->sc;
 	struct winname		*wn;
 
-	if (destroy) {
-		XGrabServer(X_Dpy);
-		cc->state = WithdrawnState;
-		xu_set_wm_state(cc->win, cc->state);
-		XRemoveFromSaveSet(X_Dpy, cc->win);
-		XSync(X_Dpy, False);
-		XUngrabServer(X_Dpy);
-	}
-
 	TAILQ_REMOVE(&sc->mruq, cc, mru_entry);
 	TAILQ_REMOVE(&Clientq, cc, entry);
 
diff --git a/xevents.c b/xevents.c
index e6247ab..8c07f39 100644
--- a/xevents.c
+++ b/xevents.c
@@ -97,27 +97,15 @@ static void
 xev_handle_unmapnotify(XEvent *ee)
 {
 	XUnmapEvent		*e = &ee->xunmap;
-	XEvent			ev;
 	struct client_ctx	*cc;
 
-	/* XXX, we need a recursive locking wrapper around grab server */
-	XGrabServer(X_Dpy);
 	if ((cc = client_find(e->window)) != NULL) {
-		/*
-		 * If it's going to die anyway, nuke it.
-		 *
-		 * Else, if it's a synthetic event delete state, since they
-		 * want it to be withdrawn. ICCM recommends you withdraw on
-		 * this even if we haven't alredy been told to iconify, to
-		 * deal with legacy clients.
-		 */
-		if (XCheckTypedWindowEvent(X_Dpy, cc->win,
-		    DestroyNotify, &ev) || e->send_event != 0) {
-			client_delete(cc, 1);
+		if (e->send_event) {
+			cc->state = WithdrawnState;
+			xu_set_wm_state(cc->win, cc->state);
 		} else
 			client_hide(cc);
 	}
-	XUngrabServer(X_Dpy);
 }
 
 static void
@@ -127,7 +115,7 @@ xev_handle_destroynotify(XEvent *ee)
 	struct client_ctx	*cc;
 
 	if ((cc = client_find(e->window)) != NULL)
-		client_delete(cc, 0);
+		client_delete(cc);
 }
 
 static void