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
This commit is contained in:
Carlos Garnacho 2013-04-29 19:25:21 +02:00 committed by Matthias Clasen
parent 8fcfbc179c
commit a33f0ff839

View File

@ -691,6 +691,15 @@ struct ChildLocation
gint y;
};
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;