From 08f216e11f4098935caaf8f2ed80c6ac0de6bf2a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 19 Jun 2019 20:59:00 +0000 Subject: [PATCH] action muxer: Fix gtk_widget_get_action_group The documentation for gtk_widget_get_action_group and gtk_widget_list_prefixes states that both of these operate on all the action groups that are 'available' to the widget. Which means: they are meant to walk up the parent muxer chain. So do that. Add tests to verify the expected behavior. Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1396 --- gtk/gtkactionmuxer.c | 33 +++++++++-- testsuite/gtk/action.c | 122 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 150 insertions(+), 5 deletions(-) diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c index 40fc0c14c9..ee97cd294f 100644 --- a/gtk/gtkactionmuxer.c +++ b/gtk/gtkactionmuxer.c @@ -742,10 +742,32 @@ gtk_action_muxer_remove (GtkActionMuxer *muxer, } } +static void +gtk_action_muxer_append_prefixes (gpointer key, + gpointer value, + gpointer user_data) +{ + const gchar *prefix = key; + GArray *prefixes= user_data; + + g_array_append_val (prefixes, prefix); +} + const gchar ** gtk_action_muxer_list_prefixes (GtkActionMuxer *muxer) { - return (const gchar **) g_hash_table_get_keys_as_array (muxer->groups, NULL); + GArray *prefixes; + + prefixes = g_array_new (TRUE, FALSE, sizeof (gchar *)); + + for ( ; muxer != NULL; muxer = muxer->parent) + { + g_hash_table_foreach (muxer->groups, + gtk_action_muxer_append_prefixes, + prefixes); + } + + return (const gchar **)(void *) g_array_free (prefixes, FALSE); } GActionGroup * @@ -754,10 +776,13 @@ gtk_action_muxer_lookup (GtkActionMuxer *muxer, { Group *group; - group = g_hash_table_lookup (muxer->groups, prefix); + for ( ; muxer != NULL; muxer = muxer->parent) + { + group = g_hash_table_lookup (muxer->groups, prefix); - if (group != NULL) - return group->group; + if (group != NULL) + return group->group; + } return NULL; } diff --git a/testsuite/gtk/action.c b/testsuite/gtk/action.c index 92a1e08ffe..7ca703bf78 100644 --- a/testsuite/gtk/action.c +++ b/testsuite/gtk/action.c @@ -72,6 +72,125 @@ menu_item_label_notify_count (ActionTest *fixture, g_object_unref (item); } +static void +g_test_action_muxer (void) +{ + GtkWidget *window; + GtkWidget *box; + GtkWidget *button; + const char **prefixes; + const char * const expected[] = { "win", NULL }; + const char * const expected1[] = { "group1", "win", NULL }; + const char * const expected2[] = { "group2", "win", NULL }; + const char * const expected3[] = { "group1", "group2", "win", NULL }; + GActionGroup *win; + GActionGroup *group1; + GActionGroup *group2; + GActionGroup *grp; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + button = gtk_button_new_with_label ("test"); + + gtk_container_add (GTK_CONTAINER (window), box); + gtk_container_add (GTK_CONTAINER (box), button); + + win = G_ACTION_GROUP (g_simple_action_group_new ()); + gtk_widget_insert_action_group (window, "win", win); + + prefixes = gtk_widget_list_action_prefixes (window); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (box); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (button); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + grp = gtk_widget_get_action_group (window, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (window, "bla"); + g_assert (grp == NULL); + + grp = gtk_widget_get_action_group (box, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (box, "bla"); + g_assert (grp == NULL); + + grp = gtk_widget_get_action_group (button, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (button, "bla"); + g_assert (grp == NULL); + + group1 = G_ACTION_GROUP (g_simple_action_group_new ()); + gtk_widget_insert_action_group (button, "group1", group1); + + prefixes = gtk_widget_list_action_prefixes (window); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (box); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (button); + g_assert (g_strv_equal ((const char * const *)prefixes, expected1)); + g_free (prefixes); + + grp = gtk_widget_get_action_group (window, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (window, "group1"); + g_assert (grp == NULL); + + grp = gtk_widget_get_action_group (box, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (box, "group1"); + g_assert (grp == NULL); + + grp = gtk_widget_get_action_group (button, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (button, "group1"); + g_assert (grp == group1); + + group2 = G_ACTION_GROUP (g_simple_action_group_new ()); + gtk_widget_insert_action_group (box, "group2", group2); + + prefixes = gtk_widget_list_action_prefixes (window); + g_assert (g_strv_equal ((const char * const *)prefixes, expected)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (box); + g_assert (g_strv_equal ((const char * const *)prefixes, expected2)); + g_free (prefixes); + + prefixes = gtk_widget_list_action_prefixes (button); + g_assert (g_strv_equal ((const char * const *)prefixes, expected3)); + g_free (prefixes); + + grp = gtk_widget_get_action_group (window, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (window, "group2"); + g_assert (grp == NULL); + + grp = gtk_widget_get_action_group (box, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (box, "group2"); + g_assert (grp == group2); + + grp = gtk_widget_get_action_group (button, "win"); + g_assert (grp == win); + grp = gtk_widget_get_action_group (button, "group2"); + g_assert (grp == group2); + + gtk_widget_destroy (window); + g_object_unref (win); + g_object_unref (group1); + g_object_unref (group2); +} + /* main */ int @@ -86,6 +205,7 @@ main (int argc, menu_item_label_notify_count, action_test_teardown); + g_test_add_func ("/action/muxer/update-parent", g_test_action_muxer); + return g_test_run (); } -