[glib] gdesktopappinfo: Send out a session bus signal when launching .desktop file



commit bb6c44b9d3fd94835044ffda38ca2f211deb5b7b
Author: Colin Walters <walters verbum org>
Date:   Mon Dec 20 13:12:28 2010 -0500

    gdesktopappinfo: Send out a session bus signal when launching .desktop file
    
    This signal contains the full path of the .desktop file, along with
    the process id, which allows multiple interested components (like
    GNOME Shell) to better know the state of the system (which processes
    correspond to which .desktop files).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=606960

 gio/gdesktopappinfo.c |   87 +++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 78 insertions(+), 9 deletions(-)
---
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 61a1a48..5851e02 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -880,18 +880,17 @@ prepend_terminal_to_vector (int    *argc,
 }
 
 static GList *
-uri_list_segment_to_files (GList *start,
-			   GList *end)
+create_files_for_uris (GList *uris)
 {
   GList *res;
-  GFile *file;
+  GList *iter;
 
   res = NULL;
-  while (start != NULL && start != end)
+
+  for (iter = uris; iter; iter = iter->next)
     {
-      file = g_file_new_for_uri ((char *)start->data);
+      GFile *file = g_file_new_for_uri ((char *)iter->data);
       res = g_list_prepend (res, file);
-      start = start->next;
     }
 
   return g_list_reverse (res);
@@ -926,6 +925,49 @@ child_setup (gpointer user_data)
     }
 }
 
+static void
+notify_desktop_launch (GDBusConnection  *session_bus,
+		       const char       *desktop_file, /* filename */
+		       long              pid,
+		       const char       *display,
+		       const char       *sn_id,
+		       GList            *uris)
+{
+  GDBusMessage *msg;
+  GVariantBuilder uri_variant;
+  GVariantBuilder extras_variant;
+  GList *iter;
+
+  if (session_bus == NULL)
+    return;
+
+  g_variant_builder_init (&uri_variant, G_VARIANT_TYPE ("as"));
+  for (iter = uris; iter; iter = iter->next)
+    g_variant_builder_add (&uri_variant, "s", iter->data);
+
+  g_variant_builder_init (&extras_variant, G_VARIANT_TYPE ("a{sv}"));
+  if (sn_id != NULL && g_utf8_validate (sn_id, -1, NULL))
+    g_variant_builder_add (&extras_variant, "{sv}",
+			   "startup-id",
+			   g_variant_new ("s",
+					  sn_id));
+  
+  msg = g_dbus_message_new_signal ("/org/gtk/gio/DesktopAppInfo",
+				   "org.gtk.gio.DesktopAppInfo",
+				   "Launched");
+  g_dbus_message_set_body (msg, g_variant_new ("(@aysxasa{sv})",
+					       g_variant_new_bytestring (desktop_file),
+					       display ? display : "",
+					       (gint64)pid,
+					       &uri_variant,
+					       &extras_variant));
+  g_dbus_connection_send_message (session_bus,
+				  msg, 0,
+				  NULL,
+				  NULL);
+  g_object_unref (msg);
+}
+
 static gboolean
 g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 				GList              *uris,
@@ -933,9 +975,9 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 				GError            **error)
 {
   GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo);
+  GDBusConnection *session_bus;
   gboolean completed = FALSE;
   GList *old_uris;
-  GList *launched_files;
   char **argv;
   int argc;
   ChildSetupData data;
@@ -944,12 +986,24 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 
   argv = NULL;
 
+  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
   do
     {
+      GPid pid;
+      GList *launched_uris;
+      GList *iter;
+
       old_uris = uris;
       if (!expand_application_parameters (info, &uris,
 					  &argc, &argv, error))
 	goto out;
+
+      /* Get the subset of URIs we're launching with this process */
+      launched_uris = NULL;
+      for (iter = old_uris; iter != NULL && iter != uris; iter = iter->next)
+	launched_uris = g_list_prepend (launched_uris, iter->data);
+      launched_uris = g_list_reverse (launched_uris);
       
       if (info->terminal && !prepend_terminal_to_vector (&argc, &argv))
 	{
@@ -964,7 +1018,7 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 
       if (launch_context)
 	{
-	  launched_files = uri_list_segment_to_files (old_uris, uris);
+	  GList *launched_files = create_files_for_uris (launched_uris);
 
 	  data.display = g_app_launch_context_get_display (launch_context,
 						           appinfo,
@@ -984,7 +1038,7 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 			  G_SPAWN_SEARCH_PATH,
 			  child_setup,
 			  &data,
-			  NULL,
+			  &pid,
 			  error))
 	{
 	  if (data.sn_id)
@@ -992,18 +1046,33 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 
 	  g_free (data.sn_id);
 	  g_free (data.display);
+	  g_list_free (launched_uris);
 
 	  goto out;
 	}
 
+      notify_desktop_launch (session_bus,
+			     info->filename,
+			     pid,
+			     data.display,
+			     data.sn_id,
+			     launched_uris);
+
       g_free (data.sn_id);
       g_free (data.display);
+      g_list_free (launched_uris);
 
       g_strfreev (argv);
       argv = NULL;
     }
   while (uris != NULL);
 
+  /* TODO - need to handle the process exiting immediately
+   * after launching an app.  See http://bugzilla.gnome.org/606960
+   */
+  if (session_bus != NULL)
+    g_object_unref (session_bus);
+
   completed = TRUE;
 
  out:



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