From 1df5857b077fa388fe037f36ba10a08833dd39eb Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Tue, 1 Aug 2023 14:04:31 +0200 Subject: [PATCH] filelauncher: Add 'always-ask' property The 'ask' property is part of the portal. It forces always asking the user with which app to open a file. Closes #5942 --- gtk/gtkfilelauncher.c | 69 ++++++++++++++++++++++++++++++++++++++++-- gtk/gtkfilelauncher.h | 5 +++ gtk/gtkopenuriportal.c | 7 +++++ gtk/gtkopenuriportal.h | 1 + 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/gtk/gtkfilelauncher.c b/gtk/gtkfilelauncher.c index 8ff3a08ae4..1536883030 100644 --- a/gtk/gtkfilelauncher.c +++ b/gtk/gtkfilelauncher.c @@ -52,10 +52,12 @@ struct _GtkFileLauncher GObject parent_instance; GFile *file; + unsigned int always_ask : 1; }; enum { PROP_FILE = 1, + PROP_ALWAYS_ASK = 2, NUM_PROPERTIES }; @@ -93,6 +95,10 @@ gtk_file_launcher_get_property (GObject *object, g_value_set_object (value, self->file); break; + case PROP_ALWAYS_ASK: + g_value_set_boolean (value, self->always_ask); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -113,6 +119,10 @@ gtk_file_launcher_set_property (GObject *object, gtk_file_launcher_set_file (self, g_value_get_object (value)); break; + case PROP_ALWAYS_ASK: + gtk_file_launcher_set_always_ask (self, g_value_get_boolean (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -140,6 +150,19 @@ gtk_file_launcher_class_init (GtkFileLauncherClass *class) G_TYPE_FILE, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkFileLauncher:always-ask: (attributes org.gtk.Property.get=gtk_file_launcher_get_always_ask org.gtk.Property.set=gtk_file_launcher_set_always_ask) + * + * Whether to ask the user to choose an app for opening the file. If `FALSE`, + * the file might be opened with a default app or the previous choice. + * + * Since: 4.12 + */ + properties[PROP_ALWAYS_ASK] = + g_param_spec_boolean ("always-ask", NULL, NULL, + FALSE, + G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } @@ -207,6 +230,48 @@ gtk_file_launcher_set_file (GtkFileLauncher *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILE]); } +/** + * gtk_file_launcher_get_always_ask: + * @self: a `GtkFileLauncher` + * + * Returns whether to ask the user to choose an app for opening the file. + * + * Returns: `TRUE` if always asking for app + * + * Since: 4.12 + */ +gboolean +gtk_file_launcher_get_always_ask (GtkFileLauncher *self) +{ + g_return_val_if_fail (GTK_IS_FILE_LAUNCHER (self), FALSE); + + return self->always_ask; +} + +/** + * gtk_file_launcher_set_always_ask: + * @self: a `GtkFileLauncher` + * @always_ask: a `gboolean` + * + * Sets whether to awlays ask the user to choose an app for opening the file. + * If `FALSE`, the file might be opened with a default app or the previous choice. + * + * Since: 4.12 + */ +void +gtk_file_launcher_set_always_ask (GtkFileLauncher *self, + gboolean always_ask) +{ + g_return_if_fail (GTK_IS_FILE_LAUNCHER (self)); + + if (self->always_ask == always_ask) + return; + + self->always_ask = always_ask; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ALWAYS_ASK]); +} + /* }}} */ /* {{{ Async implementation */ @@ -368,7 +433,7 @@ gtk_file_launcher_launch (GtkFileLauncher *self, #ifndef G_OS_WIN32 if (gtk_openuri_portal_is_available ()) { - gtk_openuri_portal_open_async (self->file, FALSE, parent, cancellable, open_done, task); + gtk_openuri_portal_open_async (self->file, FALSE, self->always_ask, parent, cancellable, open_done, task); } else #endif @@ -462,7 +527,7 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self, #ifndef G_OS_WIN32 if (gtk_openuri_portal_is_available ()) { - gtk_openuri_portal_open_async (self->file, TRUE, parent, cancellable, open_done, task); + gtk_openuri_portal_open_async (self->file, TRUE, FALSE, parent, cancellable, open_done, task); } else #endif diff --git a/gtk/gtkfilelauncher.h b/gtk/gtkfilelauncher.h index 2c5a3e665c..129ca35515 100644 --- a/gtk/gtkfilelauncher.h +++ b/gtk/gtkfilelauncher.h @@ -40,6 +40,11 @@ GFile * gtk_file_launcher_get_file (GtkFileLaunche GDK_AVAILABLE_IN_4_10 void gtk_file_launcher_set_file (GtkFileLauncher *self, GFile *file); +GDK_AVAILABLE_IN_4_12 +gboolean gtk_file_launcher_get_always_ask (GtkFileLauncher *self); +GDK_AVAILABLE_IN_4_12 +void gtk_file_launcher_set_always_ask (GtkFileLauncher *self, + gboolean always_ask); GDK_AVAILABLE_IN_4_10 void gtk_file_launcher_launch (GtkFileLauncher *self, diff --git a/gtk/gtkopenuriportal.c b/gtk/gtkopenuriportal.c index 67778affda..e41305acd5 100644 --- a/gtk/gtkopenuriportal.c +++ b/gtk/gtkopenuriportal.c @@ -112,6 +112,7 @@ typedef struct { GFile *file; char *uri; gboolean open_folder; + gboolean always_ask; GDBusConnection *connection; GCancellable *cancellable; GTask *task; @@ -275,6 +276,7 @@ open_uri (OpenUriData *data, { GFile *file = data->file; gboolean open_folder = data->open_folder; + gboolean always_ask = data->always_ask; GTask *task; GVariant *opts = NULL; int i; @@ -319,6 +321,9 @@ open_uri (OpenUriData *data, if (activation_token) g_variant_builder_add (&opt_builder, "{sv}", "activation_token", g_variant_new_string (activation_token)); + if (always_ask && !open_folder) + g_variant_builder_add (&opt_builder, "{sv}", "ask", g_variant_new_boolean (always_ask)); + opts = g_variant_builder_end (&opt_builder); if (file && g_file_is_native (file)) @@ -453,6 +458,7 @@ window_handle_exported (GtkWindow *window, void gtk_openuri_portal_open_async (GFile *file, gboolean open_folder, + gboolean always_ask, GtkWindow *parent, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -472,6 +478,7 @@ gtk_openuri_portal_open_async (GFile *file, data->parent = parent ? g_object_ref (parent) : NULL; data->file = g_object_ref (file); data->open_folder = open_folder; + data->always_ask = always_ask; data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; data->task = g_task_new (parent, cancellable, callback, user_data); g_task_set_check_cancellable (data->task, FALSE); diff --git a/gtk/gtkopenuriportal.h b/gtk/gtkopenuriportal.h index 9d7d0fca37..9eb153fb8e 100644 --- a/gtk/gtkopenuriportal.h +++ b/gtk/gtkopenuriportal.h @@ -30,6 +30,7 @@ gboolean gtk_openuri_portal_is_available (void); void gtk_openuri_portal_open_async (GFile *file, gboolean open_folder, + gboolean always_ask, GtkWindow *window, GCancellable *cancellable, GAsyncReadyCallback callback,