diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index eb8dca7af..6fe6fadb9 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -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) { diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h index a6064e11c..fac2d6467 100644 --- a/src/meta/compositor-mutter.h +++ b/src/meta/compositor-mutter.h @@ -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); diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index b0ed65ec9..0e8820d88 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -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); diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 4e98203dd..17be6f4f2 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -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)