[mutter] events: Only pass key events to Wayland if focus is on the stage
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] events: Only pass key events to Wayland if focus is on the stage
- Date: Mon, 29 Aug 2016 23:14:55 +0000 (UTC)
commit 89f6fdce5dbb4c4aa0b4efa5fc3deeee460f69d0
Author: Florian Müllner <fmuellner gnome org>
Date: Thu Mar 10 17:51:46 2016 +0100
events: Only pass key events to Wayland if focus is on the stage
Even without a compositor grab, key events may still be expected to
be processed by the compositor and not applications, for instance
when using ctrl-alt-tab to keynav in the top bar. On X11, focus is
moved to the stage window in that case, so that events are processed
before they are dispatched by the window manager. On wayland, we need
to handle this case ourselves, so make sure to not pass key events to
wayland in that case, and move the key focus back to the stage when
appropriate.
https://bugzilla.gnome.org/show_bug.cgi?id=758167
src/core/events.c | 34 ++++++++++++++++++++++++++--------
src/core/window.c | 7 +++++++
2 files changed, 33 insertions(+), 8 deletions(-)
---
diff --git a/src/core/events.c b/src/core/events.c
index a99b99d..a6f4a50 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 61f0a60..2f72ca2 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]