[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Rework ThunarBrowser; resolve shortcut files asynchronously.

Jannis Pohlmann noreply at xfce.org
Sat Jul 2 17:26:01 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 6f7a86aef8ee7d68674efc201d47be69c33c9c95 (commit)
       from bff5a583ae363322fc548e6c5347e044e0d44510 (commit)

commit 6f7a86aef8ee7d68674efc201d47be69c33c9c95
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sat Jul 2 17:12:41 2011 +0200

    Rework ThunarBrowser; resolve shortcut files asynchronously.
    
    There now is a new method thunar_browser_poke_location() for resolving
    GFile objects into ThunarFiles, in addition to the already existing
    methods for resoling ThunarFiles and GVolumes.
    
    This method is used on ThunarShortcut and ThunarShortcutRow to lazy-load
    file information and resolve items once they are being clicked on. In
    combination with the new thunar_file_get_async() method introduced
    earlier, this should avoid all startup delays caused by the synchronous
    file loading used before.

 thunar/thunar-browser.c      |  448 +++++++++++++++++++++++++++++++++---------
 thunar/thunar-browser.h      |   59 ++++---
 thunar/thunar-shortcut-row.c |  101 ++++++----
 thunar/thunar-shortcut.c     |   59 ++++---
 4 files changed, 489 insertions(+), 178 deletions(-)

diff --git a/thunar/thunar-browser.c b/thunar/thunar-browser.c
index 988e8c4..d692189 100644
--- a/thunar/thunar-browser.c
+++ b/thunar/thunar-browser.c
@@ -34,13 +34,28 @@
 typedef struct _PokeFileData   PokeFileData;
 typedef struct _PokeVolumeData PokeVolumeData;
 
+
+
+static void thunar_browser_poke_file_internal (ThunarBrowser                *browser,
+                                               GFile                        *location,
+                                               ThunarFile                   *source,
+                                               ThunarFile                   *file,
+                                               gpointer                      widget,
+                                               ThunarBrowserPokeFileFunc     func,
+                                               ThunarBrowserPokeLocationFunc location_func,
+                                               gpointer                      user_data);
+
+
+
 struct _PokeFileData
 {
-  ThunarBrowser            *browser;
-  ThunarFile               *source;
-  ThunarFile               *file;
-  ThunarBrowserPokeFileFunc func;
-  gpointer                  user_data;
+  GFile                        *location;
+  ThunarBrowser                *browser;
+  ThunarFile                   *source;
+  ThunarFile                   *file;
+  ThunarBrowserPokeFileFunc     func;
+  ThunarBrowserPokeLocationFunc location_func;
+  gpointer                      user_data;
 };
 
 struct _PokeVolumeData
@@ -81,23 +96,33 @@ thunar_browser_get_type (void)
 
 
 static PokeFileData *
-thunar_browser_poke_file_data_new (ThunarBrowser            *browser,
-                                   ThunarFile               *source,
-                                   ThunarFile               *file,
-                                   ThunarBrowserPokeFileFunc func,
-                                   gpointer                  user_data)
+thunar_browser_poke_file_data_new (ThunarBrowser                *browser,
+                                   GFile                        *location,
+                                   ThunarFile                   *source,
+                                   ThunarFile                   *file,
+                                   ThunarBrowserPokeFileFunc     func,
+                                   ThunarBrowserPokeLocationFunc location_func,
+                                   gpointer                      user_data)
 {
   PokeFileData *poke_data;
 
   _thunar_return_val_if_fail (THUNAR_IS_BROWSER (browser), NULL);
-  _thunar_return_val_if_fail (THUNAR_IS_FILE (source), NULL);
-  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
   poke_data = g_slice_new0 (PokeFileData);
   poke_data->browser = g_object_ref (browser);
-  poke_data->source = g_object_ref (source);
-  poke_data->file = g_object_ref (file);
+
+  if (location != NULL)
+    poke_data->location = g_object_ref (location);
+
+  if (source != NULL)
+    poke_data->source = g_object_ref (source);
+
+  if (file != NULL)
+    poke_data->file = g_object_ref (file);
+
   poke_data->func = func;
+  poke_data->location_func = location_func;
+
   poke_data->user_data = user_data;
 
   return poke_data;
@@ -110,12 +135,15 @@ thunar_browser_poke_file_data_free (PokeFileData *poke_data)
 {
   _thunar_return_if_fail (poke_data != NULL);
   _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
-  _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->source));
-  _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file));
 
   g_object_unref (poke_data->browser);
