[console] terminal: make FM1 calls asynchronously



commit 9db9f38bf305fdd8220760ec6587d4278dc1c979
Author: Zander Brown <zbrown gnome org>
Date:   Wed Aug 24 00:55:36 2022 +0100

    terminal: make FM1 calls asynchronously
    
    Especially if Nautilus wasn't already running this could lock the UI,
    admittedly the user is switching away but nevertheless we should be
    graceful
    
    Also fix the action name

 src/kgx-terminal.c                   | 124 +++++++++++++++++++++++++----------
 src/meson.build                      |   6 ++
 src/org.freedesktop.FileManager1.xml |  33 ++++++++++
 3 files changed, 128 insertions(+), 35 deletions(-)
---
diff --git a/src/kgx-terminal.c b/src/kgx-terminal.c
index 33956e6..49a2810 100644
--- a/src/kgx-terminal.c
+++ b/src/kgx-terminal.c
@@ -32,6 +32,7 @@
 #include <pcre2.h>
 
 #include "rgba.h"
+#include "xdg-fm1.h"
 
 #include "kgx-config.h"
 #include "kgx-terminal.h"
@@ -383,57 +384,110 @@ select_all_activated (KgxTerminal *self)
 }
 
 
+typedef struct {
+  GStrv     uris;
+  gboolean  show_folders;
+} ShowData;
+
+
 static void
-show_in_files_activated (KgxTerminal *self)
+clear_show_data (gpointer data)
+{
+  ShowData *self = data;
+
+  g_clear_pointer (&self->uris, g_strfreev);
+  g_free (self);
+}
+
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (ShowData, clear_show_data)
+
+
+static void
+complete_call (GObject *source, GAsyncResult *res, gpointer data)
 {
-  g_autoptr (GDBusProxy) proxy = NULL;
-  g_autoptr (GVariant) retval = NULL;
-  g_autoptr (GVariantBuilder) builder = NULL;
   g_autoptr (GError) error = NULL;
-  const char *uri = NULL;
-  const char *method;
+  g_autoptr (ShowData) show = data;
 
-  uri = vte_terminal_get_current_file_uri (VTE_TERMINAL (self));
-  method = "ShowItems";
+  if (show->show_folders) {
+    xdg_file_manager1_call_show_folders_finish (XDG_FILE_MANAGER1 (source),
+                                                res,
+                                                &error);
+  } else {
+    xdg_file_manager1_call_show_items_finish (XDG_FILE_MANAGER1 (source),
+                                              res,
+                                              &error);
+  }
 
-  if (uri == NULL) {
-    uri = vte_terminal_get_current_directory_uri (VTE_TERMINAL (self));
-    method = "ShowFolders";
+  if (error) {
+    g_warning ("term.show-in-files: D-Bus call failed %s", error->message);
   }
+}
 
-  if (uri == NULL) {
-    g_warning ("win.show-in-files: no file");
+
+static void
+got_proxy (GObject *source, GAsyncResult *res, gpointer data)
+{
+  g_autoptr (GError) error = NULL;
+  g_autoptr (XdgFileManager1) fm = NULL;
+  g_autoptr (ShowData) show = data;
+  g_auto (GStrv) uris = g_steal_pointer (&show->uris);
+
+  fm = xdg_file_manager1_proxy_new_finish (res, &error);
+
+  if (error) {
+    g_warning ("term.show-in-files: D-Bus connect failed %s", error->message);
     return;
   }
 
-  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                         G_DBUS_PROXY_FLAGS_NONE,
+  if (show->show_folders) {
+    xdg_file_manager1_call_show_folders (fm,
+                                         (const char *const *) uris,
+                                         "",
                                          NULL,
-                                         "org.freedesktop.FileManager1",
-                                         "/org/freedesktop/FileManager1",
-                                         "org.freedesktop.FileManager1",
-                                         NULL, &error);
-
-  if (!proxy) {
-    g_warning ("win.show-in-files: D-Bus connect failed %s", error->message);
-    return;
+                                         complete_call,
+                                         g_steal_pointer (&show));
+  } else {
+    xdg_file_manager1_call_show_items (fm,
+                                       (const char *const *) uris,
+                                       "",
+                                       NULL,
+                                       complete_call,
+                                       g_steal_pointer (&show));
   }
+}
 
-  builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
-  g_variant_builder_add (builder, "s", uri);
 
-  retval = g_dbus_proxy_call_sync (proxy,
-                                   method,
-                                   g_variant_new ("(ass)",
-                                                  builder,
-                                                  ""),
-                                   G_DBUS_CALL_FLAGS_NONE,
-                                   -1, NULL, &error);
+static void
+show_in_files_activated (KgxTerminal *self)
+{
+  g_autoptr (ShowData) data = g_new0 (ShowData, 1);
+  g_autoptr (GStrvBuilder) builder = g_strv_builder_new ();
+  const char *uri = NULL;
+
+  data->show_folders = FALSE;
+  uri = vte_terminal_get_current_file_uri (VTE_TERMINAL (self));
 
-  if (!retval) {
-    g_warning ("win.show-in-files: D-Bus call failed %s", error->message);
+  if (uri == NULL) {
+    data->show_folders = TRUE;
+    uri = vte_terminal_get_current_directory_uri (VTE_TERMINAL (self));
+  }
+
+  if (uri == NULL) {
+    g_warning ("term.show-in-files: no file");
     return;
   }
+
+  g_strv_builder_add (builder, uri);
+  data->uris = g_strv_builder_end (builder);
+
+  xdg_file_manager1_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                       G_DBUS_PROXY_FLAGS_NONE,
+                                       "org.freedesktop.FileManager1",
+                                       "/org/freedesktop/FileManager1",
+                                       NULL,
+                                       got_proxy,
+                                       g_steal_pointer (&data));
 }
 
 
@@ -661,7 +715,7 @@ location_changed (KgxTerminal *self)
   value = vte_terminal_get_current_file_uri (VTE_TERMINAL (self)) ||
             vte_terminal_get_current_directory_uri (VTE_TERMINAL (self));
 
-  gtk_widget_action_set_enabled (GTK_WIDGET (self), "term.show-in-file", value);
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "term.show-in-files", value);
 
   g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_PATH]);
 }
