GtkApplicationWindow: give up on handling dispose

Stop trying to deal with "theoretical possibilities".

We can't possibly continue to be a faithful GActionGroup implementation
across dispose because dispose has a side effect of removing everyone's
signal handlers.

The code that we ran after the dispose chainup to do all of the fancy
signal emulation was therefore dead.  The test that aimed to verify this
was buggy itself due to an uninitialised variable, so really, it never
worked at all.

We keep the re-ordering of the chainup from the original commit to avoid having
trouble with GtkActionMuxer and keep the checks in place that will prevent an
outright segfault in the case that someone else tries to use the interface
post-dispose.

https://bugzilla.gnome.org/show_bug.cgi?id=722189
This commit is contained in:
Ryan Lortie
2014-01-14 10:33:13 -05:00
parent 587f993444
commit bc3867eb85
3 changed files with 2 additions and 125 deletions

View File

@ -39,7 +39,6 @@ TEST_PROGS += \
floating \
grid \
gtkmenu \
gtkapplicationwindow \
keyhash \
listbox \
no-gtk-init \

View File

@ -1,81 +0,0 @@
#include <gtk/gtk.h>
static void
removed (GActionGroup *group,
const gchar *name,
gpointer user_data)
{
gboolean *was_removed = user_data;
*was_removed = TRUE;
}
static void
test_as_actiongroup (void)
{
GSimpleAction *action;
gboolean was_removed;
gpointer window;
gchar **list;
/* do a dummy round... */
window = g_object_ref_sink (g_object_new (GTK_TYPE_APPLICATION_WINDOW, NULL));
gtk_widget_destroy (window);
g_object_unref (window);
/* create a window, add an action */
window = g_object_ref_sink (g_object_new (GTK_TYPE_APPLICATION_WINDOW, NULL));
action = g_simple_action_new ("foo", NULL);
g_action_map_add_action (window, G_ACTION (action));
g_object_unref (action);
/* check which actions we have in the group */
list = g_action_group_list_actions (window);
g_assert_cmpstr (list[0], ==, "foo");
g_assert_cmpstr (list[1], ==, NULL);
g_strfreev (list);
/* make sure that destroying the window keeps our view of the actions
* consistent.
*/
g_signal_connect (window, "action-removed", G_CALLBACK (removed), &was_removed);
gtk_widget_destroy (window);
/* One of two things will have happened, depending on the
* implementation. Both are valid:
*
* - we received a signal that the action was removed when we
* destroyed the window; or
*
* - the action is still available.
*
* Make sure we're in one of those states.
*
* This additionally ensures that calling into methods on the window
* will continue to work after it has been destroy (and not segfault).
*/
list = g_action_group_list_actions (window);
if (was_removed == FALSE)
{
/* should still be here */
g_assert_cmpstr (list[0], ==, "foo");
g_assert_cmpstr (list[1], ==, NULL);
}
else
/* should be gone */
g_assert_cmpstr (list[0], ==, NULL);
g_object_unref (window);
g_strfreev (list);
}
int
main (int argc, char **argv)
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/gtkapplicationwindow/as-actiongroup", test_as_actiongroup);
return g_test_run ();
}