-  g_object_unref (poke_data->source);
-  g_object_unref (poke_data->file);
+
+  if (poke_data->location != NULL)
+    g_object_unref (poke_data->location);
+  if (poke_data->source != NULL)
+    g_object_unref (poke_data->source);
+  if (poke_data->file != NULL)
+    g_object_unref (poke_data->file);
 
   g_slice_free (PokeFileData, poke_data);
 }
@@ -178,12 +206,48 @@ thunar_browser_mount_operation_new (gpointer parent)
 
 
 static void
+thunar_browser_poke_mountable_file_finish (GFile      *location,
+                                           ThunarFile *file,
+                                           GError     *error,
+                                           gpointer    user_data)
+{
+  PokeFileData *poke_data = user_data;
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (user_data != NULL);
+  _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
+  _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file));
+  _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->source));
+
+  g_debug ("thunar_browser_poke_mountable_file_finish");
+
+  if (poke_data->location_func != NULL)
+    {
+      (poke_data->location_func) (poke_data->browser,
+                                  poke_data->location,
+                                  poke_data->source, 
+                                  file, 
+                                  error,
+                                  poke_data->user_data);
+    }
+
+  if (poke_data->func != NULL)
+    {
+      (poke_data->func) (poke_data->browser, poke_data->source, file, error,
+                         poke_data->user_data);
+    }
+
+  thunar_browser_poke_file_data_free (poke_data);
+}
+
+
+
+static void
 thunar_browser_poke_mountable_finish (GObject      *object,
                                       GAsyncResult *result,
                                       gpointer      user_data)
 {
   PokeFileData *poke_data = user_data;
-  ThunarFile   *target = NULL;
   GError       *error = NULL;
   GFile        *location;
 
@@ -193,6 +257,8 @@ thunar_browser_poke_mountable_finish (GObject      *object,
   _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
   _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file));
 
+  g_debug ("thunar_browser_poke_mountable_finish");
+
   if (!g_file_mount_mountable_finish (G_FILE (object), result, &error))
     {
       if (error->domain == G_IO_ERROR)
@@ -207,22 +273,35 @@ thunar_browser_poke_mountable_finish (GObject      *object,
       thunar_file_reload (poke_data->file);
 
       location = thunar_file_get_target_location (poke_data->file);
-      target = thunar_file_get (location, &error);
+
+      /* resolve the ThunarFile for the target location asynchronously
+       * and defer cleaning up the poke data until that has finished */
+      thunar_file_get_async (location, NULL, 
+                             thunar_browser_poke_mountable_file_finish,
+                             poke_data);
+
       g_object_unref (location);
     }
-
-  if (poke_data->func != NULL)
+  else
     {
-      (poke_data->func) (poke_data->browser, poke_data->source, target, error, 
-                         poke_data->user_data);
-    }
-
-  g_clear_error (&error);
+      if (poke_data->location_func != NULL)
+        {
+          (poke_data->location_func) (poke_data->browser, 
+                                      poke_data->location,
+                                      poke_data->source, 
+                                      NULL,
+                                      error,
+                                      poke_data->user_data);
+        }
 
-  if (target != NULL)
-    g_object_unref (target);
+      if (poke_data->func != NULL)
+        {
+          (poke_data->func) (poke_data->browser, poke_data->source, NULL, error,
+                             poke_data->user_data);
+        }
 
-  thunar_browser_poke_file_data_free (poke_data);
+      thunar_browser_poke_file_data_free (poke_data);
+    }
 }
 
 
@@ -241,6 +320,8 @@ thunar_browser_poke_file_finish (GObject      *object,
   _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
   _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file));
 
