[gtk/wip/carlosg/input-fixes: 6/7] gdk/wayland: Ensure to clean up stale touchpoint data on surface destroy



commit 41b7f03d552f6ddc45c6a3ee099ac132d05d6adb
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Apr 24 23:11:00 2020 +0200

    gdk/wayland: Ensure to clean up stale touchpoint data on surface destroy
    
    If the wl_surface receiving touch events is destroyed, we will get no
    wl_touch.up event to remove the touchpoint from our internal accounting.
    Check for this, and drop touchpoints happening in surfaces that do
    disappear during operation.

 gdk/wayland/gdkdevice-wayland.c  | 16 ++++++++++++++++
 gdk/wayland/gdkseat-wayland.h    |  3 +++
 gdk/wayland/gdksurface-wayland.c |  8 ++++++++
 3 files changed, 27 insertions(+)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 075a2a7c36..b30b1e63c7 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -2313,6 +2313,22 @@ gdk_wayland_seat_remove_touch (GdkWaylandSeat *seat,
   g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
 }
 
+void
+gdk_wayland_seat_clear_touchpoints (GdkWaylandSeat *seat,
+                                    GdkSurface     *surface)
+{
+  GHashTableIter iter;
+  GdkWaylandTouchData *touch;
+
+  g_hash_table_iter_init (&iter, seat->touches);
+
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch))
+    {
+      if (touch->surface == surface)
+        g_hash_table_iter_remove (&iter);
+    }
+}
+
 static void
 mimic_pointer_emulating_touch_info (GdkDevice           *device,
                                     GdkWaylandTouchData *touch)
diff --git a/gdk/wayland/gdkseat-wayland.h b/gdk/wayland/gdkseat-wayland.h
index eccc792817..711c597ae9 100644
--- a/gdk/wayland/gdkseat-wayland.h
+++ b/gdk/wayland/gdkseat-wayland.h
@@ -43,4 +43,7 @@ GType gdk_wayland_seat_get_type (void) G_GNUC_CONST;
 
 void gdk_wayland_seat_update_cursor_scale (GdkWaylandSeat *seat);
 
+void gdk_wayland_seat_clear_touchpoints (GdkWaylandSeat *seat,
+                                         GdkSurface     *surface);
+
 #endif /* __GDK_WAYLAND_SEAT_H__ */
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index c644608031..2bbc4ef40f 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -2683,6 +2683,14 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
 static void
 gdk_wayland_surface_hide (GdkSurface *surface)
 {
+  GdkSeat *seat;
+
+  seat = gdk_display_get_default_seat (surface->display);
+
+  if (surface->autohide)
+    gdk_seat_ungrab (seat);
+
+  gdk_wayland_seat_clear_touchpoints (GDK_WAYLAND_SEAT (seat), surface);
   gdk_wayland_surface_hide_surface (surface);
   _gdk_surface_clear_update_area (surface);
 }


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