filelauncher: Add 'always-ask' property
authorSophie Herold <sophie@hemio.de>
Tue, 1 Aug 2023 12:04:31 +0000 (14:04 +0200)
committerSophie Herold <sophie@hemio.de>
Tue, 1 Aug 2023 18:39:20 +0000 (20:39 +0200)
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
gtk/gtkfilelauncher.h
gtk/gtkopenuriportal.c
gtk/gtkopenuriportal.h

index 8ff3a08ae4ea4690c71df3dccdd3a91b6006906e..15368830308c626934fbbc42b3690a7abebf6828 100644 (file)
@@ -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
index 2c5a3e665c19d32871461f9fcd928bd22544835b..129ca35515d379377a67400f4bc7989e5bbb4663 100644 (file)
@@ -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,
index 67778affda10aae622e4f248c20a6a6fdf018690..e41305acd5d8522e17ca6cd2917318e2772f2c83 100644 (file)
@@ -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);
index 9d7d0fca3710968a73f934e06764676cb9b16c02..9eb153fb8e7aefac01556c2293126b856354e8e6 100644 (file)
@@ -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,