summaryrefslogtreecommitdiff
path: root/gio/gappinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'gio/gappinfo.c')
-rw-r--r--gio/gappinfo.c264
1 files changed, 19 insertions, 245 deletions
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
index ba5815568..e910c0fa1 100644
--- a/gio/gappinfo.c
+++ b/gio/gappinfo.c
@@ -32,15 +32,12 @@
#ifdef G_OS_UNIX
#include "gdbusconnection.h"
#include "gdbusmessage.h"
-#include "gdocumentportal.h"
#include "gportalsupport.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"
+#include "gunixfdlist.h"
+#include "gopenuriportal.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#endif
/**
@@ -687,240 +684,6 @@ g_app_info_should_show (GAppInfo *appinfo)
return (* iface->should_show) (appinfo);
}
-#ifdef G_OS_UNIX
-static void
-response_received (GDBusConnection *connection,
- const char *sender_name,
- const char *object_path,
- const char *interface_name,
- const char *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- GTask *task = user_data;
- guint32 response;
- guint signal_id;
-
- signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id"));
- g_dbus_connection_signal_unsubscribe (connection, signal_id);
-
- g_variant_get (parameters, "(u@a{sv})", &response, NULL);
-
- if (response == 0)
- g_task_return_boolean (task, TRUE);
- else if (response == 1)
- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled");
- else
- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed");
-
- g_object_unref (task);
-}
-
-static void
-open_uri_done (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GDBusConnection *connection = G_DBUS_CONNECTION (source);
- GTask *task = user_data;
- GVariant *res;
- GError *error = NULL;
- const char *path;
- guint signal_id;
-
- res = g_dbus_connection_call_finish (connection, result, &error);
-
- if (res == NULL)
- {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- g_variant_get (res, "(&o)", &path);
-
- signal_id =
- g_dbus_connection_signal_subscribe (connection,
- "org.freedesktop.portal.Desktop",
- "org.freedesktop.portal.Request",
- "Response",
- path,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
- response_received,
- task, NULL);
-
- g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id));
-
- 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,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDBusConnection *session_bus;
- GVariantBuilder opt_builder;
- const char *parent_window = NULL;
- char *real_uri;
- GTask *task;
- GAsyncReadyCallback dbus_callback;
- GError *error = NULL;
-
- session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (session_bus == NULL)
- {
- g_task_report_error (context, callback, user_data, NULL, error);
- return;
- }
-
- 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);
- dbus_callback = open_uri_done;
- }
- else
- {
- task = NULL;
- 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_dbus_connection_flush (session_bus, cancellable, NULL, NULL);
- g_object_unref (session_bus);
- g_free (real_uri);
-}
-
-static void
-launch_default_with_portal_sync (const char *uri,
- GAppLaunchContext *context)
-{
- GDBusConnection *session_bus;
- GVariantBuilder opt_builder;
- GVariant *res = NULL;
- const char *parent_window = NULL;
- char *real_uri;
- GError *error = NULL;
-
- session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (session_bus == NULL)
- {
- g_task_report_error (context, NULL, NULL, NULL, error);
- return;
- }
-
- 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_object_unref (session_bus);
- return;
- }
-
- 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
- g_variant_unref (res);
-
- g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
- g_object_unref (session_bus);
- g_free (real_uri);
-}
-
-static gboolean
-launch_default_with_portal (const char *uri,
- GAppLaunchContext *context,
- GError **error)
-{
- launch_default_with_portal_sync (uri, context);
- return TRUE;
-}
-#endif
-
static gboolean
launch_default_for_uri (const char *uri,
GAppLaunchContext *context,
@@ -985,10 +748,16 @@ g_app_info_launch_default_for_uri (const char *uri,
#ifdef G_OS_UNIX
if (glib_should_use_portal ())
{
+ const char *parent_window = NULL;
+
/* Reset any error previously set by launch_default_for_uri */
g_clear_error (error);
- return launch_default_with_portal (uri, launch_context, error);
+ if (launch_context && launch_context->priv->envp)
+ parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID");
+
+ return g_openuri_portal_open_uri (uri, parent_window, error);
+
}
#endif
@@ -1028,7 +797,12 @@ g_app_info_launch_default_for_uri_async (const char *uri,
#ifdef G_OS_UNIX
if (!res && glib_should_use_portal ())
{
- launch_default_with_portal_async (uri, context, cancellable, callback, user_data);
+ const char *parent_window = NULL;
+
+ if (context && context->priv->envp)
+ parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
+
+ g_openuri_portal_open_uri_async (uri, parent_window, cancellable, callback, user_data);
return;
}
#endif
@@ -1057,7 +831,7 @@ gboolean
g_app_info_launch_default_for_uri_finish (GAsyncResult *result,
GError **error)
{
- return g_task_propagate_boolean (G_TASK (result), error);
+ return g_openuri_portal_open_uri_finish (result, error);
}
/**