From 8a618e4b006000cbd521031f4c191e862da03914 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 17 Jun 2014 02:49:39 -0400 Subject: [PATCH] bugfix: don't set input focus if not accepted http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 > Clients using the Globally Active model can only use a SetInputFocus request > to acquire the input focus when they do not already have it on receipt of one > of the following events: > * ButtonPress > * ButtonRelease > * Passive-grabbed KeyPress > * Passive-grabbed KeyRelease Since managing a window happens on a MapNotify (which is absent from this list), the window cannot accept input focus, so we should not try to focus the window at all. Fixes an issue with xfce4-notifyd which (correctly) declines focus when we send WM_TAKE_FOCUS, which puts i3 in a state where i3 focus and X focus are different when a notification appears. --- src/ewmh.c | 6 +++--- src/manage.c | 2 +- testcases/t/158-wm_take_focus.t | 14 +++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ewmh.c b/src/ewmh.c index 7ab0c22a..3ef79937 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -48,9 +48,9 @@ void ewmh_update_number_of_desktops(void) { Con *output; uint32_t idx = 0; - TAILQ_FOREACH (output, &(croot->nodes_head), nodes) { + TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { Con *ws; - TAILQ_FOREACH (ws, &(output_get_content(output)->nodes_head), nodes) { + TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) { if (STARTS_WITH(ws->name, "__")) continue; ++idx; @@ -58,7 +58,7 @@ void ewmh_update_number_of_desktops(void) { } xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, - A__NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &idx); + A__NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &idx); } /* diff --git a/src/manage.c b/src/manage.c index 227e9d24..202b0649 100644 --- a/src/manage.c +++ b/src/manage.c @@ -505,7 +505,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki /* Defer setting focus after the 'new' event has been sent to ensure the * proper window event sequence. */ - if (set_focus) { + if (set_focus && !nc->window->doesnt_accept_focus) { DLOG("Now setting focus.\n"); con_focus(nc); } diff --git a/testcases/t/158-wm_take_focus.t b/testcases/t/158-wm_take_focus.t index ba03913a..050e1162 100644 --- a/testcases/t/158-wm_take_focus.t +++ b/testcases/t/158-wm_take_focus.t @@ -59,6 +59,18 @@ subtest 'Window without WM_TAKE_FOCUS', sub { done_testing; }; +# http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 +# > Clients using the Globally Active model can only use a SetInputFocus request +# > to acquire the input focus when they do not already have it on receipt of one +# > of the following events: +# > * ButtonPress +# > * ButtonRelease +# > * Passive-grabbed KeyPress +# > * Passive-grabbed KeyRelease +# +# Since managing a window happens on a MapNotify (which is absent from this +# list), the window cannot accept input focus, so we should not try to focus +# the window at all. subtest 'Window with WM_TAKE_FOCUS and without InputHint', sub { fresh_workspace; @@ -74,7 +86,7 @@ subtest 'Window with WM_TAKE_FOCUS and without InputHint', sub { $window->map; - ok(recv_take_focus($window), 'got ClientMessage with WM_TAKE_FOCUS atom'); + ok(!recv_take_focus($window), 'did not receive ClientMessage'); done_testing; }; -- 2.39.5