[file-roller] Use open uri portal instead of GtkAppChooserDialog



commit d0ec54a22babf10dd0c337fc39bda52e500db7d2
Author: Maximiliano Sandoval R <msandova protonmail com>
Date:   Fri Jul 23 12:59:34 2021 +0200

    Use open uri portal instead of GtkAppChooserDialog
    
    Fixes: https://gitlab.gnome.org/GNOME/file-roller/-/issues/105

 README.md                         |  2 ++
 default.nix                       |  1 +
 flatpak/org.gnome.FileRoller.json | 16 ++++++++++
 meson.build                       |  5 +++
 meson_options.txt                 |  8 +++++
 src/dlg-open-with.c               | 67 +++++++++++++++++++++++++++++++++++++--
 src/fr-window.c                   | 51 ++++++++++++++++++++++++++++-
 src/meson.build                   |  2 ++
 8 files changed, 148 insertions(+), 4 deletions(-)
---
diff --git a/README.md b/README.md
index 48fe1934..1d7232d0 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,8 @@ Also you need the following libraries:
 
 * glib >= 2.38
 * gtk+ >= 3.22.0
+* libportal >= 0.5
+* libportal-gtk3 >= 0.5
 * libnautilus-extension >= 3.28.0 (optional)
 * libarchive >= 3.1.900a (optional)
 
diff --git a/default.nix b/default.nix
index d3b581ce..340dff8a 100644
--- a/default.nix
+++ b/default.nix
@@ -112,6 +112,7 @@ makeDerivation rec {
     json-glib
     libarchive
     libhandy
+    libportal-gtk3
   ];
 
   inherit doCheck;
diff --git a/flatpak/org.gnome.FileRoller.json b/flatpak/org.gnome.FileRoller.json
index 3fc763c1..f605fab7 100644
--- a/flatpak/org.gnome.FileRoller.json
+++ b/flatpak/org.gnome.FileRoller.json
@@ -107,6 +107,22 @@
                 }
             ]
         },
