[gtk+] Warn about recursively calling size req wrappers on the same object and orientation



commit 8960d64cc687cb4c98381ff5bd7a6d04be9dde1d
Author: Havoc Pennington <hp pobox com>
Date:   Sun Sep 5 02:48:36 2010 -0400

    Warn about recursively calling size req wrappers on the same object and orientation
    
    We are not re-entrant and there is no reason for widgets to
    do this, most likely they'll just get unexpected bugs because
    the wrappers may modify the request.
    
    Computing the request should logically rely only on the
    widget itself, not on any adjustments caused by set_size_request,
    size groups, and so forth.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=628829

 gtk/gtksizerequest.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c
index 7c67c7e..827265e 100644
--- a/gtk/gtksizerequest.c
+++ b/gtk/gtksizerequest.c
@@ -155,6 +155,57 @@ do_size_request (GtkWidget      *widget,
   g_signal_emit_by_name (widget, "size-request", requisition);
 }
 
+#ifndef G_DISABLE_CHECKS
+static GQuark recursion_check_quark = 0;
+#endif /* G_DISABLE_CHECKS */
+
+static void
+push_recursion_check (GtkSizeRequest  *request,
+                      GtkSizeGroupMode orientation,
+                      gint             for_size)
+{
+#ifndef G_DISABLE_CHECKS
+  const char *previous_method;
+  const char *method;
+
+  if (recursion_check_quark == 0)
+    recursion_check_quark = g_quark_from_static_string ("gtk-size-request-in-progress");
+
+  previous_method = g_object_get_qdata (G_OBJECT (request), recursion_check_quark);
+
+  if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
+    {
+      method = for_size < 0 ? "get_width" : "get_width_for_height";
+    }
+  else
+    {
+      method = for_size < 0 ? "get_height" : "get_height_for_width";
+    }
+
+  if (previous_method != NULL)
+    {
+      g_warning ("%s %p: widget tried to gtk_size_request_%s inside "
+                 " GtkSizeRequest::%s implementation. "
+                 "Should just invoke GTK_SIZE_REQUEST_GET_IFACE(widget)->%s "
+                 "directly rather than using gtk_size_request_%s",
+                 G_OBJECT_TYPE_NAME (request), request,
+                 method, previous_method,
+                 method, method);
+    }
+
+  g_object_set_qdata (G_OBJECT (request), recursion_check_quark, (char*) method);
+#endif /* G_DISABLE_CHECKS */
+}
+
+static void
+pop_recursion_check (GtkSizeRequest  *request,
+                     GtkSizeGroupMode orientation)
+{
+#ifndef G_DISABLE_CHECKS
+  g_object_set_qdata (G_OBJECT (request), recursion_check_quark, NULL);
+#endif
+}
+
 static void
 compute_size_for_orientation (GtkSizeRequest    *request,
                               GtkSizeGroupMode   orientation,
@@ -207,6 +258,7 @@ compute_size_for_orientation (GtkSizeRequest    *request,
       /* Unconditional size request runs but is often unhandled. */
       do_size_request (widget, &requisition);
 
+      push_recursion_check (request, orientation, for_size);
       if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
         {
           requisition_size = requisition.width;
@@ -227,6 +279,7 @@ compute_size_for_orientation (GtkSizeRequest    *request,
             GTK_SIZE_REQUEST_GET_IFACE (request)->get_height_for_width (request, for_size, 
 									&min_size, &nat_size);
         }
+      pop_recursion_check (request, orientation);
 
       if (min_size > nat_size)
         {



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