window: Postpone focusing until grab ended if uninteractable
When GNOME Shell is in the overview, we don't want windows to steal focus left and right, but once we leave the overview, we do want whatever was mapped with "take_focus" to get focus. Do that, but after the last grab was dismissed. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2690 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3185>
This commit is contained in:
parent
03ee48094e
commit
05eeb684d1
@ -297,6 +297,9 @@ void meta_display_cancel_touch (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_windows_are_interactable (MetaDisplay *display);
|
||||
|
||||
void meta_display_queue_focus (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_display_show_tablet_mapping_notification (MetaDisplay *display,
|
||||
ClutterInputDevice *pad,
|
||||
const gchar *pretty_name);
|
||||
|
@ -141,6 +141,11 @@ typedef struct _MetaDisplayPrivate
|
||||
GList *queue_windows[META_N_QUEUE_TYPES];
|
||||
|
||||
gboolean enable_input_capture;
|
||||
|
||||
struct {
|
||||
MetaWindow *window;
|
||||
gulong unmanaging_handler_id;
|
||||
} focus_on_grab_dismissed;
|
||||
} MetaDisplayPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaDisplay, meta_display, G_TYPE_OBJECT)
|
||||
@ -209,6 +214,10 @@ meta_display_show_osd (MetaDisplay *display,
|
||||
const gchar *icon_name,
|
||||
const gchar *message);
|
||||
|
||||
static void on_is_grabbed_changed (ClutterStage *stage,
|
||||
GParamSpec *pspec,
|
||||
MetaDisplay *display);
|
||||
|
||||
static MetaBackend *
|
||||
backend_from_display (MetaDisplay *display)
|
||||
{
|
||||
@ -917,6 +926,7 @@ meta_display_new (MetaContext *context,
|
||||
GError **error)
|
||||
{
|
||||
MetaBackend *backend = meta_context_get_backend (context);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
MetaDisplay *display;
|
||||
MetaDisplayPrivate *priv;
|
||||
guint32 timestamp;
|
||||
@ -1091,6 +1101,8 @@ meta_display_new (MetaContext *context,
|
||||
meta_display_unset_input_focus (display, timestamp);
|
||||
#endif
|
||||
|
||||
g_signal_connect (stage, "notify::is-grabbed",
|
||||
G_CALLBACK (on_is_grabbed_changed), display);
|
||||
|
||||
display->sound_player = g_object_new (META_TYPE_SOUND_PLAYER, NULL);
|
||||
|
||||
@ -1315,6 +1327,52 @@ meta_display_windows_are_interactable (MetaDisplay *display)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_is_grabbed_changed (ClutterStage *stage,
|
||||
GParamSpec *pspec,
|
||||
MetaDisplay *display)
|
||||
{
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
|
||||
if (!priv->focus_on_grab_dismissed.window)
|
||||
return;
|
||||
|
||||
meta_window_focus (priv->focus_on_grab_dismissed.window, META_CURRENT_TIME);
|
||||
|
||||
g_clear_signal_handler (&priv->focus_on_grab_dismissed.unmanaging_handler_id,
|
||||
priv->focus_on_grab_dismissed.window);
|
||||
priv->focus_on_grab_dismissed.window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
focus_on_grab_dismissed_unmanaging_cb (MetaWindow *window,
|
||||
MetaDisplay *display)
|
||||
{
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (priv->focus_on_grab_dismissed.window == window);
|
||||
|
||||
g_clear_signal_handler (&priv->focus_on_grab_dismissed.unmanaging_handler_id,
|
||||
priv->focus_on_grab_dismissed.window);
|
||||
priv->focus_on_grab_dismissed.window = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_queue_focus (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
|
||||
g_clear_signal_handler (&priv->focus_on_grab_dismissed.unmanaging_handler_id,
|
||||
priv->focus_on_grab_dismissed.window);
|
||||
|
||||
priv->focus_on_grab_dismissed.window = window;
|
||||
priv->focus_on_grab_dismissed.unmanaging_handler_id =
|
||||
g_signal_connect (window, "unmanaging",
|
||||
G_CALLBACK (focus_on_grab_dismissed_unmanaging_cb),
|
||||
display);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_xserver_time_is_before:
|
||||
* @display: a #MetaDisplay
|
||||
|
@ -1939,15 +1939,6 @@ window_state_on_map (MetaWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do not focus window on map if input is already taken by the
|
||||
* compositor.
|
||||
*/
|
||||
if (!meta_display_windows_are_interactable (window->display))
|
||||
{
|
||||
*takes_focus = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* When strict focus mode is enabled, prevent new windows from taking
|
||||
* focus unless they are ancestors to the transient.
|
||||
*/
|
||||
@ -2262,7 +2253,10 @@ meta_window_show (MetaWindow *window)
|
||||
|
||||
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
||||
|
||||
meta_window_focus (window, timestamp);
|
||||
if (meta_display_windows_are_interactable (window->display))
|
||||
meta_window_focus (window, timestamp);
|
||||
else
|
||||
meta_display_queue_focus (window->display, window);
|
||||
}
|
||||
else if (display->x11_display)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user