+        {
+            "name": "libportal",
+            "buildsystem": "meson",
+            "builddir": true,
+            "config-opts": [
+                "-Ddocs=false",
+                "-Dbackends=gtk3"
+            ],
+            "sources" : [
+                {
+                    "type": "git",
+                    "url": "https://github.com/flatpak/libportal.git";,
+                    "branch": "main"
+                }
+            ]
+        },
         {
             "name" : "file-roller",
             "buildsystem" : "meson",
diff --git a/meson.build b/meson.build
index 4bb09ab9..1304bbd9 100644
--- a/meson.build
+++ b/meson.build
@@ -22,12 +22,16 @@ c_comp = meson.get_compiler('c')
 
 # Dependencies
 
+use_native_appchooser = get_option('use_native_appchooser')
+
 libm_dep = c_comp.find_library('m')
 thread_dep = dependency('threads')
 glib_dep = dependency('glib-2.0', version : glib_version)
 gthread_dep = dependency('gthread-2.0')
 gtk_dep = dependency('gtk+-3.0', version : gtk_version)
 hdy_dep = dependency('libhandy-1', version: hdy_version)
+libportal_dep = dependency('libportal', version: '>= 0.5', required: use_native_appchooser)
+libportal_gtk3_dep = dependency('libportal-gtk3', version: '>= 0.5', required: use_native_appchooser)
 
 # Optional dependencies
 use_gobject_introspection = get_option('introspection')
@@ -92,6 +96,7 @@ if have_mkdtemp
   config_data.set('HAVE_MKDTEMP', 1)
 endif
 config_data.set_quoted('CPIO_PATH', cpio_path)
+config_data.set('USE_NATIVE_APPCHOOSER', use_native_appchooser)
 config_file = configure_file(output : 'config.h', configuration : config_data)
 config_inc = include_directories('.')
 
diff --git a/meson_options.txt b/meson_options.txt
index 6040c516..4bd69b6d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -16,6 +16,14 @@ option('notification',
   description : 'Enable operation completion notification'
 )
 
+option('use_native_appchooser',
+  type : 'boolean',
+  value : true,
+  description : '''Whether to use desktop environment’s native app chooser via
+  XDG portal. Offers better desktop integration but ‘Open with…’ dialogue will
+  ask for each file individually, when opening multiple files.'''
+)
+
 option('packagekit',
   type : 'boolean', 
   value : true, 
diff --git a/src/dlg-open-with.c b/src/dlg-open-with.c
index 7000bb57..e8ebdbfa 100644
--- a/src/dlg-open-with.c
+++ b/src/dlg-open-with.c
@@ -29,6 +29,10 @@
 #include "fr-window.h"
 #include "dlg-open-with.h"
 
+#ifdef USE_NATIVE_APPCHOOSER
+# include <libportal/portal.h>
+# include <libportal-gtk3/portal-gtk3.h>
+#endif
 
 typedef struct {
        FrWindow *window;
@@ -36,6 +40,26 @@ typedef struct {
 } OpenData;
 
 
+#ifdef USE_NATIVE_APPCHOOSER
+static void
+open_with_portal_cb (GObject     *source_obj,
+                    GAsyncResult *result,
+                    gpointer      user_data)
+{
+       XdpPortal *portal = XDP_PORTAL (source_obj);
+       GtkWindow *window = GTK_WINDOW (user_data);
+       g_autoptr (GError) error = NULL;
+
+       if (!xdp_portal_open_uri_finish (portal, result, &error)
+           && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+       {
+               _gtk_error_dialog_run (GTK_WINDOW (window),
+                                      _("Could not perform the operation"),
+                                      "%s",
+                                      error->message);
+       }
+}
+#else
 static void
 app_chooser_response_cb (GtkDialog *dialog,
                         int        response_id,
@@ -66,10 +90,33 @@ app_chooser_response_cb (GtkDialog *dialog,
        }
 }
 
+#endif
 
-void
-dlg_open_with (FrWindow *window,
-              GList    *file_list)
+
+#ifdef USE_NATIVE_APPCHOOSER
+static void
+dlg_open_with_native_appchooser (FrWindow *window,
+                                GList    *file_list)
+{
+       GList     *scan;
+       g_autoptr(XdpParent) parent = NULL;
+       g_autoptr(XdpPortal) portal = NULL;
+
+       portal = xdp_portal_new ();
+       parent = xdp_parent_new_gtk (GTK_WINDOW (window));
+
+       for (scan = file_list; scan; scan = scan->next) {
+               g_autofree char *uri;
+               uri = g_file_get_uri (G_FILE (scan->data));
+               xdp_portal_open_uri (portal, parent, uri,
+                                    XDP_OPEN_URI_FLAG_ASK, NULL,
+                                    open_with_portal_cb, window);
+       }
+}
+#else
+static void
+dlg_open_with_nonnative_appchooser (FrWindow *window,
+                         GList    *file_list)
 {
        OpenData  *o_data;
        GtkWidget *app_chooser;
@@ -88,6 +135,20 @@ dlg_open_with (FrWindow *window,
        gtk_widget_show (app_chooser);
 }
 
+#endif
+
+
+void
+dlg_open_with (FrWindow *window,
+              GList    *file_list)
+{
+#ifdef USE_NATIVE_APPCHOOSER
+       dlg_open_with_native_appchooser (window, file_list);
+#else
+       dlg_open_with_nonnative_appchooser (window, file_list);
+#endif
+}
+
 
 void
 open_with_cb (GtkWidget *widget,
diff --git a/src/fr-window.c b/src/fr-window.c
index 0c06cb65..f448ae6c 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -9172,8 +9172,45 @@ monitor_extracted_files (OpenFilesData *odata)
 }
 
 
+#ifdef USE_NATIVE_APPCHOOSER
+static void
+open_extracted_files_with_native_appchooser (OpenFilesData *odata)
+{
+       GList               *file_list = odata->cdata->file_list;
+       GList               *scan;
+       GError              *error = NULL;
+       GtkWindow           *window;
+
+       g_return_if_fail (file_list != NULL);
+
+       if (file_list->data == NULL)
+               return;
+
+       window = GTK_WINDOW (odata->window);
+
+       if (! odata->window->archive->read_only)
+               monitor_extracted_files (odata);
+
+       if (odata->ask_application) {
+               dlg_open_with (odata->window, file_list);
+               return;
+       }
+
+       for (scan = file_list; scan; scan = scan->next) {
+               g_autofree char *uri;
+               uri = g_file_get_uri (G_FILE (scan->data));
+               if (!gtk_show_uri_on_window (window, uri, GDK_CURRENT_TIME, &error)) {
+                       _gtk_error_dialog_run (window,
+                                       _("Could not perform the operation"),
+                                       "%s",
+                                       error->message);
+                       g_clear_error (&error);
+               }
+       }
+}
+#else
 static gboolean
-fr_window_open_extracted_files (OpenFilesData *odata)
+open_extracted_files_with_nonnative_appchooser (OpenFilesData *odata)
 {
        GList               *file_list = odata->cdata->file_list;
        GFile               *first_file;
@@ -9251,6 +9288,18 @@ fr_window_open_extracted_files (OpenFilesData *odata)
 
        return result;
 }
+#endif
+
+
+static void
+fr_window_open_extracted_files (OpenFilesData *odata)
+{
+#ifdef USE_NATIVE_APPCHOOSER
+       open_extracted_files_with_native_appchooser (odata);
+#else
+       open_extracted_files_with_nonnative_appchooser (odata);
+#endif
+}
 
 
 static void
diff --git a/src/meson.build b/src/meson.build
index 7e75ae6c..1bf3f873 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -130,6 +130,8 @@ fr_exe = executable('file-roller',
     gthread_dep, 
     gtk_dep, 
     hdy_dep,
+    use_native_appchooser ? libportal_dep : [],
+    use_native_appchooser ? libportal_gtk3_dep : [],
     use_gobject_introspection ? gobject_introspection_dep : [],
     use_json_glib ? libjson_glib_dep : [],
     use_libarchive ? libarchive_dep : []


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]