diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2016-08-09 17:10:15 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2016-10-17 16:22:00 +0100 |
commit | 11151379df75ed536d9a5e7e81dc6acf200580b8 (patch) | |
tree | acb6e1574cbae52a995897ba11b340fed132f128 | |
parent | fc15f027ec2af82a4502f672b873f8082c626916 (diff) | |
download | gtk+-11151379df75ed536d9a5e7e81dc6acf200580b8.tar.gz |
gtk: Sort children by window depth when rendering
This makes popovers pop over instead of under.
-rw-r--r-- | gtk/gtkcontainer.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index eb47c3d675..54e3fbfbba 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -3402,6 +3402,7 @@ typedef struct { GtkContainer *container; GskRenderer *renderer; GskRenderNode *parent; + GArray *child_infos; } RenderData; static void @@ -3463,16 +3464,55 @@ propagate_render_node (GtkWidget *child, gsk_render_node_unref (node); } +static void +collect_child_infos (GtkWidget *widget, + gpointer data_) +{ + RenderData *data = data_; + ChildOrderInfo info; + GList *siblings; + GdkWindow *window; + + info.child = widget; + info.window_depth = G_MAXINT; + + window = _gtk_widget_get_window (widget); + if (window == NULL) + return; + + if (window != gtk_widget_get_window (GTK_WIDGET (data->container))) + { + siblings = gdk_window_peek_children (gdk_window_get_parent (window)); + info.window_depth = g_list_index (siblings, window); + } + + g_array_append_val (data->child_infos, info); +} + + void gtk_container_propagate_render_node (GtkContainer *container, GskRenderer *renderer, GskRenderNode *parent_node) { - RenderData data = { - container, - renderer, - parent_node - }; + RenderData data; + int i; + + data.container = container; + data.renderer = renderer; + data.parent = parent_node; + data.child_infos = g_array_new (FALSE, TRUE, sizeof (ChildOrderInfo)); + + gtk_container_forall (container, collect_child_infos, &data); + + g_array_sort (data.child_infos, compare_children_for_draw); + + for (i = 0; i < data.child_infos->len; i++) + { + ChildOrderInfo *info = &g_array_index (data.child_infos, ChildOrderInfo, i); + + propagate_render_node (info->child, &data); + } - gtk_container_forall (container, propagate_render_node, &data); + g_array_free (data.child_infos, TRUE); } |