[gtk/wip/carlosg/input-cleanups: 12/26] gtkwidget: Avoid poking surfaces and events in gtk_widget_list_devices()



commit f401b05e7b697c7eafe5e4436830e0229e58aecd
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Jun 24 11:14:52 2020 +0200

    gtkwidget: Avoid poking surfaces and events in gtk_widget_list_devices()
    
    This got stuck in ancient times when widgets were windowed, so the devices
    in a window to know the devices in that widget would pan out. We do only
    want here the devices that are inside the widget, not spread over the
    surface, so rewrite this helper function to poke the toplevel foci, and
    look they are contained inside the widget.

 gtk/gtkwidget.c        | 40 ++++++----------------------------------
 gtk/gtkwindow.c        | 26 ++++++++++++++++++++++++++
 gtk/gtkwindowprivate.h |  3 +++
 3 files changed, 35 insertions(+), 34 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 8cb889fef2..0093abb031 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -7548,22 +7548,12 @@ gtk_widget_adjust_baseline_request (GtkWidget *widget,
     }
 }
 
-static gboolean
-is_my_surface (GtkWidget *widget,
-              GdkSurface *surface)
-{
-  if (!surface)
-    return FALSE;
-
-  return gdk_surface_get_widget (surface) == widget;
-}
-
 /*
  * _gtk_widget_list_devices:
  * @widget: a #GtkWidget
  *
  * Returns the list of pointer #GdkDevices that are currently
- * on top of any surface belonging to @widget. Free the list
+ * on top of @widget. Free the list
  * with g_free(), the elements are owned by GTK+ and must
  * not be freed.
  */
@@ -7571,11 +7561,7 @@ GdkDevice **
 _gtk_widget_list_devices (GtkWidget *widget,
                           guint     *out_n_devices)
 {
-  GPtrArray *result;
-  GdkSeat *seat;
-  GList *devices;
-  GList *l;
-  GdkDevice *device;
+  GtkRoot *root;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
   g_assert (out_n_devices);
@@ -7586,29 +7572,15 @@ _gtk_widget_list_devices (GtkWidget *widget,
       return NULL;
     }
 
-  seat = gdk_display_get_default_seat (_gtk_widget_get_display (widget));
-  if (!seat)
+  root = gtk_widget_get_root (widget);
+  if (!root)
     {
       *out_n_devices = 0;
       return NULL;
     }
-  device = gdk_seat_get_pointer (seat);
-
-  result = g_ptr_array_new ();
-  if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
-    g_ptr_array_add (result, device);
-
-  devices = gdk_seat_get_physical_devices (seat, GDK_SEAT_CAPABILITY_ALL_POINTING);
-  for (l = devices; l; l = l->next)
-    {
-      device = l->data;
-      if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
-        g_ptr_array_add (result, device);
-    }
-  g_list_free (devices);
 
-  *out_n_devices = result->len;
-  return (GdkDevice **)g_ptr_array_free (result, FALSE);
+  return gtk_window_get_foci_on_widget (GTK_WINDOW (root),
+                                        widget, out_n_devices);
 }
 
 /*
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 206def4e89..c9d3bfd33f 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -7195,3 +7195,29 @@ gtk_window_destroy (GtkWindow *window)
 
   g_object_unref (window);
 }
+
+GdkDevice**
+gtk_window_get_foci_on_widget (GtkWindow *window,
+                               GtkWidget *widget,
+                               guint     *n_devices)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GPtrArray *array = g_ptr_array_new ();
+  GList *l;
+
+  for (l = priv->foci; l; l = l->next)
+    {
+      GtkPointerFocus *focus = l->data;
+      GtkWidget *target;
+
+      target = gtk_pointer_focus_get_effective_target (focus);
+
+      if (target == widget || gtk_widget_is_ancestor (target, widget))
+        g_ptr_array_add (array, focus->device);
+    }
+
+  if (n_devices)
+    *n_devices = array->len;
+
+  return (GdkDevice**) g_ptr_array_free (array, FALSE);
+}
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 527e078057..14a3f8617c 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -124,6 +124,9 @@ GtkWidget *      gtk_window_pick_popover (GtkWindow   *window,
                                           double       x,
                                           double       y,
                                           GtkPickFlags flags);
+GdkDevice** gtk_window_get_foci_on_widget (GtkWindow *window,
+                                           GtkWidget *widget,
+                                           guint     *n_devices);
 
 G_END_DECLS
 


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