Merge branch 'jsparber/open_uri_activation_token' into 'main'

gappinfo: Pass activation token from launch context to open_uri/file portal

Closes #2868

See merge request GNOME/glib!3933
This commit is contained in:
Philip Withnall
2024-08-14 14:16:40 +00:00
3 changed files with 101 additions and 43 deletions

View File

@@ -25,6 +25,7 @@
#include "gappinfo.h" #include "gappinfo.h"
#include "gappinfoprivate.h" #include "gappinfoprivate.h"
#include "gcontextspecificgroup.h" #include "gcontextspecificgroup.h"
#include "gdesktopappinfo.h"
#include "gtask.h" #include "gtask.h"
#include "gcancellable.h" #include "gcancellable.h"
@@ -1203,15 +1204,34 @@ g_app_info_launch_default_for_uri (const char *uri,
#ifdef G_OS_UNIX #ifdef G_OS_UNIX
if (!res && glib_should_use_portal ()) if (!res && glib_should_use_portal ())
{ {
GFile *file = NULL;
const char *parent_window = NULL; const char *parent_window = NULL;
char *startup_id = NULL;
/* Reset any error previously set by launch_default_for_uri */ /* Reset any error previously set by launch_default_for_uri */
g_clear_error (error); g_clear_error (error);
if (launch_context && launch_context->priv->envp) file = g_file_new_for_uri (uri);
parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID");
return g_openuri_portal_open_uri (uri, parent_window, error); if (launch_context)
{
GList *file_list;
if (launch_context->priv->envp)
parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID");
file_list = g_list_prepend (NULL, file);
startup_id = g_app_launch_context_get_startup_notify_id (launch_context,
NULL,
file_list);
g_list_free (file_list);
}
res = g_openuri_portal_open_file (file, parent_window, startup_id, error);
g_object_unref (file);
g_free (startup_id);
} }
#endif #endif
@@ -1241,7 +1261,7 @@ launch_default_for_uri_portal_open_uri_cb (GObject *object,
GTask *task = G_TASK (user_data); GTask *task = G_TASK (user_data);
GError *error = NULL; GError *error = NULL;
if (g_openuri_portal_open_uri_finish (result, &error)) if (g_openuri_portal_open_file_finish (result, &error))
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
else else
g_task_return_error (task, g_steal_pointer (&error)); g_task_return_error (task, g_steal_pointer (&error));
@@ -1258,20 +1278,40 @@ launch_default_for_uri_portal_open_uri (GTask *task, GError *error)
if (glib_should_use_portal ()) if (glib_should_use_portal ())
{ {
GFile *file;
const char *parent_window = NULL; const char *parent_window = NULL;
char *startup_id = NULL;
/* Reset any error previously set by launch_default_for_uri */ /* Reset any error previously set by launch_default_for_uri */
g_error_free (error); g_error_free (error);
if (data->context && data->context->priv->envp) file = g_file_new_for_uri (data->uri);
parent_window = g_environ_getenv (data->context->priv->envp,
"PARENT_WINDOW_ID"); if (data->context)
{
GList *file_list;
if (data->context->priv->envp)
parent_window = g_environ_getenv (data->context->priv->envp,
"PARENT_WINDOW_ID");
file_list = g_list_prepend (NULL, file);
startup_id = g_app_launch_context_get_startup_notify_id (data->context,
NULL,
file_list);
g_list_free (file_list);
}
g_openuri_portal_open_file_async (file,
parent_window,
startup_id,
cancellable,
launch_default_for_uri_portal_open_uri_cb,
g_steal_pointer (&task));
g_object_unref (file);
g_free (startup_id);
g_openuri_portal_open_uri_async (data->uri,
parent_window,
cancellable,
launch_default_for_uri_portal_open_uri_cb,
g_steal_pointer (&task));
return; return;
} }
#endif #endif
@@ -1775,8 +1815,8 @@ g_app_launch_context_get_display (GAppLaunchContext *context,
/** /**
* g_app_launch_context_get_startup_notify_id: * g_app_launch_context_get_startup_notify_id:
* @context: the launch context * @context: the launch context
* @info: the app info * @info: (nullable): the app info
* @files: (element-type GFile): list of [iface@Gio.File] objects * @files: (nullable) (element-type GFile): a list of [iface@Gio.File] objects
* *
* Initiates startup notification for the application and returns the * Initiates startup notification for the application and returns the
* `XDG_ACTIVATION_TOKEN` or `DESKTOP_STARTUP_ID` for the launched operation, * `XDG_ACTIVATION_TOKEN` or `DESKTOP_STARTUP_ID` for the launched operation,
@@ -1791,6 +1831,8 @@ g_app_launch_context_get_display (GAppLaunchContext *context,
* [freedesktop.org Startup Notification Protocol](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt). * [freedesktop.org Startup Notification Protocol](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt).
* *
* Support for the XDG Activation Protocol was added in GLib 2.76. * Support for the XDG Activation Protocol was added in GLib 2.76.
* Since GLib 2.82 @info and @files can be `NULL`. If thats not supported by the backend,
* the returned token will be `NULL`.
* *
* Returns: (nullable): a startup notification ID for the application, or `NULL` if * Returns: (nullable): a startup notification ID for the application, or `NULL` if
* not supported. * not supported.
@@ -1803,7 +1845,7 @@ g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
GAppLaunchContextClass *class; GAppLaunchContextClass *class;
g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL); g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
g_return_val_if_fail (G_IS_APP_INFO (info), NULL); g_return_val_if_fail (info == NULL || G_IS_APP_INFO (info), NULL);
class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context); class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);

View File

@@ -80,11 +80,11 @@ init_openuri_portal (void)
} }
gboolean gboolean
g_openuri_portal_open_uri (const char *uri, g_openuri_portal_open_file (GFile *file,
const char *parent_window, const char *parent_window,
GError **error) const char *startup_id,
GError **error)
{ {
GFile *file = NULL;
GVariantBuilder opt_builder; GVariantBuilder opt_builder;
gboolean res; gboolean res;
@@ -97,7 +97,11 @@ g_openuri_portal_open_uri (const char *uri,
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 (startup_id)
g_variant_builder_add (&opt_builder, "{sv}",
"activation_token",
g_variant_new_string (startup_id));
if (g_file_is_native (file)) if (g_file_is_native (file))
{ {
char *path = NULL; char *path = NULL;
@@ -138,6 +142,10 @@ g_openuri_portal_open_uri (const char *uri,
} }
else else
{ {
char *uri = NULL;
uri = g_file_get_uri (file);
res = gxdp_open_uri_call_open_uri_sync (openuri, res = gxdp_open_uri_call_open_uri_sync (openuri,
parent_window ? parent_window : "", parent_window ? parent_window : "",
uri, uri,
@@ -145,10 +153,9 @@ g_openuri_portal_open_uri (const char *uri,
NULL, NULL,
NULL, NULL,
error); error);
g_free (uri);
} }
g_object_unref (file);
return res; return res;
} }
@@ -245,15 +252,15 @@ open_call_done (GObject *source,
} }
void void
g_openuri_portal_open_uri_async (const char *uri, g_openuri_portal_open_file_async (GFile *file,
const char *parent_window, const char *parent_window,
GCancellable *cancellable, const char *startup_id,
GAsyncReadyCallback callback, GCancellable *cancellable,
gpointer user_data) GAsyncReadyCallback callback,
gpointer user_data)
{ {
GDBusConnection *connection; GDBusConnection *connection;
GTask *task; GTask *task;
GFile *file;
GVariant *opts = NULL; GVariant *opts = NULL;
int i; int i;
guint signal_id; guint signal_id;
@@ -303,12 +310,16 @@ g_openuri_portal_open_uri_async (const char *uri,
g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token)); g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token));
g_free (token); g_free (token);
if (startup_id)
g_variant_builder_add (&opt_builder, "{sv}",
"activation_token",
g_variant_new_string (startup_id));
opts = g_variant_builder_end (&opt_builder); opts = g_variant_builder_end (&opt_builder);
} }
else else
task = NULL; task = NULL;
file = g_file_new_for_uri (uri);
if (g_file_is_native (file)) if (g_file_is_native (file))
{ {
char *path = NULL; char *path = NULL;
@@ -349,6 +360,10 @@ g_openuri_portal_open_uri_async (const char *uri,
} }
else else
{ {
char *uri = NULL;
uri = g_file_get_uri (file);
gxdp_open_uri_call_open_uri (openuri, gxdp_open_uri_call_open_uri (openuri,
parent_window ? parent_window : "", parent_window ? parent_window : "",
uri, uri,
@@ -356,14 +371,13 @@ g_openuri_portal_open_uri_async (const char *uri,
cancellable, cancellable,
task ? open_call_done : NULL, task ? open_call_done : NULL,
task); task);
g_free (uri);
} }
g_object_unref (file);
} }
gboolean gboolean
g_openuri_portal_open_uri_finish (GAsyncResult *result, g_openuri_portal_open_file_finish (GAsyncResult *result,
GError **error) GError **error)
{ {
return g_task_propagate_boolean (G_TASK (result), error); return g_task_propagate_boolean (G_TASK (result), error);
} }

View File

@@ -25,18 +25,20 @@
G_BEGIN_DECLS G_BEGIN_DECLS
gboolean g_openuri_portal_open_uri (const char *uri, gboolean g_openuri_portal_open_file (GFile *file,
const char *parent_window, const char *parent_window,
GError **error); const char *startup_id,
GError **error);
void g_openuri_portal_open_uri_async (const char *uri, void g_openuri_portal_open_file_async (GFile *file,
const char *parent_window, const char *parent_window,
GCancellable *cancellable, const char *startup_id,
GAsyncReadyCallback callback, GCancellable *cancellable,
gpointer user_data); GAsyncReadyCallback callback,
gpointer user_data);
gboolean g_openuri_portal_open_uri_finish (GAsyncResult *result, gboolean g_openuri_portal_open_file_finish (GAsyncResult *result,
GError **error); GError **error);
G_END_DECLS G_END_DECLS