+  g_debug ("thunar_browser_poke_file_finish");
+
   if (!g_file_mount_enclosing_volume_finish (G_FILE (object), result, &error))
     {
       if (error->domain == G_IO_ERROR)
@@ -253,6 +334,28 @@ thunar_browser_poke_file_finish (GObject      *object,
   if (error == NULL)
     thunar_file_reload (poke_data->file);
 
+  if (poke_data->location_func != NULL)
+    {
+      if (error == NULL)
+        {
+          (poke_data->location_func) (poke_data->browser, 
+                                      poke_data->location,
+                                      poke_data->source, 
+                                      poke_data->file, 
+                                      NULL, 
+                                      poke_data->user_data);
+        }
+      else
+        {
+          (poke_data->location_func) (poke_data->browser,
+                                      poke_data->location,
+                                      poke_data->source,
+                                      NULL,
+                                      error,
+                                      poke_data->user_data);
+        }
+    }
+
   if (poke_data->func != NULL)
     {
       if (error == NULL)
@@ -275,67 +378,116 @@ thunar_browser_poke_file_finish (GObject      *object,
 
 
 static void
-thunar_browser_poke_file_internal (ThunarBrowser            *browser,
-                                   ThunarFile               *source,
-                                   ThunarFile               *file,
-                                   gpointer                  widget,
-                                   ThunarBrowserPokeFileFunc func,
-                                   gpointer                  user_data)
+thunar_browser_poke_shortcut_file_finish (GFile *location,
+                                          ThunarFile *file,
+                                          GError *error,
+                                          gpointer user_data)
+{
+  PokeFileData *poke_data = user_data;
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (user_data != NULL);
+  _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
+  _thunar_return_if_fail (THUNAR_IS_FILE (poke_data->file));
+
+  g_debug ("thunar_browser_poke_shortcut_file_finish");
+
+  if (error == NULL)
+    {
+      thunar_browser_poke_file_internal (poke_data->browser,
+                                         poke_data->location,
+                                         poke_data->source,
+                                         file,
+                                         NULL,
+                                         poke_data->func,
+                                         poke_data->location_func,
+                                         poke_data->user_data);
+    }
+  else
+    {
+      if (poke_data->location_func != NULL)
+        {
+          (poke_data->location_func) (poke_data->browser,
+                                      poke_data->location,
+                                      poke_data->source,
+                                      NULL,
+                                      error, 
+                                      poke_data->user_data);
+        }
+
+      if (poke_data->func != NULL)
+        {
+          (poke_data->func) (poke_data->browser, poke_data->source, NULL, error, 
+                             poke_data->user_data);
+        }
+    }
+
+  thunar_browser_poke_file_data_free (poke_data);
+}
+
+
+
+static void
+thunar_browser_poke_file_internal (ThunarBrowser                *browser,
+                                   GFile                        *location,
+                                   ThunarFile                   *source,
+                                   ThunarFile                   *file,
+                                   gpointer                      widget,
+                                   ThunarBrowserPokeFileFunc     func,
+                                   ThunarBrowserPokeLocationFunc location_func,
+                                   gpointer                      user_data)
 {
   GMountOperation *mount_operation;
-  ThunarFile      *target;
   PokeFileData    *poke_data;
-  GError          *error = NULL;
-  GFile           *location;
+  GFile           *target;
 
   _thunar_return_if_fail (THUNAR_IS_BROWSER (browser));
+  _thunar_return_if_fail (G_IS_FILE (location));
   _thunar_return_if_fail (THUNAR_IS_FILE (source));
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
 
+  g_debug ("thunar_browser_poke_file_internal");
+
   if (thunar_file_get_kind (file) == G_FILE_TYPE_SHORTCUT)
     {
-      location = thunar_file_get_target_location (file);
-      target = thunar_file_get (location, &error);
-      g_object_unref (location);
+      g_debug ("  is shortcut");
 
-      if (target != NULL)
-        {
-          /* TODO in very rare occasions (shortcut X -> other shortcut -> shortcut X),
-           * this can lead to endless recursion  */
-          thunar_browser_poke_file_internal (browser, source, target, widget, 
-                                             func, user_data);
-        }
-      else
-        {
-          if (func != NULL)
-            func (browser, source, NULL, error, user_data);
-        }
+      target = thunar_file_get_target_location (file);
 
-      g_clear_error (&error);
+      poke_data = thunar_browser_poke_file_data_new (browser, location, source,
+                                                     file, func, NULL, user_data);
 
-      if (target != NULL)
-        g_object_unref (target);
+      thunar_file_get_async (target, NULL,
+                             thunar_browser_poke_shortcut_file_finish,
+                             poke_data);
+
+      g_object_unref (target);
     }
   else if (thunar_file_get_kind (file) == G_FILE_TYPE_MOUNTABLE)
     {
+      g_debug ("  is mountable");
+
       if (thunar_file_is_mounted (file))
         {
-          location = thunar_file_get_target_location (file);
-          target = thunar_file_get (location, &error);
-          g_object_unref (location);
+          g_debug ("  is mounted");
+
+          target = thunar_file_get_target_location (file);
 
-          if (func != NULL)
-            func (browser, source, target, error, user_data);
+          poke_data = thunar_browser_poke_file_data_new (browser, location, source,
+                                                         file, func, NULL, user_data);
 
-          g_clear_error (&error);
+          thunar_file_get_async (target, NULL,
+                                 thunar_browser_poke_mountable_file_finish,
+                                 poke_data);
 
-          if (target != NULL)
-            g_object_unref (target);
+          g_object_unref (target);
         }
       else
         {
-          poke_data = thunar_browser_poke_file_data_new (browser, source, file,
-                                                         func, user_data);
+          g_debug ("  is not mounted yet");
+
+          poke_data = thunar_browser_poke_file_data_new (browser, location, source,
+                                                         file, func, NULL, user_data);
 
           mount_operation = thunar_browser_mount_operation_new (widget);
 
@@ -349,8 +501,10 @@ thunar_browser_poke_file_internal (ThunarBrowser            *browser,
     }
   else if (!thunar_file_is_mounted (file))
     {
-      poke_data = thunar_browser_poke_file_data_new (browser, source, file,
-                                                     func, user_data);
+      g_debug ("  is file, not mounted yet");
+
+      poke_data = thunar_browser_poke_file_data_new (browser, location, source,
+                                                     file, func, NULL, user_data);
 
       mount_operation = thunar_browser_mount_operation_new (widget);
 
@@ -363,6 +517,11 @@ thunar_browser_poke_file_internal (ThunarBrowser            *browser,
     }
   else
     {
+      g_debug ("  is file, already mounted and loaded");
+
+      if (location_func != NULL)
+        location_func (browser, location, source, file, NULL, user_data);
+
       if (func != NULL)
         func (browser, source, file, NULL, user_data);
     }
@@ -403,7 +562,36 @@ thunar_browser_poke_file (ThunarBrowser            *browser,
   _thunar_return_if_fail (THUNAR_IS_BROWSER (browser));
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
 
-  thunar_browser_poke_file_internal (browser, file, file, widget, func, user_data);
+  g_debug ("thunar_browser_poke_file");
+
+  thunar_browser_poke_file_internal (browser, file->gfile, file, file, widget,
+                                     func, NULL, user_data);
+}
+
+
+
+static void
+thunar_browser_poke_volume_file_finish (GFile      *location,
+                                        ThunarFile *file,
+                                        GError     *error,
+                                        gpointer    user_data)
+{
+  PokeVolumeData *poke_data = user_data;
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (user_data != NULL);
+  _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
+  _thunar_return_if_fail (G_IS_VOLUME (poke_data->volume));
+
+  g_debug ("thunar_browser_poke_volume_file_finish");
+
+  if (poke_data->func != NULL)
+    {
+      (poke_data->func) (poke_data->browser, poke_data->volume, file, error,
+                         poke_data->user_data);
+    }
+
+  thunar_browser_poke_volume_data_free (poke_data);
 }
 
 
@@ -414,7 +602,6 @@ thunar_browser_poke_volume_finish (GObject      *object,
                                    gpointer      user_data)
 {
   PokeVolumeData *poke_data = user_data;
-  ThunarFile     *file;
   GError         *error = NULL;
   GMount         *mount;
   GFile          *mount_point;
@@ -426,6 +613,8 @@ thunar_browser_poke_volume_finish (GObject      *object,
   _thunar_return_if_fail (G_IS_VOLUME (poke_data->volume));
   _thunar_return_if_fail (G_VOLUME (object) == poke_data->volume);
 
+  g_debug ("thunar_browser_poke_volume_finish");
+
   if (!g_volume_mount_finish (G_VOLUME (object), result, &error))
     {
       if (error->domain == G_IO_ERROR)
@@ -433,6 +622,8 @@ thunar_browser_poke_volume_finish (GObject      *object,
           if (error->code == G_IO_ERROR_ALREADY_MOUNTED)
             g_clear_error (&error);
         }
+
+      thunar_browser_poke_volume_data_free (poke_data);
     }
 
   if (error == NULL)
@@ -440,19 +631,14 @@ thunar_browser_poke_volume_finish (GObject      *object,
       mount = g_volume_get_mount (poke_data->volume);
       mount_point = g_mount_get_root (mount);
 
-      file = thunar_file_get (mount_point, &error);
+      /* resolve the ThunarFile for the mount point asynchronously
+       * and defer cleaning up the poke data until that has finished */
+      thunar_file_get_async (mount_point, NULL,
+                             thunar_browser_poke_volume_file_finish,
+                             poke_data);
 
       g_object_unref (mount_point);
       g_object_unref (mount);
-
-      if (poke_data->func != NULL)
-        {
-          (poke_data->func) (poke_data->browser, poke_data->volume, file, error, 
-                             poke_data->user_data);
-        }
-
-      if (file != NULL)
-        g_object_unref (file);
     }
   else
     {
@@ -461,9 +647,9 @@ thunar_browser_poke_volume_finish (GObject      *object,
           (poke_data->func) (poke_data->browser, poke_data->volume, NULL, error,
                              poke_data->user_data);
         }
-    }
 
-  thunar_browser_poke_volume_data_free (poke_data);
+      thunar_browser_poke_volume_data_free (poke_data);
+    }
 }
 
 
@@ -494,31 +680,27 @@ thunar_browser_poke_volume (ThunarBrowser              *browser,
 {
   GMountOperation *mount_operation;
   PokeVolumeData  *poke_data;
-  ThunarFile      *file;
-  GError          *error = NULL;
   GMount          *mount;
   GFile           *mount_point;
 
   _thunar_return_if_fail (THUNAR_IS_BROWSER (browser));
   _thunar_return_if_fail (G_IS_VOLUME (volume));
 
+  g_debug ("thunar_browser_poke_volume");
+
   if (thunar_g_volume_is_mounted (volume))
     {
       mount = g_volume_get_mount (volume);
       mount_point = g_mount_get_root (mount);
 
-      file = thunar_file_get (mount_point, &error);
+      poke_data = thunar_browser_poke_volume_data_new (browser, volume, func, user_data);
+
+      thunar_file_get_async (mount_point, NULL, 
+                             thunar_browser_poke_volume_file_finish,
+                             poke_data);
 
       g_object_unref (mount_point);
       g_object_unref (mount);
-
-      if (func != NULL)
-        func (browser, volume, file, error, user_data);
-
-      g_clear_error (&error);
-
-      if (file != NULL)
-        g_object_unref (file);
     }
   else
     {
@@ -532,3 +714,81 @@ thunar_browser_poke_volume (ThunarBrowser              *browser,
       g_object_unref (mount_operation);
     }
 }
+
+
+
+static void
+thunar_browser_poke_location_file_finish (GFile      *location,
+                                          ThunarFile *file,
+                                          GError     *error,
+                                          gpointer    user_data)
+{
+  PokeFileData *poke_data = user_data;
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (user_data != NULL);
+  _thunar_return_if_fail (THUNAR_IS_BROWSER (poke_data->browser));
+  _thunar_return_if_fail (G_IS_FILE (poke_data->location));
+
+  g_debug ("thunar_browser_poke_mountable_file_finish");
+
+  if (error == NULL)
+    {
+      thunar_browser_poke_file_internal (poke_data->browser,
+                                         location,
+                                         file,
+                                         file,
+                                         NULL,
+                                         poke_data->func,
+                                         poke_data->location_func,
+                                         poke_data->user_data);
+    }
+  else
+    {
+      if (poke_data->location_func != NULL)
+        {
+          (poke_data->location_func) (poke_data->browser, location, NULL, NULL, error,
+                                      poke_data->user_data);
+        }
+    }
+
+  thunar_browser_poke_file_data_free (poke_data);
+}
+
+
+
+/**
+ * thunar_browser_poke_location:
+ * @browser   : a #ThunarBrowser.
+ * @location  : a #GFile.
+ * @widget    : a #GtkWidget, a #GdkScreen or %NULL.
+ * @func      : a #ThunarBrowserPokeVolumeFunc callback or %NULL.
+ * @user_data : pointer to arbitrary user data or %NULL.
+ *
+ * Pokes a #GFile to see what's behind it.
+ *
+ * It first resolves the #GFile into a #ThunarFile asynchronously using
+ * thunar_file_get_async(). It then performs the same steps as 
+ * thunar_browser_poke_file().
+ **/
+void
+thunar_browser_poke_location (ThunarBrowser                *browser,
+                              GFile                        *location,
+                              gpointer                      widget,
+                              ThunarBrowserPokeLocationFunc func,
+                              gpointer                      user_data)
+{
+  PokeFileData *poke_data;
+
+  _thunar_return_if_fail (THUNAR_IS_BROWSER (browser));
+  _thunar_return_if_fail (G_IS_FILE (location));
+
+  g_debug ("thunar_browser_poke_location %s", g_file_get_uri (location));
+
+  poke_data = thunar_browser_poke_file_data_new (browser, location, NULL, NULL,
+                                                 NULL, func, user_data);
+
+  thunar_file_get_async (location, NULL,
+                         thunar_browser_poke_location_file_finish,
+                         poke_data);
+}
diff --git a/thunar/thunar-browser.h b/thunar/thunar-browser.h
index d9bb795..23ffe53 100644
--- a/thunar/thunar-browser.h
+++ b/thunar/thunar-browser.h
@@ -33,17 +33,24 @@ G_BEGIN_DECLS
 typedef struct _ThunarBrowser      ThunarBrowser;
 typedef struct _ThunarBrowserIface ThunarBrowserIface;
 
-typedef void (*ThunarBrowserPokeFileFunc)   (ThunarBrowser *browser,
-                                             ThunarFile    *file,
-                                             ThunarFile    *target_file,
-                                             GError        *error,
-                                             gpointer       user_data);
-
-typedef void (*ThunarBrowserPokeVolumeFunc) (ThunarBrowser *browser,
-                                             GVolume       *volume,
-                                             ThunarFile    *mount_point,
-                                             GError        *error,
-                                             gpointer       user_data);
+typedef void (*ThunarBrowserPokeFileFunc)     (ThunarBrowser *browser,
+                                               ThunarFile    *file,
+                                               ThunarFile    *target_file,
+                                               GError        *error,
+                                               gpointer       user_data);
+
+typedef void (*ThunarBrowserPokeVolumeFunc)   (ThunarBrowser *browser,
+                                               GVolume       *volume,
+                                               ThunarFile    *mount_point,
+                                               GError        *error,
+                                               gpointer       user_data);
+
+typedef void (*ThunarBrowserPokeLocationFunc) (ThunarBrowser *browser,
+                                               GFile         *location,
+                                               ThunarFile    *file,
+                                               ThunarFile    *target_file,
+                                               GError        *error,
+                                               gpointer       user_data);
 
 struct _ThunarBrowserIface
 {
@@ -54,18 +61,24 @@ struct _ThunarBrowserIface
   /* virtual methods */
 };
 
-GType thunar_browser_get_type    (void) G_GNUC_CONST;
-
-void  thunar_browser_poke_file   (ThunarBrowser              *browser,
-                                  ThunarFile                 *file,
-                                  gpointer                    widget,
-                                  ThunarBrowserPokeFileFunc   func,
-                                  gpointer                    user_data);
-void  thunar_browser_poke_volume (ThunarBrowser              *browser,
-                                  GVolume                    *volume,
-                                  gpointer                    widget,
-                                  ThunarBrowserPokeVolumeFunc func,
-                                  gpointer                    user_data);
+GType thunar_browser_get_type      (void) G_GNUC_CONST;
+
+void  thunar_browser_poke_file     (ThunarBrowser                *browser,
+                                    ThunarFile                   *file,
+                                    gpointer                      widget,
+                                    ThunarBrowserPokeFileFunc     func,
+                                    gpointer                      user_data);
+void  thunar_browser_poke_volume   (ThunarBrowser                *browser,
+                                    GVolume                      *volume,
+                                    gpointer                      widget,
+                                    ThunarBrowserPokeVolumeFunc   func,
+                                    gpointer                      user_data);
+
+void  thunar_browser_poke_location (ThunarBrowser                *browser,
+                                    GFile                        *location,
+                                    gpointer                      widget,
+                                    ThunarBrowserPokeLocationFunc func,
+                                    gpointer                      user_data);
 
 G_END_DECLS
 
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index 1fbee4f..2c5fad6 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -136,6 +136,12 @@ static void     thunar_shortcut_row_poke_file_finish      (ThunarBrowser
                                                            ThunarFile            *target_file,
                                                            GError                *error,
                                                            gpointer               user_data);
+static void     thunar_shortcut_row_poke_location_finish  (ThunarBrowser         *browser,
+                                                           GFile                 *location,
+                                                           ThunarFile            *file,
+                                                           ThunarFile            *target_file,
+                                                           GError                *error,
+                                                           gpointer               user_data);
 static void     thunar_shortcut_row_icon_changed          (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_label_changed         (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_location_changed      (ThunarShortcutRow     *row);
@@ -907,6 +913,9 @@ thunar_shortcut_row_mount_unmount_finish (GObject      *object,
   _thunar_return_if_fail (G_IS_MOUNT (mount));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
+  /* stop spinning */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
   if (!g_mount_unmount_with_operation_finish (mount, result, &error))
     {
       thunar_dialogs_show_error (GTK_WIDGET (row), error,
@@ -914,9 +923,6 @@ thunar_shortcut_row_mount_unmount_finish (GObject      *object,
                                  row->label);
       g_error_free (error);
     }
-
-  /* stop spinning */
-  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -930,6 +936,9 @@ thunar_shortcut_row_mount_eject_finish (GObject      *object,
   GMount            *mount = G_MOUNT (object);
   GError            *error = NULL;
 
+  /* stop spinning */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
   _thunar_return_if_fail (G_IS_MOUNT (mount));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
@@ -941,9 +950,6 @@ thunar_shortcut_row_mount_eject_finish (GObject      *object,
                                  row->label);
       g_error_free (error);
     }
-
-  /* stop spinning */
-  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -961,6 +967,9 @@ thunar_shortcut_row_volume_eject_finish (GObject      *object,
   _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
+  /* stop spinning */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
   if (!g_volume_eject_with_operation_finish (volume, result, &error))
     {
       thunar_dialogs_show_error (GTK_WIDGET (row), error,
@@ -968,9 +977,6 @@ thunar_shortcut_row_volume_eject_finish (GObject      *object,
                                  row->label);
       g_error_free (error);
     }
-
-  /* stop spinning */
-  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -989,6 +995,9 @@ thunar_shortcut_row_poke_volume_finish (ThunarBrowser *browser,
   _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
 
+  /* deactivate the spinner */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
   if (error == NULL)
     {
       g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, file, open_in_new_window);
@@ -999,9 +1008,6 @@ thunar_shortcut_row_poke_volume_finish (ThunarBrowser *browser,
                                  _("Failed to open \"%s\""),
                                  row->label);
     }
-
-  /* deactivate the spinner */
-  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -1020,6 +1026,9 @@ thunar_shortcut_row_poke_file_finish (ThunarBrowser *browser,
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
   _thunar_return_if_fail (target_file == NULL || THUNAR_IS_FILE (target_file));
 
+  /* deactivate the spinner */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
   if (error == NULL)
     {
       g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, target_file, 
@@ -1031,9 +1040,40 @@ thunar_shortcut_row_poke_file_finish (ThunarBrowser *browser,
                                  _("Failed to open \"%s\""),
                                  row->label);
     }
+}
+
+
+
+static void
+thunar_shortcut_row_poke_location_finish (ThunarBrowser *browser,
+                                          GFile         *location,
+                                          ThunarFile    *file,
+                                          ThunarFile    *target_file,
+                                          GError        *error,
+                                          gpointer       user_data)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (browser);
+  gboolean           open_in_new_window = GPOINTER_TO_UINT (user_data);
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (browser));
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (target_file == NULL || THUNAR_IS_FILE (target_file));
 
   /* deactivate the spinner */
   thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
+
+  if (error == NULL)
+    {
+      g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, target_file, 
+                     open_in_new_window);
+    }
+  else
+    {
+      thunar_dialogs_show_error (GTK_WIDGET (row), error,
+                                 _("Failed to open \"%s\""),
+                                 row->label);
+    }
 }
 
 
@@ -1042,9 +1082,6 @@ void
 thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row,
                                           gboolean           open_in_new_window)
 {
-  ThunarFile *file;
-  GError     *error = NULL;
-
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
   /* check if we are currently mounting/ejecting something */
@@ -1064,31 +1101,23 @@ thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row,
                                   thunar_shortcut_row_poke_volume_finish,
                                   GUINT_TO_POINTER (open_in_new_window));
     }
+  else if (row->file != NULL)
+    {
+      /* activate the spinner */
+      thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_RESOLVING);
+
+      thunar_browser_poke_file (THUNAR_BROWSER (row), row->file, row,
+                                thunar_shortcut_row_poke_file_finish,
+                                GUINT_TO_POINTER (open_in_new_window));
+    }
   else if (row->location != NULL)
     {
-      file = thunar_file_get (row->location, NULL);
-      if (file != NULL)
-        {
-          /* activate the spinner */
-          thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_RESOLVING);
+      /* activate the spinner */
+      thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_RESOLVING);
 
-          thunar_browser_poke_file (THUNAR_BROWSER (row), file, row,
-                                    thunar_shortcut_row_poke_file_finish,
+      thunar_browser_poke_location (THUNAR_BROWSER (row), row->location, row,
+                                    thunar_shortcut_row_poke_location_finish,
                                     GUINT_TO_POINTER (open_in_new_window));
-
-          g_object_unref (file);
-        }
-      else
-        {
-          g_set_error (&error, G_IO_ERROR, G_IO_ERROR_UNKNOWN,
-                       _("Folder could not be loaded"));
-
-          thunar_dialogs_show_error (GTK_WIDGET (row), error,
-                                     _("Failed to open \"%s\""),
-                                     row->label);
-
-          g_error_free (error);
-        }
     }
   else
     {
diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
index a2ec353..070455e 100644
--- a/thunar/thunar-shortcut.c
+++ b/thunar/thunar-shortcut.c
@@ -27,6 +27,7 @@
 
 #include <gio/gio.h>
 
+#include <thunar/thunar-browser.h>
 #include <thunar/thunar-enum-types.h>
 #include <thunar/thunar-file.h>
 #include <thunar/thunar-private.h>
@@ -61,21 +62,23 @@ enum
 
 
 
-static void thunar_shortcut_constructed      (GObject        *object);
-static void thunar_shortcut_finalize         (GObject        *object);
-static void thunar_shortcut_get_property     (GObject        *object,
-                                              guint           prop_id,
-                                              GValue         *value,
-                                              GParamSpec     *pspec);
-static void thunar_shortcut_set_property     (GObject        *object,
-                                              guint           prop_id,
-                                              const GValue   *value,
-                                              GParamSpec     *pspec);
-static void thunar_shortcut_load_file_finish (GFile          *location,
-                                              ThunarFile     *file,
-                                              GError         *error,
-                                              gpointer        user_data);
-static void thunar_shortcut_load_file        (ThunarShortcut *shortcut);
+static void thunar_shortcut_constructed          (GObject        *object);
+static void thunar_shortcut_finalize             (GObject        *object);
+static void thunar_shortcut_get_property         (GObject        *object,
+                                                  guint           prop_id,
+                                                  GValue         *value,
+                                                  GParamSpec     *pspec);
+static void thunar_shortcut_set_property         (GObject        *object,
+                                                  guint           prop_id,
+                                                  const GValue   *value,
+                                                  GParamSpec     *pspec);
+static void thunar_shortcut_poke_location_finish (ThunarBrowser  *browser,
+                                                  GFile          *location,
+                                                  ThunarFile     *file,
+                                                  ThunarFile     *target_file,
+                                                  GError         *error,
+                                                  gpointer        user_data);
+static void thunar_shortcut_load_file            (ThunarShortcut *shortcut);
 
 
 
@@ -112,7 +115,8 @@ struct _ThunarShortcut
 
 
 
-G_DEFINE_TYPE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
 
 
 
@@ -442,15 +446,18 @@ thunar_shortcut_set_property (GObject      *object,
 
 
 static void
-thunar_shortcut_load_file_finish (GFile      *location,
-                                  ThunarFile *file,
-                                  GError     *error,
-                                  gpointer    user_data)
+thunar_shortcut_poke_location_finish (ThunarBrowser *browser,
+                                      GFile         *location,
+                                      ThunarFile    *file,
+                                      ThunarFile    *target_file,
+                                      GError        *error,
+                                      gpointer       user_data)
 {
-  ThunarShortcut *shortcut = THUNAR_SHORTCUT (user_data);
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (browser);
 
   _thunar_return_if_fail (G_IS_FILE (location));
   _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (target_file == NULL || THUNAR_IS_FILE (target_file));
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   
   if (error != NULL)
@@ -460,7 +467,7 @@ thunar_shortcut_load_file_finish (GFile      *location,
   else
     {
       /* set the file and update the shortcut */
-      thunar_shortcut_set_file (shortcut, file);
+      thunar_shortcut_set_file (shortcut, target_file);
     }
 
   /* release the shortcut */
@@ -479,9 +486,11 @@ thunar_shortcut_load_file (ThunarShortcut *shortcut)
 
   /* load the ThunarFile asynchronously */
   /* TODO pass a cancellable here */
-  thunar_file_get_async (shortcut->location, NULL,
-                         thunar_shortcut_load_file_finish,
-                         g_object_ref (shortcut));
+  thunar_browser_poke_location (THUNAR_BROWSER (shortcut),
+                                shortcut->location,
+                                NULL,
+                                thunar_shortcut_poke_location_finish,
+                                g_object_ref (shortcut));
 }
 
 



More information about the Xfce4-commits mailing list