diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2013-04-29 19:25:21 +0200 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2013-05-12 21:17:01 -0400 |
commit | a33f0ff839641cb897a457aa9b7dabaf22a0aaf6 (patch) | |
tree | 21b5929bc18cd3af7de3a53ba34c51089a9222f5 | |
parent | 8fcfbc179c5741104a725dc2161d9a6c5bdd5350 (diff) | |
download | gtk+-a33f0ff839641cb897a457aa9b7dabaf22a0aaf6.tar.gz |
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
-rw-r--r-- | gtk/gtktooltip.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c index aba9ffb38a..0914641c5d 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; |