diff options
Diffstat (limited to 'gio/gopenuriportal.c')
-rw-r--r-- | gio/gopenuriportal.c | 158 |
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 |