[gtk+] Find tooltip/dnd widget running through container children in inverse order



commit a33f0ff839641cb897a457aa9b7dabaf22a0aaf6
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Apr 29 19:25:21 2013 +0200

    Find tooltip/dnd widget running through container children in inverse order
    
    Usually, educated GtkContainers' forall() implementation returns children
    in an order that's safe for the default draw() implementation in GtkContainer.
    So for widgets with some stacking notions (eg. GtkOverlay),
    _gtk_widget_find_at_coords() needs to recurse within containers in reverse
    order so it finds the topmost widget.
    
    As this function is used in both tooltips and DnD code, this improves behavior
    of "floating" widgets wrt those two. This could for example be seen in the
    "Transparent" GTK+ demo, where dropping text on the entry results on the text
    going to the textview.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=699239

 gtk/gtktooltip.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c
index aba9ffb..0914641 100644
--- a/gtk/gtktooltip.c
+++ b/gtk/gtktooltip.c
@@ -692,6 +692,15 @@ struct ChildLocation
 };
 
 static void
+prepend_and_ref_widget (GtkWidget *widget,
+                        gpointer   data)
+{
+  GSList **slist_p = data;
+
+  *slist_p = g_slist_prepend (*slist_p, g_object_ref (widget));
+}
+
+static void
 child_location_foreach (GtkWidget *child,
                        gpointer   data)
 {
@@ -735,6 +744,7 @@ child_location_foreach (GtkWidget *child,
          if (GTK_IS_CONTAINER (child))
            {
              struct ChildLocation tmp = { NULL, NULL, 0, 0 };
+              GSList *children = NULL, *tmp_list;
 
              /* Take (x, y) relative the child's allocation and
               * recurse.
@@ -744,12 +754,20 @@ child_location_foreach (GtkWidget *child,
              tmp.container = child;
 
              gtk_container_forall (GTK_CONTAINER (child),
-                                   child_location_foreach, &tmp);
+                                   prepend_and_ref_widget, &children);
+
+              for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
+                {
+                  child_location_foreach (tmp_list->data, &tmp);
+                  g_object_unref (tmp_list->data);
+                }
 
              if (tmp.child)
                child_loc->child = tmp.child;
              else
                child_loc->child = child;
+
+              g_slist_free (children);
            }
          else
            child_loc->child = child;


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