From 0144feb41fc1819cec6415483bd8a61e64373aca Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 28 Apr 2024 16:31:13 +0200 Subject: [PATCH] GApplication: Allow multiple parameters for D-Bus activation D-Bus Activation allows passing an array of parameters. Allow apps to export actions that accept tuples to match the number of elements in the parameters so the full potential of the D-Bus interface can be used. Closes: https://gitlab.gnome.org/GNOME/glib/-/issues/3333 --- gio/gapplicationimpl-dbus.c | 24 +++++++++++- gio/tests/gapplication.c | 77 ++++++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c index f9bf28c40..1ba533839 100644 --- a/gio/gapplicationimpl-dbus.c +++ b/gio/gapplicationimpl-dbus.c @@ -291,8 +291,6 @@ g_application_impl_method_call (GDBusConnection *connection, /* Only on the freedesktop interface */ g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data); - g_variant_iter_next (iter, "v", ¶meter); - g_variant_iter_free (iter); /* Check the action exists and the parameter type matches. */ if (!g_action_group_query_action (impl->exported_actions, @@ -306,6 +304,28 @@ g_application_impl_method_call (GDBusConnection *connection, return; } + /* Accept multiple parameters as a tuple with the exact number of parameters */ + if (g_variant_iter_n_children (iter) > 1) + { + GVariant *value = NULL; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + + while (g_variant_iter_loop (iter, "v", &value)) + { + g_variant_builder_add_value (&builder, value); + } + + parameter = g_variant_ref_sink (g_variant_builder_end (&builder)); + } + else + { + g_variant_iter_next (iter, "v", ¶meter); + } + + g_variant_iter_free (iter); + if (!((parameter_type == NULL && parameter == NULL) || (parameter_type != NULL && parameter != NULL && g_variant_is_of_type (parameter, parameter_type)))) { diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c index 8c1dac10c..1b8f2513b 100644 --- a/gio/tests/gapplication.c +++ b/gio/tests/gapplication.c @@ -1734,7 +1734,7 @@ test_dbus_activate_action (void) { GDBusMessage *message; /* (not nullable) (owned) */ guint n_expected_activations; - } messages[6]; + } messages[12]; gsize i; g_test_summary ("Test that calling the ActivateAction D-Bus method works"); @@ -1796,6 +1796,79 @@ test_dbus_activate_action (void) g_dbus_message_set_body (messages[5].message, g_variant_new ("(sava{sv})", "nonexistent", NULL, NULL)); messages[5].n_expected_activations = 0; + /* Action with tuple as parameter given as two items to the interface */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new_string ("first")); + g_variant_builder_add (&builder, "v", g_variant_new_string ("second")); + + messages[6].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + + g_dbus_message_set_body (messages[6].message, g_variant_new ("(sava{sv})", "multi", &builder, NULL)); + messages[6].n_expected_activations = 1; + + /* Action with tuple as parameter given as two items to the interface but with a wrong type */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new_string ("first")); + g_variant_builder_add (&builder, "v", g_variant_new_uint32 (42)); + + messages[7].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + g_dbus_message_set_body (messages[7].message, g_variant_new ("(sava{sv})", "multi", &builder, NULL)); + messages[7].n_expected_activations = 0; + + /* Action with tuple as parameter given as a single item to the interface */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new ("(ss)", "first", "second")); + + messages[8].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + g_dbus_message_set_body (messages[8].message, g_variant_new ("(sava{sv})", "multi", &builder, NULL)); + messages[8].n_expected_activations = 1; + + /* Action with tuple as parameter given as a single item to the interface but with additional items */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new ("(ss)", "first", "second")); + g_variant_builder_add (&builder, "v", g_variant_new_uint32 (42)); + g_variant_builder_add (&builder, "v", g_variant_new_uint32 (42)); + + messages[9].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + g_dbus_message_set_body (messages[9].message, g_variant_new ("(sava{sv})", "multi", &builder, NULL)); + messages[9].n_expected_activations = 0; + + /* Action with tuple with single item as parameter */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new ("(s)", "first")); + + messages[10].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + g_dbus_message_set_body (messages[10].message, g_variant_new ("(sava{sv})", "single", &builder, NULL)); + messages[10].n_expected_activations = 1; + + /* Action with tuple with single item as parameter with additional items */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + g_variant_builder_add (&builder, "v", g_variant_new ("(s)", "first")); + g_variant_builder_add (&builder, "v", g_variant_new_uint32 (42)); + g_variant_builder_add (&builder, "v", g_variant_new_uint32 (43)); + + messages[11].message = g_dbus_message_new_method_call ("org.gtk.TestApplication.ActivateAction", + "/org/gtk/TestApplication/ActivateAction", + "org.freedesktop.Application", + "ActivateAction"); + g_dbus_message_set_body (messages[11].message, g_variant_new ("(sava{sv})", "single", &builder, NULL)); + messages[11].n_expected_activations = 0; + /* Try each message */ bus = g_test_dbus_new (G_TEST_DBUS_NONE); g_test_dbus_up (bus); @@ -1808,6 +1881,8 @@ test_dbus_activate_action (void) { { "undo", dbus_activate_action_cb, NULL, NULL, NULL, { 0 } }, { "lang", dbus_activate_action_cb, "s", "'latin'", NULL, { 0 } }, + { "single", dbus_activate_action_cb, "(s)", NULL, NULL, { 0 } }, + { "multi", dbus_activate_action_cb, "(ss)", NULL, NULL, { 0 } }, }; guint n_activations = 0;