From a2a8f0cdaa978f25c69b7a1611d4c2d4cbfc06fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Sat, 16 Feb 2019 22:48:17 +0100 Subject: [PATCH] wayland/pointer: Set focus to NULL when the cursor is hidden This is important when using a touchscreen or stylus instead of a mouse or touchpad. If the cursor only gets hidden and the focus stays the same, the window will still send hover events to the UI element under the cursor causing unexpected distractions while interacting with the touchscreen. Fix this by emitting a visibility-changed signal from the cursor tracker which then triggers a focus surface sync and always set the focus surface to NULL when it's synced while the cursor is hidden. https://gitlab.gnome.org/GNOME/mutter/merge_requests/448 --- src/backends/meta-cursor-tracker.c | 10 ++++++++++ src/wayland/meta-wayland-pointer.c | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 88607bf4d..74481dd1c 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -50,6 +50,7 @@ enum { CURSOR_CHANGED, CURSOR_MOVED, + VISIBILITY_CHANGED, LAST_SIGNAL }; @@ -173,6 +174,13 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) G_TYPE_NONE, 2, G_TYPE_FLOAT, G_TYPE_FLOAT); + + signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } /** @@ -433,6 +441,8 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, tracker->is_showing = visible; sync_cursor (tracker); + + g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0); } MetaCursorSprite * diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 3ace7b3e4..c6c050f89 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -226,6 +226,14 @@ static void sync_focus_surface (MetaWaylandPointer *pointer) { MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + + if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker)) + { + meta_wayland_pointer_set_focus (pointer, NULL); + return; + } switch (display->event_route) { @@ -473,6 +481,13 @@ meta_wayland_pointer_on_cursor_changed (MetaCursorTracker *cursor_tracker, meta_wayland_surface_update_outputs (pointer->cursor_surface); } +static void +meta_wayland_pointer_on_cursor_visibility_changed (MetaCursorTracker *cursor_tracker, + MetaWaylandPointer *pointer) +{ + sync_focus_surface (pointer); +} + void meta_wayland_pointer_enable (MetaWaylandPointer *pointer) { @@ -493,6 +508,11 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer) "cursor-changed", G_CALLBACK (meta_wayland_pointer_on_cursor_changed), pointer); + + g_signal_connect (cursor_tracker, + "visibility-changed", + G_CALLBACK (meta_wayland_pointer_on_cursor_visibility_changed), + pointer); } void @@ -505,6 +525,10 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) (gpointer) meta_wayland_pointer_on_cursor_changed, pointer); + g_signal_handlers_disconnect_by_func (cursor_tracker, + meta_wayland_pointer_on_cursor_visibility_changed, + pointer); + if (pointer->cursor_surface && pointer->cursor_surface_destroy_id) { g_signal_handler_disconnect (pointer->cursor_surface,