From e4268059934cb1009bfd864eb2b4962cc87e96a4 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 21 Aug 2015 15:50:10 -0400 Subject: [PATCH] track focus time for x11 canvas focus, unset client focus on x11 canvas focus-in in the case that the canvas window has just had focus set on it, apply this focus and ensure that no client retains focus this resolves a race condition where focusing the compositor canvas <-> client extremely quickly would result in a client trying to steal focus when it was not actually focused a notable (but trivial) side effect is that now when flipping desks at high speed while using mouse-based focus policies, the user is almost guaranteed to end on a desk which has open windows on it --- src/bin/e_comp_x.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index e986daffe..67c9d8965 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -43,6 +43,7 @@ struct _E_Comp_X_Data }; static unsigned int focus_time = 0; +static unsigned int focus_canvas_time = 0; static Ecore_Timer *focus_timer; static E_Client *mouse_client; static Eina_List *handlers = NULL; @@ -112,7 +113,11 @@ _e_comp_x_focus_check(void) /* if there is no new focused or it is a non-X client, * focus comp canvas on focus-out */ if ((!focused) || (e_pixmap_type_get(focused->pixmap) != E_PIXMAP_TYPE_X)) - e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE); + { + focus_canvas_time = ecore_x_current_time_get(); + focus_time = 0; + e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE); + } } static void @@ -2676,7 +2681,17 @@ _e_comp_x_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_W E_Client *ec, *focused; ec = _e_comp_x_client_find_by_window(ev->win); - if (!ec) return ECORE_CALLBACK_RENEW; + if (!ec) + { + if ((ev->win == e_comp->ee_win) && (ev->time >= focus_canvas_time) && (!focus_time)) + { + focused = e_client_focused_get(); + if (focused) + evas_object_focus_set(focused->frame, 0); + focus_canvas_time = 0; + } + return ECORE_CALLBACK_RENEW; + } /* block refocus attempts on iconic clients * these result from iconifying a client during a grab */ @@ -4335,6 +4350,7 @@ static void _e_comp_x_hook_client_focus_set(void *d EINA_UNUSED, E_Client *ec) { focus_time = ecore_x_current_time_get(); + focus_canvas_time = 0; if (!e_client_has_xwindow(ec)) { e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);