diff --git a/src/meson.build b/src/meson.build
index c5fabce..1118019 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -57,6 +57,12 @@ kgx_sources += gnome.compile_resources('kgx-resources',
   c_name: 'kgx'
 )
 
+kgx_sources += gnome.gdbus_codegen('xdg-fm1',
+           sources: 'org.freedesktop.FileManager1.xml',
+  interface_prefix: 'org.freedesktop.',
+         namespace: 'Xdg',
+)
+
 kgx_enums = gnome.mkenums_simple('kgx-enums',
                                     sources: [
                                       'kgx-close-dialog.h',
diff --git a/src/org.freedesktop.FileManager1.xml b/src/org.freedesktop.FileManager1.xml
new file mode 100644
index 0000000..7f03e86
--- /dev/null
+++ b/src/org.freedesktop.FileManager1.xml
@@ -0,0 +1,33 @@
+<!DOCTYPE node PUBLIC
+      "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+      "https://dbus.freedesktop.org/doc/introspect.dtd"; >
+<!--
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+-->
+<node>
+  <interface name='org.freedesktop.FileManager1'>
+    <method name='ShowFolders'>
+      <arg type='as' name='URIs' direction='in'/>
+      <arg type='s' name='StartupId' direction='in'/>
+    </method>
+    <method name='ShowItems'>
+      <arg type='as' name='URIs' direction='in'/>
+      <arg type='s' name='StartupId' direction='in'/>
+    </method>
+    <method name='ShowItemProperties'>
+      <arg type='as' name='URIs' direction='in'/>
+      <arg type='s' name='StartupId' direction='in'/>
+    </method>
+  </interface>
+</node>


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