widget: Make gtk_widget_pick() really slow
authorBenjamin Otte <otte@redhat.com>
Sun, 5 Nov 2017 03:05:55 +0000 (04:05 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 5 Nov 2017 04:13:17 +0000 (05:13 +0100)
We cannot fast-track picking by using gtk_widget_contains(). Child
widgets may extend their parent using ie negative margins.

This is not just a theoretical concern, this is what's happening right
now with GtkScale's sliders relative to the trough.

The problem is that we now iterate through all widgets, even when they
aren't anywhere near the mouse pointer. So essentially every pick
operation is now guaranteed O(N_WIDGETS) which used to be the worst case
that pretty much never happened.

gtk/gtkwidget.c

index 69dfe6d8ae74d01b4255e4ca907d3c66ccbd1b07..5d41c2d35545286ac7da78437fcb996e9bba306a 100644 (file)
@@ -955,9 +955,6 @@ gtk_widget_real_pick (GtkWidget *widget,
 {
   GtkWidget *child;
 
-  if (!gtk_widget_contains (widget, x, y))
-    return NULL;
-
   for (child = _gtk_widget_get_last_child (widget);
        child;
        child = _gtk_widget_get_prev_sibling (child))
@@ -972,6 +969,9 @@ gtk_widget_real_pick (GtkWidget *widget,
         return picked;
     }
 
+  if (!gtk_widget_contains (widget, x, y))
+    return NULL;
+
   return widget;
 }
 
@@ -13186,6 +13186,11 @@ gtk_widget_pick (GtkWidget *widget,
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
+  if (gtk_widget_get_pass_through (widget) ||
+      !gtk_widget_is_sensitive (widget) ||
+      !gtk_widget_is_drawable (widget))
+    return NULL;
+
   return GTK_WIDGET_GET_CLASS (widget)->pick (widget, x, y);
 }