about summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2013-12-12 20:15:07 +0000
committerokan <okan>2013-12-12 20:15:07 +0000
commitb276a2ef00a3333e0d474ad960c0e2b16880904d (patch)
treeb3e1b5f66735ecf4b7d6e70981064d59210f3f41
parente767ac9c6556d04c346b89e8d47d721c38cc366e (diff)
downloadcwm-b276a2ef00a3333e0d474ad960c0e2b16880904d.tar.gz
cwm-b276a2ef00a3333e0d474ad960c0e2b16880904d.tar.xz
cwm-b276a2ef00a3333e0d474ad960c0e2b16880904d.zip
ICCCM explicitly states that server time (CurrentTime) should *not* be
used for focus events, but rather the timestamp of the generated event.
Track the last event timestamp and send it down for a WM_TAKE_FOCUS
ClientMessage.  I suspect we should do this for clients that don't
announce this Atom as well, though the raciness gets us into a bind.

Solves focus order issue since WM_TAKE_FOCUS; fix verified by sthen@

ok sthen@
-rw-r--r--calmwm.c1
-rw-r--r--calmwm.h3
-rw-r--r--client.c11
-rw-r--r--xevents.c2
4 files changed, 12 insertions, 5 deletions
diff --git a/calmwm.c b/calmwm.c
index f2a8a3d..940db44 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -37,6 +37,7 @@
 
 char				**cwm_argv;
 Display				*X_Dpy;
+Time				 Last_Event_Time = CurrentTime;
 Atom				 cwmh[CWMH_NITEMS];
 Atom				 ewmh[EWMH_NITEMS];
 
diff --git a/calmwm.h b/calmwm.h
index 9dfe66a..c524fcf 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -316,6 +316,7 @@ struct mwm_hints {
 #define	MWM_DECOR_BORDER	(1<<1)
 
 extern Display				*X_Dpy;
+extern Time				 Last_Event_Time;
 extern struct screen_ctx_q		 Screenq;
 extern struct client_ctx_q		 Clientq;
 extern struct conf			 Conf;
@@ -381,7 +382,7 @@ void 			 client_htile(struct client_ctx *);
 void			 client_lower(struct client_ctx *);
 void			 client_map(struct client_ctx *);
 void			 client_maximize(struct client_ctx *);
-void			 client_msg(struct client_ctx *, Atom);
+void			 client_msg(struct client_ctx *, Atom, Time);
 void			 client_move(struct client_ctx *);
 struct client_ctx	*client_init(Window, struct screen_ctx *, int);
 void			 client_ptrsave(struct client_ctx *);
diff --git a/client.c b/client.c
index a601805..2ffeb34 100644
--- a/client.c
+++ b/client.c
@@ -168,6 +168,9 @@ client_setactive(struct client_ctx *cc)
 	struct screen_ctx	*sc = cc->sc;
 	struct client_ctx	*oldcc;
 
+	if (cc->flags & CLIENT_HIDDEN)
+		return;
+
 	XInstallColormap(X_Dpy, cc->colormap);
 
 	if ((cc->flags & CLIENT_INPUT) ||
@@ -176,7 +179,7 @@ client_setactive(struct client_ctx *cc)
 		    RevertToPointerRoot, CurrentTime);
 	}
 	if (cc->flags & CLIENT_WM_TAKE_FOCUS)
-		client_msg(cc, cwmh[WM_TAKE_FOCUS]);
+		client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
 
 	if ((oldcc = client_current())) {
 		oldcc->active = 0;
@@ -511,7 +514,7 @@ client_wm_hints(struct client_ctx *cc)
 }
 
 void
-client_msg(struct client_ctx *cc, Atom proto)
+client_msg(struct client_ctx *cc, Atom proto, Time ts)
 {
 	XClientMessageEvent	 cm;
 
@@ -521,7 +524,7 @@ client_msg(struct client_ctx *cc, Atom proto)
 	cm.message_type = cwmh[WM_PROTOCOLS];
 	cm.format = 32;
 	cm.data.l[0] = proto;
-	cm.data.l[1] = CurrentTime;
+	cm.data.l[1] = ts;
 
 	XSendEvent(X_Dpy, cc->win, False, NoEventMask, (XEvent *)&cm);
 }
@@ -530,7 +533,7 @@ void
 client_send_delete(struct client_ctx *cc)
 {
 	if (cc->flags & CLIENT_WM_DELETE_WINDOW)
-		client_msg(cc, cwmh[WM_DELETE_WINDOW]);
+		client_msg(cc, cwmh[WM_DELETE_WINDOW], CurrentTime);
 	else
 		XKillClient(X_Dpy, cc->win);
 }
diff --git a/xevents.c b/xevents.c
index 60944d7..e2065ba 100644
--- a/xevents.c
+++ b/xevents.c
@@ -212,6 +212,8 @@ xev_handle_enternotify(XEvent *ee)
 	XCrossingEvent		*e = &ee->xcrossing;
 	struct client_ctx	*cc;
 
+	Last_Event_Time = e->time;
+
 	if ((cc = client_find(e->window)) != NULL)
 		client_setactive(cc);
 }