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
This commit is contained in:
Mike Blumenkrantz 2015-08-21 15:50:10 -04:00
parent 6d976ab6e3
commit e426805993
1 changed files with 18 additions and 2 deletions

View File

@ -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);