1 #include <gtk/gtk.h>
2
3 static void
check_finalized(gpointer data,GObject * where_the_object_was)4 check_finalized (gpointer data,
5 GObject *where_the_object_was)
6 {
7 gboolean *did_finalize = (gboolean *)data;
8
9 *did_finalize = TRUE;
10 }
11
12 static void
popover(void)13 popover (void)
14 {
15 GtkWidget *button = gtk_menu_button_new ();
16 GtkWidget *p = gtk_popover_new ();
17 gboolean finalized = FALSE;
18
19 gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), p);
20
21 /* GtkButton is a normal widget and thus floating */
22 g_assert_true (g_object_is_floating (button));
23 /* GtkPopver sinks itself */
24 g_assert_true (!g_object_is_floating (p));
25
26 g_object_weak_ref (G_OBJECT (p), check_finalized, &finalized);
27
28 g_object_ref_sink (button);
29 g_object_unref (button);
30 /* We do NOT unref p since the only reference held to it gets
31 * removed when the button gets disposed. */
32 g_assert_true (finalized);
33 }
34
35 static void
popover2(void)36 popover2 (void)
37 {
38 GtkWidget *button = gtk_menu_button_new ();
39 GtkWidget *p = gtk_popover_new ();
40 gboolean finalized = FALSE;
41
42 gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), p);
43
44 g_assert_true (g_object_is_floating (button));
45 g_assert_true (!g_object_is_floating (p));
46
47 g_object_weak_ref (G_OBJECT (p), check_finalized, &finalized);
48
49 g_object_ref_sink (button);
50
51 gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), NULL);
52
53 g_assert_true (finalized);
54
55 g_object_unref (button);
56 }
57
58 static void
filechooserwidget(void)59 filechooserwidget (void)
60 {
61 /* We use GtkFileChooserWidget simply because it's a complex widget, that's it. */
62 GtkWidget *w = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
63 gboolean finalized = FALSE;
64
65 g_assert_true (g_object_is_floating (w));
66 g_object_ref_sink (w);
67 g_object_weak_ref (G_OBJECT (w), check_finalized, &finalized);
68
69 g_object_unref (w);
70
71 g_assert_true (finalized);
72 }
73
74 static void
window(void)75 window (void)
76 {
77 GtkWidget *w = gtk_window_new ();
78 gboolean finalized = FALSE;
79
80 /* GTK holds a ref */
81 g_assert_true (!g_object_is_floating (w));
82 g_object_weak_ref (G_OBJECT (w), check_finalized, &finalized);
83
84 gtk_window_destroy (GTK_WINDOW (w));
85
86 g_assert_true (finalized);
87 }
88
89 int
main(int argc,char ** argv)90 main (int argc, char **argv)
91 {
92 (g_test_init) (&argc, &argv, NULL);
93 gtk_init ();
94
95 g_test_add_func ("/gtk/widget-refcount/popover", popover);
96 g_test_add_func ("/gtk/widget-refcount/popover2", popover2);
97 g_test_add_func ("/gtk/widget-refcount/filechoosewidget", filechooserwidget);
98 g_test_add_func ("/gtk/widget-refcount/window", window);
99
100 return g_test_run ();
101 }
102