diff --git a/src/core/events.c b/src/core/events.c index a99b99dc1..a6f4a502a 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -47,6 +47,18 @@ (e)->type == CLUTTER_TOUCH_END || \ (e)->type == CLUTTER_TOUCH_CANCEL) +#define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \ + (e)->type == CLUTTER_KEY_RELEASE) + +static gboolean +stage_has_key_focus (void) +{ + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + + return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == stage; +} + static MetaWindow * get_window_for_event (MetaDisplay *display, const ClutterEvent *event) @@ -58,14 +70,8 @@ get_window_for_event (MetaDisplay *display, ClutterActor *source; /* Always use the key focused window for key events. */ - switch (event->type) - { - case CLUTTER_KEY_PRESS: - case CLUTTER_KEY_RELEASE: - return display->focus_window; - default: - break; - } + if (IS_KEY_EVENT (event)) + return stage_has_key_focus () ? display->focus_window : NULL; source = clutter_event_get_source (event); if (META_IS_SURFACE_ACTOR (source)) @@ -299,6 +305,18 @@ meta_display_handle_event (MetaDisplay *display, goto out; } + /* Do not pass keyboard events to Wayland if key focus is not on the + * stage in normal mode (e.g. during keynav in the panel) + */ + if (display->event_route == META_EVENT_ROUTE_NORMAL) + { + if (IS_KEY_EVENT (event) && !stage_has_key_focus ()) + { + bypass_wayland = TRUE; + goto out; + } + } + if (display->current_pad_osd) { bypass_wayland = TRUE; diff --git a/src/core/window.c b/src/core/window.c index 61f0a60ee..2f72ca2f6 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4300,6 +4300,13 @@ meta_window_focus (MetaWindow *window, META_WINDOW_GET_CLASS (window)->focus (window, timestamp); + if (window->display->event_route == META_EVENT_ROUTE_NORMAL) + { + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + clutter_stage_set_key_focus (stage, NULL); + } + if (window->wm_state_demands_attention) meta_window_unset_demands_attention(window);