x11: Adopt code to focus stage window on Clutter key focus

We currently offer the mechanism for GNOME Shell to implement, and
while this is not exercised often (our entries are typically surrounded
by a ClutterGrab ensuring key events, so this is reserved to grab-less
entries, probably there are some in extensions), this is arguably
something Mutter should cover by itself without GNOME Shell guidance.

This is only necessary on the X11 backend, although it is conceptually
more tied to the MetaX11Display connection, so perform the focus
tracking there only if not running as a Wayland compositor (i.e. --x11).

This avoids the only case where the low-level
meta_x11_display_set_input_focus_xwindow() function is used, or rather
makes it completely a MetaX11Display implementation detail, leaving
only the MetaDisplay API as the high-level entry points to handle
window key focus.

The public API that allowed GNOME Shell to implement these mechanisms
is also gone in this commit.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3269>
This commit is contained in:
Carlos Garnacho 2023-09-05 00:54:04 +02:00 committed by Georges Basile Stavracas Neto
parent 3b46b4a099
commit 4179679239
4 changed files with 79 additions and 59 deletions

View File

@ -330,53 +330,6 @@ meta_get_window_actors (MetaDisplay *display)
return priv->windows;
}
void
meta_focus_stage_window (MetaDisplay *display,
guint32 timestamp)
{
#ifdef HAVE_X11_CLIENT
ClutterStage *stage;
Window window;
stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
if (!stage)
return;
window = meta_x11_get_stage_window (stage);
if (window == None)
return;
meta_x11_display_set_input_focus_xwindow (display->x11_display,
window,
timestamp);
#endif
}
gboolean
meta_stage_is_focused (MetaDisplay *display)
{
if (meta_is_wayland_compositor ())
return TRUE;
#ifdef HAVE_X11_CLIENT
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
Window window;
if (!stage)
return FALSE;
window = meta_x11_get_stage_window (stage);
if (window == None)
return FALSE;
return (display->x11_display->focus_xwindow == window);
#else
return FALSE;
#endif
}
void
meta_compositor_grab_begin (MetaCompositor *compositor)
{

View File

@ -49,10 +49,3 @@ void meta_disable_unredirect_for_display (MetaDisplay *display);
META_EXPORT
void meta_enable_unredirect_for_display (MetaDisplay *display);
META_EXPORT
void meta_focus_stage_window (MetaDisplay *display,
guint32 timestamp);
META_EXPORT
gboolean meta_stage_is_focused (MetaDisplay *display);

View File

@ -232,10 +232,6 @@ void meta_x11_display_create_guard_window (MetaX11Display *x11_display);
guint32 meta_x11_display_get_current_time_roundtrip (MetaX11Display *x11_display);
void meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display,
Window window,
guint32 timestamp);
int meta_x11_display_logical_monitor_to_xinerama_index (MetaX11Display *x11_display,
MetaLogicalMonitor *logical_monitor);

View File

@ -105,6 +105,10 @@ static void meta_x11_display_init_frames_client (MetaX11Display *x11_display);
static void meta_x11_display_remove_cursor_later (MetaX11Display *x11_display);
static void meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display,
Window window,
guint32 timestamp);
static MetaBackend *
backend_from_x11_display (MetaX11Display *x11_display)
{
@ -1123,6 +1127,61 @@ on_frames_client_died (GObject *source,
}
}
#ifdef HAVE_X11
static gboolean
stage_is_focused (MetaX11Display *x11_display)
{
MetaDisplay *display = x11_display->display;
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
Window xwindow = meta_x11_get_stage_window (stage);
return x11_display->focus_xwindow == xwindow;
}
static void
on_focus_window_changed (MetaX11Display *x11_display)
{
MetaDisplay *display = x11_display->display;
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
if (!stage_is_focused (x11_display))
clutter_stage_set_key_focus (stage, NULL);
}
static void
on_stage_key_focus_changed (MetaX11Display *x11_display)
{
MetaDisplay *display = x11_display->display;
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
ClutterActor *key_focus;
uint32_t timestamp;
gboolean has_actor_focus, has_stage_focus;
key_focus = clutter_stage_get_key_focus (stage);
has_actor_focus = key_focus != CLUTTER_ACTOR (stage);
has_stage_focus = stage_is_focused (x11_display);
if (has_actor_focus == has_stage_focus)
return;
timestamp = meta_display_get_current_time_roundtrip (display);
if (has_actor_focus)
{
Window xwindow;
xwindow = meta_x11_get_stage_window (stage);
meta_x11_display_set_input_focus_xwindow (display->x11_display,
xwindow,
timestamp);
}
else
{
meta_display_focus_default_window (display, timestamp);
}
}
#endif
static void
meta_x11_display_init_frames_client (MetaX11Display *x11_display)
{
@ -1274,6 +1333,25 @@ meta_x11_display_new (MetaDisplay *display,
G_CONNECT_SWAPPED);
update_cursor_theme (x11_display);
#ifdef HAVE_XWAYLAND
if (!meta_is_wayland_compositor ())
#endif
{
ClutterStage *stage =
CLUTTER_STAGE (meta_get_stage_for_display (display));
g_signal_connect_object (display,
"notify::focus-window",
G_CALLBACK (on_focus_window_changed),
x11_display,
G_CONNECT_SWAPPED);
g_signal_connect_object (stage,
"notify::key-focus",
G_CALLBACK (on_stage_key_focus_changed),
x11_display,
G_CONNECT_SWAPPED);
}
x11_display->xids = g_hash_table_new (meta_unsigned_long_hash,
meta_unsigned_long_equal);
x11_display->alarms = g_hash_table_new (meta_unsigned_long_hash,
@ -2032,7 +2110,7 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display,
meta_x11_error_trap_pop (x11_display);
}
void
static void
meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display,
Window window,
guint32 timestamp)