[glib/open-file: 1/2] Use OpenFile for local files



commit 9946597a18b98b701f98ba1fa1a577c2d7c1a90b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 20 16:21:14 2017 -0400

    Use OpenFile for local files
    
    The OpenURI portal has a separate method to handle local
    files now. Use it.

 gio/gappinfo.c |  202 ++++++++++++++++++++++++++++++++------------------------
 1 files changed, 116 insertions(+), 86 deletions(-)
---
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
index ba58155..796af06 100644
--- a/gio/gappinfo.c
+++ b/gio/gappinfo.c
@@ -32,15 +32,19 @@
 #ifdef G_OS_UNIX
 #include "gdbusconnection.h"
 #include "gdbusmessage.h"
-#include "gdocumentportal.h"
 #include "gportalsupport.h"
+#include "gunixfdlist.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #endif
 
 #ifdef G_OS_UNIX
 #define FLATPAK_OPENURI_PORTAL_BUS_NAME "org.freedesktop.portal.Desktop"
 #define FLATPAK_OPENURI_PORTAL_PATH "/org/freedesktop/portal/desktop"
 #define FLATPAK_OPENURI_PORTAL_IFACE "org.freedesktop.portal.OpenURI"
-#define FLATPAK_OPENURI_PORTAL_METHOD "OpenURI"
+#define FLATPAK_OPENURI_PORTAL_URI_METHOD "OpenURI"
+#define FLATPAK_OPENURI_PORTAL_FILE_METHOD "OpenFile"
 #endif
 
 /**
@@ -755,38 +759,6 @@ open_uri_done (GObject      *source,
   g_variant_unref (res);
 }
 
-static char *
-real_uri_for_portal (const char          *uri,
-                     GAppLaunchContext   *context,
-                     GCancellable        *cancellable,
-                     GAsyncReadyCallback  callback,
-                     gpointer             user_data,
-                     GError             **error)
-{
-  GFile *file = NULL;
-  char *real_uri = NULL;
-
-  file = g_file_new_for_uri (uri);
-  if (g_file_is_native (file))
-    {
-      real_uri = g_document_portal_add_document (file, error);
-      g_object_unref (file);
-
-      if (real_uri == NULL)
-        {
-          g_task_report_error (context, callback, user_data, NULL, *error);
-          return NULL;
-        }
-    }
-  else
-    {
-      g_object_unref (file);
-      real_uri = g_strdup (uri);
-    }
-
-  return real_uri;
-}
-
 static void
 launch_default_with_portal_async (const char          *uri,
                                   GAppLaunchContext   *context,
@@ -797,8 +769,8 @@ launch_default_with_portal_async (const char          *uri,
   GDBusConnection *session_bus;
   GVariantBuilder opt_builder;
   const char *parent_window = NULL;
-  char *real_uri;
   GTask *task;
+  GFile *file;
   GAsyncReadyCallback dbus_callback;
   GError *error = NULL;
 
@@ -812,15 +784,6 @@ launch_default_with_portal_async (const char          *uri,
   if (context && context->priv->envp)
     parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
 
-  real_uri = real_uri_for_portal (uri, context, cancellable, callback, user_data, &error);
-  if (real_uri == NULL)
-    {
-      g_object_unref (session_bus);
-      return;
-    }
-
-  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
-
   if (callback)
     {
       task = g_task_new (context, cancellable, callback, user_data);
@@ -832,25 +795,62 @@ launch_default_with_portal_async (const char          *uri,
       dbus_callback = NULL;
     }
 
-  g_dbus_connection_call (session_bus,
-                          FLATPAK_OPENURI_PORTAL_BUS_NAME,
-                          FLATPAK_OPENURI_PORTAL_PATH,
-                          FLATPAK_OPENURI_PORTAL_IFACE,
-                          FLATPAK_OPENURI_PORTAL_METHOD,
-                          g_variant_new ("(ss@a{sv})",
-                                         parent_window ? parent_window : "",
-                                         real_uri,
-                                         g_variant_builder_end (&opt_builder)),
-                          NULL,
-                          G_DBUS_CALL_FLAGS_NONE,
-                          G_MAXINT,
-                          cancellable,
-                          dbus_callback,
-                          task);
+  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
+
+  file = g_file_new_for_uri (uri);
+  if (g_file_is_native (file))
+    {
+      char *path;
+      GUnixFDList *fd_list;
+      int fd, fd_id;
+
+      path = g_file_get_path (file);
+
+      fd = open (path, O_PATH | O_CLOEXEC);
+      fd_list = g_unix_fd_list_new_from_array (&fd, 1);
+      fd_id = 0;
+
+      g_dbus_connection_call_with_unix_fd_list (session_bus,
+                                                FLATPAK_OPENURI_PORTAL_BUS_NAME,
+                                                FLATPAK_OPENURI_PORTAL_PATH,
+                                                FLATPAK_OPENURI_PORTAL_IFACE,
+                                                FLATPAK_OPENURI_PORTAL_FILE_METHOD,
+                                                g_variant_new ("(sh@a{sv})",
+                                                               parent_window ? parent_window : "",
+                                                               fd_id,
+                                                               g_variant_builder_end (&opt_builder)),
+                                                NULL,
+                                                G_DBUS_CALL_FLAGS_NONE,
+                                                G_MAXINT,
+                                                fd_list,
+                                                cancellable,
+                                                dbus_callback,
+                                                task);
+      g_object_unref (fd_list);
+      g_free (path);
+    }
+  else
+    {
+      g_dbus_connection_call (session_bus,
+                              FLATPAK_OPENURI_PORTAL_BUS_NAME,
+                              FLATPAK_OPENURI_PORTAL_PATH,
+                              FLATPAK_OPENURI_PORTAL_IFACE,
+                              FLATPAK_OPENURI_PORTAL_URI_METHOD,
+                              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,
+                              cancellable,
+                              dbus_callback,
+                              task);
+    }
 
   g_dbus_connection_flush (session_bus, cancellable, NULL, NULL);
   g_object_unref (session_bus);
-  g_free (real_uri);
+  g_object_unref (file);
 }
 
 static void
@@ -859,11 +859,16 @@ launch_default_with_portal_sync (const char          *uri,
 {
   GDBusConnection *session_bus;
   GVariantBuilder opt_builder;
+  GFile *file;
   GVariant *res = NULL;
   const char *parent_window = NULL;
-  char *real_uri;
   GError *error = NULL;
 
+  /* Calling the D-Bus method for the OpenURI portal "protects" the logic from
+   * not ever having the remote method running in case the xdg-desktop-portal
+   * process is not yet running and the caller quits quickly after the call.
+   */
+
   session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
   if (session_bus == NULL)
     {
@@ -874,33 +879,58 @@ launch_default_with_portal_sync (const char          *uri,
   if (context && context->priv->envp)
     parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
 
-  real_uri = real_uri_for_portal (uri, context, NULL, NULL, NULL, &error);
-  if (real_uri == NULL)
+  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
+
+  file = g_file_new_for_uri (uri);
+  if (g_file_is_native (file))
     {
-      g_object_unref (session_bus);
-      return;
+      char *path;
+      GUnixFDList *fd_list;
+      int fd, fd_id;
+
+      path = g_file_get_path (file);
+
+      fd = open (path, O_PATH | O_CLOEXEC);
+      fd_list = g_unix_fd_list_new_from_array (&fd, 1);
+      fd_id = 0;
+
+      res = g_dbus_connection_call_with_unix_fd_list_sync (session_bus,
+                                                           FLATPAK_OPENURI_PORTAL_BUS_NAME,
+                                                           FLATPAK_OPENURI_PORTAL_PATH,
+                                                           FLATPAK_OPENURI_PORTAL_IFACE,
+                                                           FLATPAK_OPENURI_PORTAL_FILE_METHOD,
+                                                           g_variant_new ("(sh@a{sv})",
+                                                                          parent_window ? parent_window : "",
+                                                                          fd_id,
+                                                                          g_variant_builder_end 
(&opt_builder)),
+                                                           NULL,
+                                                           G_DBUS_CALL_FLAGS_NONE,
+                                                           G_MAXINT,
+                                                           fd_list,
+                                                           NULL,
+                                                           NULL,
+                                                           &error);
+      g_object_unref (fd_list);
+      g_free (path);
+    }
+  else
+    {
+      res = g_dbus_connection_call_sync (session_bus,
+                                         FLATPAK_OPENURI_PORTAL_BUS_NAME,
+                                         FLATPAK_OPENURI_PORTAL_PATH,
+                                         FLATPAK_OPENURI_PORTAL_IFACE,
+                                         FLATPAK_OPENURI_PORTAL_URI_METHOD,
+                                         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,
+                                         &error);
     }
 
-  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
-
-  /* Calling the D-Bus method for the OpenURI portal "protects" the logic from
-   * not ever having the remote method running in case the xdg-desktop-portal
-   * process is not yet running and the caller quits quickly after the call.
-   */
-  res = g_dbus_connection_call_sync (session_bus,
-                                     FLATPAK_OPENURI_PORTAL_BUS_NAME,
-                                     FLATPAK_OPENURI_PORTAL_PATH,
-                                     FLATPAK_OPENURI_PORTAL_IFACE,
-                                     FLATPAK_OPENURI_PORTAL_METHOD,
-                                     g_variant_new ("(ss@a{sv})",
-                                                    parent_window ? parent_window : "",
-                                                    real_uri,
-                                                    g_variant_builder_end (&opt_builder)),
-                                     NULL,
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     G_MAXINT,
-                                     NULL,
-                                     &error);
   if (res == NULL)
     g_task_report_error (context, NULL, NULL, NULL, error);
   else
@@ -908,7 +938,7 @@ launch_default_with_portal_sync (const char          *uri,
 
   g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
   g_object_unref (session_bus);
-  g_free (real_uri);
+  g_object_unref (file);
 }
 
 static gboolean


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