[mutter] wayland/pointer: Set focus to NULL when the cursor is hidden



commit a2a8f0cdaa978f25c69b7a1611d4c2d4cbfc06fb
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Sat Feb 16 22:48:17 2019 +0100

    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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]