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