compositor: Focus the no focus window during modal plugin operations

Modal operations are usually far from transient, so it makes sense to
unfocus the currently focused window while the operation is going on.
If no other window was focused and the window is still alive when the
modal operation is finished, focus will be restored back.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/452
This commit is contained in:
Carlos Garnacho 2018-09-18 19:49:03 +02:00 committed by Jonas Ådahl
parent 7bd668e6d0
commit e62c9e1c5d
2 changed files with 20 additions and 0 deletions

View File

@ -40,6 +40,8 @@ struct _MetaCompositor
MetaPluginManager *plugin_mgr; MetaPluginManager *plugin_mgr;
MetaWindow *restore_focus_window;
gboolean frame_has_updated_xsurfaces; gboolean frame_has_updated_xsurfaces;
gboolean have_x11_sync_object; gboolean have_x11_sync_object;
}; };

View File

@ -375,6 +375,11 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
if (!grab_devices (options, timestamp)) if (!grab_devices (options, timestamp))
return FALSE; return FALSE;
g_set_object (&compositor->restore_focus_window,
meta_display_get_focus_window (display));
meta_x11_display_focus_the_no_focus_window (display->x11_display,
timestamp);
display->grab_op = META_GRAB_OP_COMPOSITOR; display->grab_op = META_GRAB_OP_COMPOSITOR;
display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB; display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
display->grab_window = NULL; display->grab_window = NULL;
@ -418,6 +423,19 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
display->grab_have_pointer = FALSE; display->grab_have_pointer = FALSE;
display->grab_have_keyboard = FALSE; display->grab_have_keyboard = FALSE;
if (compositor->restore_focus_window)
{
if (!compositor->restore_focus_window->unmanaging &&
!meta_display_get_focus_window (display))
{
meta_x11_display_set_input_focus_window (display->x11_display,
compositor->restore_focus_window,
FALSE, timestamp);
}
g_clear_object (&compositor->restore_focus_window);
}
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp); meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);