[glib] Add portal support to g_app_info_launch_default_for_uri



commit 5b77a19fe1fc89017dc3ed4f74386aa8c2a73d0e
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jun 21 08:17:16 2016 -0400

    Add portal support to g_app_info_launch_default_for_uri
    
    We need to patch in the portal support at a high enough
    level that GAppInfo is not involved - a sandboxed app may
    not be able to see any applications, so it can only launch
    the defaults.
    
    Note that even though the API is called launch_default...,
    the portal may still offer the user to choose the application
    to launch.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=768498

 gio/gappinfo.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 52 insertions(+), 4 deletions(-)
---
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
index bfcc85b..f19e401 100644
--- a/gio/gappinfo.c
+++ b/gio/gappinfo.c
@@ -20,13 +20,18 @@
 
 #include "config.h"
 
+#include <unistd.h>
+
 #include "gappinfo.h"
 #include "gappinfoprivate.h"
 #include "gcontextspecificgroup.h"
+#include "gdbusconnection.h"
+#include "gdbusmessage.h"
 
 #include "glibintl.h"
 #include <gioerror.h>
 #include <gfile.h>
+#include "gportalsupport.h"
 
 
 /**
@@ -85,6 +90,10 @@
  * different ideas of what a given URI means.
  */
 
+struct _GAppLaunchContextPrivate {
+  char **envp;
+};
+
 typedef GAppInfoIface GAppInfoInterface;
 G_DEFINE_INTERFACE (GAppInfo, g_app_info, G_TYPE_OBJECT)
 
@@ -665,6 +674,46 @@ g_app_info_should_show (GAppInfo *appinfo)
   return (* iface->should_show) (appinfo);
 }
 
+static gboolean
+launch_default_with_portal (const char         *uri,
+                            GAppLaunchContext  *context,
+                            GError            **error)
+{
+  GDBusConnection *session_bus;
+  GVariantBuilder opt_builder;
+  const char *parent_window = NULL;
+
+  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+  if (session_bus == NULL)
+    return FALSE;
+
+  if (context && context->priv->envp)
+    parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
+
+  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
+
+  g_dbus_connection_call (session_bus,
+                          "org.freedesktop.portal.Desktop",
+                          "/org/freedesktop/portal/desktop",
+                          "org.freedesktop.portal.OpenURI",
+                          "OpenURI",
+                          g_variant_new ("(ss@a{sv})",
+                                         parent_window ? parent_window : "",
+                                         uri,
+                                         g_variant_builder_end (&opt_builder)),
+                          NULL,
+                          G_DBUS_CALL_FLAGS_NONE,
+                          G_MAXINT,
+                          NULL,
+                          NULL,
+                          NULL);
+
+  g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
+  g_object_unref (session_bus);
+
+  return TRUE;
+}
+
 /**
  * g_app_info_launch_default_for_uri:
  * @uri: the uri to show
@@ -688,6 +737,9 @@ g_app_info_launch_default_for_uri (const char         *uri,
   GList l;
   gboolean res;
 
+  if (glib_should_use_portal ())
+    return launch_default_with_portal (uri, launch_context, error);
+
   /* g_file_query_default_handler() calls
    * g_app_info_get_default_for_uri_scheme() too, but we have to do it
    * here anyway in case GFile can't parse @uri correctly.
@@ -788,10 +840,6 @@ enum {
   LAST_SIGNAL
 };
 
-struct _GAppLaunchContextPrivate {
-  char **envp;
-};
-
 static guint signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT)


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