diff options
author | Guido Günther <agx@sigxcpu.org> | 2021-09-29 08:19:09 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2021-10-04 10:29:08 +0200 |
commit | 7665b748bb86b0506f2d1c6d21d1d373689e1817 (patch) | |
tree | f8c54b63ea4b2d9dada064ab94068fc54b48039c | |
parent | 5890b2bdea351a0a01e2fef84e2febdb1fcc4fd1 (diff) | |
download | glib-7665b748bb86b0506f2d1c6d21d1d373689e1817.tar.gz |
gappinfo: Add launch-started signal
Emit this when we're about to spawn or DBus activate a GAppInfo. This
allows lauchers to keep the appinfo associated with a startup id.
We use a GVariant to allow for future exansion of the supplied data.
-rw-r--r-- | gio/gappinfo.c | 36 | ||||
-rw-r--r-- | gio/gappinfo.h | 4 | ||||
-rw-r--r-- | gio/gdesktopappinfo.c | 25 | ||||
-rw-r--r-- | gio/tests/desktop-app-info.c | 28 |
4 files changed, 90 insertions, 3 deletions
diff --git a/gio/gappinfo.c b/gio/gappinfo.c index 75340c43f..d9d2bdaf7 100644 --- a/gio/gappinfo.c +++ b/gio/gappinfo.c @@ -1103,6 +1103,7 @@ g_app_info_delete (GAppInfo *appinfo) enum { LAUNCH_FAILED, + LAUNCH_STARTED, LAUNCHED, LAST_SIGNAL }; @@ -1161,6 +1162,41 @@ g_app_launch_context_class_init (GAppLaunchContextClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); /** + * GAppLaunchContext::launch-started: + * @context: the object emitting the signal + * @info: the #GAppInfo that is about to be launched + * @platform_data: (nullable): additional platform-specific data for this launch + * + * The #GAppLaunchContext::launch-started signal is emitted when a #GAppInfo is + * about to be launched. If non-null the @platform_data is an + * GVariant dictionary mapping strings to variants (ie `a{sv}`), which + * contains additional, platform-specific data about this launch. On + * UNIX, at least the `startup-notification-id` keys will be + * present. + * + * The value of the `startup-notification-id` key (type `s`) is a startup + * notification ID corresponding to the format from the [startup-notification + * specification](https://specifications.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt). + * It allows tracking the progress of the launchee through startup. + * + * It is guaranteed that this signal is followed by either a #GAppLaunchContext::launched or + * #GAppLaunchContext::launch-failed signal. + * + * Since: 2.72 + */ + signals[LAUNCH_STARTED] = g_signal_new (I_("launch-started"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GAppLaunchContextClass, launch_started), + NULL, NULL, + _g_cclosure_marshal_VOID__OBJECT_VARIANT, + G_TYPE_NONE, 2, + G_TYPE_APP_INFO, G_TYPE_VARIANT); + g_signal_set_va_marshaller (signals[LAUNCH_STARTED], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_VARIANTv); + + /** * GAppLaunchContext::launched: * @context: the object emitting the signal * @info: the #GAppInfo that was just launched diff --git a/gio/gappinfo.h b/gio/gappinfo.h index d26d048a5..ad3068e31 100644 --- a/gio/gappinfo.h +++ b/gio/gappinfo.h @@ -293,12 +293,14 @@ struct _GAppLaunchContextClass void (* launched) (GAppLaunchContext *context, GAppInfo *info, GVariant *platform_data); + void (* launch_started) (GAppLaunchContext *context, + GAppInfo *info, + GVariant *platform_data); /* Padding for future expansion */ void (*_g_reserved1) (void); void (*_g_reserved2) (void); void (*_g_reserved3) (void); - void (*_g_reserved4) (void); }; GLIB_AVAILABLE_IN_ALL diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 4a2592a64..55312fdfb 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -2731,6 +2731,26 @@ notify_desktop_launch (GDBusConnection *session_bus, g_object_unref (msg); } +static void +emit_launch_started (GAppLaunchContext *context, + GDesktopAppInfo *info, + const gchar *startup_id) +{ + GVariantBuilder builder; + GVariant *platform_data = NULL; + + if (startup_id) + { + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, "{sv}", + "startup-notification-id", + g_variant_new_string (startup_id)); + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + } + g_signal_emit_by_name (context, "launch-started", info, platform_data); + g_clear_pointer (&platform_data, g_variant_unref); +} + #define _SPAWN_FLAGS_DEFAULT (G_SPAWN_SEARCH_PATH) static gboolean @@ -2826,6 +2846,8 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info, } g_list_free_full (launched_files, g_object_unref); + + emit_launch_started (launch_context, info, sn_id); } /* Wrap the @argv in a command which will set the @@ -3057,6 +3079,9 @@ launch_uris_with_dbus (GDesktopAppInfo *info, g_variant_dict_init (&dict, platform_data); g_variant_dict_lookup (&dict, "desktop-startup-id", "s", &data->startup_id); + if (launch_context) + emit_launch_started (launch_context, info, data->startup_id); + g_dbus_connection_call (session_bus, info->app_id, object_path, "org.freedesktop.Application", uris ? "Open" : "Activate", g_variant_builder_end (&builder), NULL, G_DBUS_CALL_FLAGS_NONE, -1, diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c index 15dcd8f1c..95a2a1589 100644 --- a/gio/tests/desktop-app-info.c +++ b/gio/tests/desktop-app-info.c @@ -728,6 +728,20 @@ test_show_in (void) assert_shown ("invalid-desktop.desktop", FALSE, "../invalid/desktop:../invalid/desktop"); } +static void +on_launch_started (GAppLaunchContext *context, GAppInfo *info, GVariant *platform_data, gpointer data) +{ + gboolean *invoked = data; + + g_assert_true (G_IS_APP_LAUNCH_CONTEXT (context)); + g_assert_true (G_IS_APP_INFO (info)); + /* Our default context doesn't fill in any platform data */ + g_assert_null (platform_data); + + g_assert_false (*invoked); + *invoked = TRUE; +} + /* Test g_desktop_app_info_launch_uris_as_manager() and * g_desktop_app_info_launch_uris_as_manager_with_fds() */ @@ -738,6 +752,8 @@ test_launch_as_manager (void) GError *error = NULL; gboolean retval; const gchar *path; + gboolean invoked = FALSE; + GAppLaunchContext *context; if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0') { @@ -754,23 +770,31 @@ test_launch_as_manager (void) return; } - retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, NULL, 0, + context = g_app_launch_context_new (); + g_signal_connect (context, "launch-started", + G_CALLBACK (on_launch_started), + &invoked); + retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, context, 0, NULL, NULL, NULL, NULL, &error); g_assert_no_error (error); g_assert_true (retval); + g_assert_true (invoked); + invoked = FALSE; retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo, - NULL, NULL, 0, + NULL, context, 0, NULL, NULL, NULL, NULL, -1, -1, -1, &error); g_assert_no_error (error); g_assert_true (retval); + g_assert_true (invoked); g_object_unref (appinfo); + g_assert_finalize_object (context); } int |