summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2013-04-29 19:25:21 +0200
committerMatthias Clasen <mclasen@redhat.com>2013-05-12 21:17:01 -0400
commita33f0ff839641cb897a457aa9b7dabaf22a0aaf6 (patch)
tree21b5929bc18cd3af7de3a53ba34c51089a9222f5
parent8fcfbc179c5741104a725dc2161d9a6c5bdd5350 (diff)
downloadgtk+-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.c20
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;