mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
appinfo: Launch the OpenURI portal using a synchronous D-Bus call
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. This should not be a problem as the method returns immediately (regardless of the user making a selection), but making it synchronous would prevent situations where the OpenURI method would never be called because of D-Bus dropping the message after the caller dies, without explicitly waiting for a reply. https://bugzilla.gnome.org/show_bug.cgi?id=780441
This commit is contained in:
parent
26e0b3dde4
commit
b374cc2e23
126
gio/gappinfo.c
126
gio/gappinfo.c
@ -36,6 +36,12 @@
|
|||||||
#include "gportalsupport.h"
|
#include "gportalsupport.h"
|
||||||
#endif
|
#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"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gappinfo
|
* SECTION:gappinfo
|
||||||
@ -745,6 +751,38 @@ open_uri_done (GObject *source,
|
|||||||
g_variant_unref (res);
|
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
|
static void
|
||||||
launch_default_with_portal_async (const char *uri,
|
launch_default_with_portal_async (const char *uri,
|
||||||
GAppLaunchContext *context,
|
GAppLaunchContext *context,
|
||||||
@ -755,7 +793,6 @@ launch_default_with_portal_async (const char *uri,
|
|||||||
GDBusConnection *session_bus;
|
GDBusConnection *session_bus;
|
||||||
GVariantBuilder opt_builder;
|
GVariantBuilder opt_builder;
|
||||||
const char *parent_window = NULL;
|
const char *parent_window = NULL;
|
||||||
GFile *file;
|
|
||||||
char *real_uri;
|
char *real_uri;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
GAsyncReadyCallback dbus_callback;
|
GAsyncReadyCallback dbus_callback;
|
||||||
@ -771,28 +808,15 @@ launch_default_with_portal_async (const char *uri,
|
|||||||
if (context && context->priv->envp)
|
if (context && context->priv->envp)
|
||||||
parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
|
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);
|
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
|
||||||
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);
|
|
||||||
g_object_unref (session_bus);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_unref (file);
|
|
||||||
real_uri = g_strdup (uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
task = g_task_new (context, cancellable, callback, user_data);
|
task = g_task_new (context, cancellable, callback, user_data);
|
||||||
@ -825,12 +849,70 @@ launch_default_with_portal_async (const char *uri,
|
|||||||
g_free (real_uri);
|
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
|
static gboolean
|
||||||
launch_default_with_portal (const char *uri,
|
launch_default_with_portal (const char *uri,
|
||||||
GAppLaunchContext *context,
|
GAppLaunchContext *context,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
launch_default_with_portal_async (uri, context, NULL, NULL, NULL);
|
launch_default_with_portal_sync (uri, context);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user