summaryrefslogtreecommitdiff
path: root/gio/gopenuriportal.c
diff options
context:
space:
mode:
Diffstat (limited to 'gio/gopenuriportal.c')
-rw-r--r--gio/gopenuriportal.c158
1 files changed, 91 insertions, 67 deletions
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index 461b8388b..308d876e4 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -39,59 +39,28 @@
#define HAVE_O_CLOEXEC 1
#endif
-
-static GXdpOpenURI *openuri;
-
-static gboolean
-init_openuri_portal (void)
-{
- static gsize openuri_inited = 0;
-
- if (g_once_init_enter (&openuri_inited))
- {
- GError *error = NULL;
- GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-
- if (connection != NULL)
- {
- openuri = gxdp_open_uri_proxy_new_sync (connection, 0,
- "org.freedesktop.portal.Desktop",
- "/org/freedesktop/portal/desktop",
- NULL, &error);
- if (openuri == NULL)
- {
- g_warning ("Cannot create document portal proxy: %s", error->message);
- g_error_free (error);
- }
-
- g_object_unref (connection);
- }
- else
- {
- g_warning ("Cannot connect to session bus when initializing document portal: %s",
- error->message);
- g_error_free (error);
- }
-
- g_once_init_leave (&openuri_inited, 1);
- }
-
- return openuri != NULL;
-}
-
gboolean
g_openuri_portal_open_file (GFile *file,
const char *parent_window,
const char *startup_id,
GError **error)
{
+ GXdpOpenURI *openuri;
GVariantBuilder opt_builder;
gboolean res;
- if (!init_openuri_portal ())
+ openuri = gxdp_open_uri_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ NULL,
+ error);
+
+ if (openuri == NULL)
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
- "OpenURI portal is not available");
+ g_prefix_error (error, "Failed to create OpenURI proxy: ");
return FALSE;
}
@@ -115,7 +84,7 @@ g_openuri_portal_open_file (GFile *file,
if (fd == -1)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- "Failed to open '%s'", path);
+ "Failed to open ā€˜%sā€™: %s", path, g_strerror (errsv));
g_free (path);
g_variant_builder_clear (&opt_builder);
return FALSE;
@@ -156,6 +125,10 @@ g_openuri_portal_open_file (GFile *file,
g_free (uri);
}
+ g_prefix_error (error, "Failed to call OpenURI portal: ");
+
+ g_clear_object (&openuri);
+
return res;
}
@@ -165,6 +138,31 @@ enum {
XDG_DESKTOP_PORTAL_FAILED = 2
};
+typedef struct
+{
+ GXdpOpenURI *proxy;
+ char *response_handle;
+ unsigned int response_signal_id;
+ gboolean open_file;
+} CallData;
+
+static CallData *
+call_data_new (void)
+{
+ return g_new0 (CallData, 1);
+}
+
+static void
+call_data_free (gpointer data)
+{
+ CallData *call = data;
+
+ g_assert (call->response_signal_id == 0);
+ g_clear_object (&call->proxy);
+ g_clear_pointer (&call->response_handle, g_free);
+ g_free_sized (data, sizeof (CallData));
+}
+
static void
response_received (GDBusConnection *connection,
const char *sender_name,
@@ -175,11 +173,12 @@ response_received (GDBusConnection *connection,
gpointer user_data)
{
GTask *task = user_data;
+ CallData *call_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);
+ call_data = g_task_get_task_data (task);
+ g_dbus_connection_signal_unsubscribe (connection, call_data->response_signal_id);
+ call_data->response_signal_id = 0;
g_variant_get (parameters, "(u@a{sv})", &response, NULL);
@@ -208,17 +207,15 @@ open_call_done (GObject *source,
GXdpOpenURI *openuri = GXDP_OPEN_URI (source);
GDBusConnection *connection;
GTask *task = user_data;
+ CallData *call_data;
GError *error = NULL;
- gboolean open_file;
gboolean res;
char *path = NULL;
- const char *handle;
- guint signal_id;
+ call_data = g_task_get_task_data (task);
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (openuri));
- open_file = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "open-file"));
- if (open_file)
+ if (call_data->open_file)
res = gxdp_open_uri_call_open_file_finish (openuri, &path, NULL, result, &error);
else
res = gxdp_open_uri_call_open_uri_finish (openuri, &path, result, &error);
@@ -231,11 +228,12 @@ open_call_done (GObject *source,
return;
}
- handle = (const char *)g_object_get_data (G_OBJECT (task), "handle");
- if (g_strcmp0 (handle, path) != 0)
+ if (g_strcmp0 (call_data->response_handle, path) != 0)
{
- signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id"));
- g_dbus_connection_signal_unsubscribe (connection, signal_id);
+ guint signal_id;
+
+ g_dbus_connection_signal_unsubscribe (connection, call_data->response_signal_id);
+ call_data->response_signal_id = 0;
signal_id = g_dbus_connection_signal_subscribe (connection,
"org.freedesktop.portal.Desktop",
@@ -247,8 +245,12 @@ open_call_done (GObject *source,
response_received,
task,
NULL);
- g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id));
+ g_clear_pointer (&call_data->response_handle, g_free);
+ call_data->response_signal_id = signal_id;
+ call_data->response_handle = g_steal_pointer (&path);
}
+
+ g_free (path);
}
void
@@ -259,17 +261,28 @@ g_openuri_portal_open_file_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ CallData *call_data;
+ GError *error = NULL;
GDBusConnection *connection;
+ GXdpOpenURI *openuri;
GTask *task;
GVariant *opts = NULL;
int i;
guint signal_id;
- if (!init_openuri_portal ())
+ openuri = gxdp_open_uri_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ NULL,
+ &error);
+
+ if (openuri == NULL)
{
- g_task_report_new_error (NULL, callback, user_data, NULL,
- G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
- "OpenURI portal is not available");
+ g_prefix_error (&error, "Failed to create OpenURI proxy: ");
+ g_task_report_error (NULL, callback, user_data, NULL, error);
return;
}
@@ -291,7 +304,6 @@ g_openuri_portal_open_file_async (GFile *file,
sender[i] = '_';
handle = g_strdup_printf ("/org/freedesktop/portal/desktop/request/%s/%s", sender, token);
- g_object_set_data_full (G_OBJECT (task), "handle", handle, g_free);
g_free (sender);
signal_id = g_dbus_connection_signal_subscribe (connection,
@@ -304,7 +316,6 @@ g_openuri_portal_open_file_async (GFile *file,
response_received,
task,
NULL);
- g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id));
g_variant_builder_init_static (&opt_builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token));
@@ -316,9 +327,18 @@ g_openuri_portal_open_file_async (GFile *file,
g_variant_new_string (startup_id));
opts = g_variant_builder_end (&opt_builder);
+
+ call_data = call_data_new ();
+ call_data->proxy = g_object_ref (openuri);
+ call_data->response_handle = g_steal_pointer (&handle);
+ call_data->response_signal_id = signal_id;
+ g_task_set_task_data (task, call_data, call_data_free);
}
else
- task = NULL;
+ {
+ call_data = NULL;
+ task = NULL;
+ }
if (g_file_is_native (file))
{
@@ -326,17 +346,19 @@ g_openuri_portal_open_file_async (GFile *file,
GUnixFDList *fd_list = NULL;
int fd, fd_id, errsv;
- if (task)
- g_object_set_data (G_OBJECT (task), "open-file", GINT_TO_POINTER (TRUE));
+ if (call_data)
+ call_data->open_file = TRUE;
path = g_file_get_path (file);
fd = g_open (path, O_RDONLY | O_CLOEXEC);
errsv = errno;
if (fd == -1)
{
+ g_clear_object (&task);
g_task_report_new_error (NULL, callback, user_data, NULL,
G_IO_ERROR, g_io_error_from_errno (errsv),
- "OpenURI portal is not available");
+ "Failed to open ā€˜%sā€™: %s", path, g_strerror (errsv));
+ g_clear_object (&openuri);
return;
}
@@ -373,6 +395,8 @@ g_openuri_portal_open_file_async (GFile *file,
task);
g_free (uri);
}
+
+ g_clear_object (&openuri);
}
gboolean