summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.h2
-rw-r--r--client.c5
-rw-r--r--xevents.c35
3 files changed, 23 insertions, 19 deletions
diff --git a/calmwm.h b/calmwm.h
index 5234376..1343011 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -310,7 +310,7 @@ __dead void		 usage(void);
 struct client_ctx	*client_find(Window);
 void			 client_setup(void);
 struct client_ctx	*client_new(Window, struct screen_ctx *, int);
-int			 client_delete(struct client_ctx *, int, int);
+int			 client_delete(struct client_ctx *);
 void			 client_setactive(struct client_ctx *, int);
 void			 client_resize(struct client_ctx *);
 void			 client_lower(struct client_ctx *);
diff --git a/client.c b/client.c
index cf72174..ab3bd3d 100644
--- a/client.c
+++ b/client.c
@@ -144,14 +144,11 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
 }
 
 int
-client_delete(struct client_ctx *cc, int sendevent, int ignorewindow)
+client_delete(struct client_ctx *cc)
 {
 	struct screen_ctx	*sc = CCTOSC(cc);
 	struct winname		*wn;
 
-	if (cc->state == IconicState && !sendevent)
-		return (1);
-
 	group_client_delete(cc);
 
 	XGrabServer(X_Dpy);
diff --git a/xevents.c b/xevents.c
index 4add085..8db5862 100644
--- a/xevents.c
+++ b/xevents.c
@@ -36,12 +36,8 @@ void
 xev_handle_maprequest(struct xevent *xev, XEvent *ee)
 {
 	XMapRequestEvent	*e = &ee->xmaprequest;
-	XWindowAttributes	 xattr;
 	struct client_ctx	*cc = NULL, *old_cc;
-
-#ifdef notyet
-	int state;
-#endif
+	XWindowAttributes	 xattr;
 
 	if ((old_cc = client_current()) != NULL)
 		client_ptrsave(old_cc);
@@ -51,12 +47,6 @@ xev_handle_maprequest(struct xevent *xev, XEvent *ee)
 		cc = client_new(e->window, screen_fromroot(xattr.root), 1);
 	}
 
-#ifdef notyet			/* XXX - possibly, we shouldn't map if
-				 * the window is withdrawn. */
-	if (xu_getstate(cc, &state) == 0 && state == WithdrawnState)
-		warnx("WITHDRAWNSTATE for %s", cc->name);
-#endif
-
 	client_ptrwarp(cc);
 	xev_register(xev);
 }
@@ -65,10 +55,27 @@ void
 xev_handle_unmapnotify(struct xevent *xev, XEvent *ee)
 {
 	XUnmapEvent		*e = &ee->xunmap;
+	XEvent			ev;
 	struct client_ctx	*cc;
 
-	if ((cc = client_find(e->window)) != NULL)
-		client_delete(cc, e->send_event, 0);
+	/* 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);
+		} else
+			client_hide(cc);
+	}
+	XUngrabServer(X_Dpy);
 
 	xev_register(xev);
 }
@@ -80,7 +87,7 @@ xev_handle_destroynotify(struct xevent *xev, XEvent *ee)
 	struct client_ctx	*cc;
 
 	if ((cc = client_find(e->window)) != NULL)
-		client_delete(cc, 1, 1);
+		client_delete(cc);
 
 	xev_register(xev);
 }