From c1bc6d37b385ff4dad1582583fd21f2c45b2c168 Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 5 Nov 2013 00:55:42 +0000 Subject: quick keyboard focus fix for clients that neither populate wmhints nor wmprotocols, like rdesktop; focus needs to be re-visited --- client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client.c b/client.c index 74fafbc..6c9581d 100644 --- a/client.c +++ b/client.c @@ -211,7 +211,8 @@ client_setactive(struct client_ctx *cc, int fg) if (fg) { XInstallColormap(X_Dpy, cc->colormap); - if (cc->flags & CLIENT_INPUT) { + if ((cc->flags & CLIENT_INPUT) || + ((cc->xproto & _WM_TAKE_FOCUS) == 0)) { XSetInputFocus(X_Dpy, cc->win, RevertToPointerRoot, CurrentTime); } -- cgit 1.4.1 From 3bb928a1c26c76d7e0a929ca3502c29170a83e53 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 8 Nov 2013 17:35:12 +0000 Subject: stash WMProtocols in flags --- calmwm.h | 8 ++------ client.c | 10 +++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/calmwm.h b/calmwm.h index f0361ba..bedfde0 100644 --- a/calmwm.h +++ b/calmwm.h @@ -126,11 +126,6 @@ struct winname { }; TAILQ_HEAD(winname_q, winname); -enum wm_protocols { - _WM_DELETE_WINDOW = 0x0001, - _WM_TAKE_FOCUS = 0x0002, -}; - struct client_ctx { TAILQ_ENTRY(client_ctx) entry; TAILQ_ENTRY(client_ctx) group_entry; @@ -157,7 +152,6 @@ struct client_ctx { int x; /* x position */ int y; /* y position */ } ptr; - enum wm_protocols xproto; #define CLIENT_HIDDEN 0x0001 #define CLIENT_IGNORE 0x0002 #define CLIENT_VMAXIMIZED 0x0004 @@ -166,6 +160,8 @@ struct client_ctx { #define CLIENT_GROUP 0x0020 #define CLIENT_UNGROUP 0x0040 #define CLIENT_INPUT 0x0080 +#define CLIENT_WM_DELETE_WINDOW 0x0100 +#define CLIENT_WM_TAKE_FOCUS 0x0200 #define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) diff --git a/client.c b/client.c index 6c9581d..f697cf2 100644 --- a/client.c +++ b/client.c @@ -212,11 +212,11 @@ client_setactive(struct client_ctx *cc, int fg) if (fg) { XInstallColormap(X_Dpy, cc->colormap); if ((cc->flags & CLIENT_INPUT) || - ((cc->xproto & _WM_TAKE_FOCUS) == 0)) { + ((cc->flags & CLIENT_WM_TAKE_FOCUS) == 0)) { XSetInputFocus(X_Dpy, cc->win, RevertToPointerRoot, CurrentTime); } - if (cc->xproto & _WM_TAKE_FOCUS) + if (cc->flags & CLIENT_WM_TAKE_FOCUS) client_msg(cc, cwmh[WM_TAKE_FOCUS]); conf_grab_mouse(cc->win); /* @@ -532,9 +532,9 @@ client_wm_protocols(struct client_ctx *cc) if (XGetWMProtocols(X_Dpy, cc->win, &p, &j)) { for (i = 0; i < j; i++) { if (p[i] == cwmh[WM_DELETE_WINDOW]) - cc->xproto |= _WM_DELETE_WINDOW; + cc->flags |= CLIENT_WM_DELETE_WINDOW; else if (p[i] == cwmh[WM_TAKE_FOCUS]) - cc->xproto |= _WM_TAKE_FOCUS; + cc->flags |= CLIENT_WM_TAKE_FOCUS; } XFree(p); } @@ -559,7 +559,7 @@ client_msg(struct client_ctx *cc, Atom proto) void client_send_delete(struct client_ctx *cc) { - if (cc->xproto & _WM_DELETE_WINDOW) + if (cc->flags & CLIENT_WM_DELETE_WINDOW) client_msg(cc, cwmh[WM_DELETE_WINDOW]); else XKillClient(X_Dpy, cc->win); -- cgit 1.4.1 From bda68b09244bc2130839e6a828158cf1a9f0839b Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 11 Nov 2013 12:51:15 +0000 Subject: Put back the border draw call in client_resize; since we are adding and removing the border on maximized clients we need to redraw. Also noticed by Tim van der Molen --- client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client.c b/client.c index f697cf2..1c559d4 100644 --- a/client.c +++ b/client.c @@ -401,6 +401,8 @@ client_resize(struct client_ctx *cc, int reset) xu_ewmh_set_net_wm_state(cc); } + client_draw_border(cc); + XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y, cc->geom.w, cc->geom.h); client_config(cc); -- cgit 1.4.1 From 2937b2066f005ccb6f89bfe6480284874a398feb Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 12 Nov 2013 21:25:00 +0000 Subject: 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. --- calmwm.h | 2 +- client.c | 11 +---------- xevents.c | 20 ++++---------------- 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 -- cgit 1.4.1