From fc42a0696e9b71e4012bf43852facb6446c6cd77 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 9 May 2020 19:23:29 -0400 Subject: [PATCH] Add a test for refcounts under reordering It turns out that we have a ref leak at the very core of our dom model :( gtk_widget_insert_before/after leak a reference if the widget was already under the same parent. This is something that GtkBox frequently does. It shows up e.g. when packing widgets at the end in a headerbar. --- testsuite/gtk/widgetorder.c | 41 ++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/testsuite/gtk/widgetorder.c b/testsuite/gtk/widgetorder.c index 01a885a6df..c0ffafaeac 100644 --- a/testsuite/gtk/widgetorder.c +++ b/testsuite/gtk/widgetorder.c @@ -545,7 +545,45 @@ no_loop (void) g_assert (gtk_widget_get_next_sibling (l2) == NULL); } -int main (int argc, char **argv) +static void +reorder_refcount (void) +{ + GtkWidget *p = gtk_label_new (""); + GtkWidget *l1 = gtk_label_new (""); + GtkWidget *l2 = gtk_label_new (""); + + g_assert (g_object_is_floating (l1)); + g_assert (G_OBJECT (l1)->ref_count == 1); + + gtk_widget_set_parent (l1, p); + + g_assert (!g_object_is_floating (l1)); + g_assert (G_OBJECT (l1)->ref_count == 1); + + g_assert (g_object_is_floating (l2)); + g_assert (G_OBJECT (l2)->ref_count == 1); + + gtk_widget_set_parent (l2, p); + + g_assert (!g_object_is_floating (l2)); + g_assert (G_OBJECT (l2)->ref_count == 1); + + g_assert (gtk_widget_get_next_sibling (l1) == l2); + + gtk_widget_insert_before (l2, p, l1); + + g_assert (gtk_widget_get_prev_sibling (l1) == l2); + + g_assert (G_OBJECT (l1)->ref_count == 1); + g_assert (G_OBJECT (l2)->ref_count == 1); + + gtk_widget_unparent (l1); + gtk_widget_unparent (l2); + g_object_unref (g_object_ref_sink (p)); +} + +int +main (int argc, char **argv) { gtk_init (); g_test_init (&argc, &argv, NULL); @@ -565,6 +603,7 @@ int main (int argc, char **argv) g_test_add_func ("/widgetorder/same-after", same_after); g_test_add_func ("/widgetorder/same-before", same_before); g_test_add_func ("/widgetorder/no-loop", no_loop); + g_test_add_func ("/widgetorder/reorder-refcount", reorder_refcount); return g_test_run (); }