1 | #include <gtk/gtk.h> |
2 | |
3 | static void |
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 |
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), popover: 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), notify: check_finalized, data: &finalized); |
27 | |
28 | g_object_ref_sink (button); |
29 | g_object_unref (object: 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 |
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), popover: 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), notify: check_finalized, data: &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 (object: button); |
56 | } |
57 | |
58 | static 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 (action: 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), notify: check_finalized, data: &finalized); |
68 | |
69 | g_object_unref (object: w); |
70 | |
71 | g_assert_true (finalized); |
72 | } |
73 | |
74 | static 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), notify: check_finalized, data: &finalized); |
83 | |
84 | gtk_window_destroy (GTK_WINDOW (w)); |
85 | |
86 | g_assert_true (finalized); |
87 | } |
88 | |
89 | int |
90 | main (int argc, char **argv) |
91 | { |
92 | (g_test_init) (argc: &argc, argv: &argv, NULL); |
93 | gtk_init (); |
94 | |
95 | g_test_add_func (testpath: "/gtk/widget-refcount/popover" , test_func: popover); |
96 | g_test_add_func (testpath: "/gtk/widget-refcount/popover2" , test_func: popover2); |
97 | g_test_add_func (testpath: "/gtk/widget-refcount/filechoosewidget" , test_func: filechooserwidget); |
98 | g_test_add_func (testpath: "/gtk/widget-refcount/window" , test_func: window); |
99 | |
100 | return g_test_run (); |
101 | } |
102 | |