[glib: 2/4] gdesktopappinfo: Emit "launched" and "launch-failed" signals for DBus activation too




commit 5890b2bdea351a0a01e2fef84e2febdb1fcc4fd1
Author: Guido Günther <agx sigxcpu org>
Date:   Thu Aug 19 12:15:27 2021 +0200

    gdesktopappinfo: Emit "launched" and "launch-failed" signals for DBus activation too
    
    When using g_desktop_app_info_launch_uris_as_manager the "launched"
    signal allows to map a desktop-startup-id to a GAppInfo. Make this
    possible for DBus activation too.
    
    Since we don't have a PID there we pass a 0. Update the signal
    description accordingly.

 gio/gappinfo.c        |  4 +++
 gio/gdesktopappinfo.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 77 insertions(+), 2 deletions(-)
---
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
index eed35a92f..75340c43f 100644
--- a/gio/gappinfo.c
+++ b/gio/gappinfo.c
@@ -1172,6 +1172,10 @@ g_app_launch_context_class_init (GAppLaunchContextClass *klass)
    * platform-specific data about this launch. On UNIX, at least the
    * `pid` and `startup-notification-id` keys will be present.
    *
+   * Since 2.72 the `pid` may be 0 if the process id wasn't known (for
+   * example if the process was launched via D-Bus). The `pid` may not be
+   * set at all in subsequent releases.
+   *
    * Since: 2.36
    */
   signals[LAUNCHED] = g_signal_new (I_("launched"),
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 229e62143..4a2592a64 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -2959,6 +2959,64 @@ g_desktop_app_info_make_platform_data (GDesktopAppInfo   *info,
   return g_variant_builder_end (&builder);
 }
 
+typedef struct
+{
+  GDesktopAppInfo     *info; /* (owned) */
+  GAppLaunchContext   *launch_context; /* (owned) (nullable) */
+  GAsyncReadyCallback  callback;
+  gchar               *startup_id; /* (owned) */
+  gpointer             user_data;
+} LaunchUrisWithDBusData;
+
+static void
+launch_uris_with_dbus_data_free (LaunchUrisWithDBusData *data)
+{
+  g_clear_object (&data->info);
+  g_clear_object (&data->launch_context);
+  g_free (data->startup_id);
+
+  g_free (data);
+}
+
+static void
+launch_uris_with_dbus_signal_cb (GObject      *object,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  LaunchUrisWithDBusData *data = user_data;
+  GVariantBuilder builder;
+
+  if (data->launch_context)
+    {
+      if (g_task_had_error (G_TASK (result)))
+        g_app_launch_context_launch_failed (data->launch_context, data->startup_id);
+      else
+        {
+          GVariant *platform_data;
+
+          g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+          /* the docs guarantee `pid` will be set, but we can’t
+           * easily know it for a D-Bus process, so set it to zero */
+          g_variant_builder_add (&builder, "{sv}", "pid", g_variant_new_int32 (0));
+          if (data->startup_id)
+            g_variant_builder_add (&builder, "{sv}",
+                                   "startup-notification-id",
+                                   g_variant_new_string (data->startup_id));
+          platform_data = g_variant_ref_sink (g_variant_builder_end (&builder));
+          g_signal_emit_by_name (data->launch_context,
+                                 "launched",
+                                 data->info,
+                                 platform_data);
+          g_variant_unref (platform_data);
+        }
+    }
+
+  if (data->callback)
+    data->callback (object, result, data->user_data);
+
+  launch_uris_with_dbus_data_free (data);
+}
+
 static void
 launch_uris_with_dbus (GDesktopAppInfo    *info,
                        GDBusConnection    *session_bus,
@@ -2968,8 +3026,11 @@ launch_uris_with_dbus (GDesktopAppInfo    *info,
                        GAsyncReadyCallback callback,
                        gpointer            user_data)
 {
+  GVariant *platform_data;
   GVariantBuilder builder;
+  GVariantDict dict;
   gchar *object_path;
+  LaunchUrisWithDBusData *data;
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
 
@@ -2983,13 +3044,23 @@ launch_uris_with_dbus (GDesktopAppInfo    *info,
       g_variant_builder_close (&builder);
     }
 
-  g_variant_builder_add_value (&builder, g_desktop_app_info_make_platform_data (info, uris, launch_context));
+  platform_data = g_desktop_app_info_make_platform_data (info, uris, launch_context);
 
+  g_variant_builder_add_value (&builder, platform_data);
   object_path = object_path_from_appid (info->app_id);
+
+  data = g_new0 (LaunchUrisWithDBusData, 1);
+  data->info = g_object_ref (info);
+  data->callback = callback;
+  data->user_data = user_data;
+  data->launch_context = launch_context ? g_object_ref (launch_context) : NULL;
+  g_variant_dict_init (&dict, platform_data);
+  g_variant_dict_lookup (&dict, "desktop-startup-id", "s", &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,
-                          cancellable, callback, user_data);
+                          cancellable, launch_uris_with_dbus_signal_cb, g_steal_pointer (&data));
   g_free (object_path);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]