[Xfce4-commits] r29916 - in thunar/branches/migration-to-gio: . thunar

Jannis Pohlmann jannis at xfce.org
Wed Apr 29 18:28:32 CEST 2009


Author: jannis
Date: 2009-04-29 16:28:31 +0000 (Wed, 29 Apr 2009)
New Revision: 29916

Modified:
   thunar/branches/migration-to-gio/ChangeLog
   thunar/branches/migration-to-gio/thunar/thunar-tree-model.c
   thunar/branches/migration-to-gio/thunar/thunar-tree-view.c
Log:
	* thunar/thunar-tree-model.c, thunar/thunar-tree-view.c: Rewrite the
	  volume management code based on GVolumeMonitor/GVolume. This code
	  still has quite a few problems with trying to mount several times in
	  a row and mount+open doesn't seem to work.

Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog	2009-04-29 16:28:21 UTC (rev 29915)
+++ thunar/branches/migration-to-gio/ChangeLog	2009-04-29 16:28:31 UTC (rev 29916)
@@ -1,5 +1,12 @@
 2009-04-29	Jannis Pohlmann <jannis at xfce.org>
 
+	* thunar/thunar-tree-model.c, thunar/thunar-tree-view.c: Rewrite the
+	  volume management code based on GVolumeMonitor/GVolume. This code
+	  still has quite a few problems with trying to mount several times in
+	  a row and mount+open doesn't seem to work.
+
+2009-04-29	Jannis Pohlmann <jannis at xfce.org>
+
 	* thunar/thunar-shortcuts-view.c: Avoid segfaults due to an invalid
 	  GtkTreeSelection being used in thunar_shortcuts_view_open_selection()
 	  and thunar_shortcuts_view_open_selection_in_new_window(). This can

Modified: thunar/branches/migration-to-gio/thunar/thunar-tree-model.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-tree-model.c	2009-04-29 16:28:21 UTC (rev 29915)
+++ thunar/branches/migration-to-gio/thunar/thunar-tree-model.c	2009-04-29 16:28:31 UTC (rev 29916)
@@ -116,21 +116,22 @@
 static void                 thunar_tree_model_file_changed            (ThunarFileMonitor      *file_monitor,
                                                                        ThunarFile             *file,
                                                                        ThunarTreeModel        *model);
-static void                 thunar_tree_model_volume_changed          (ThunarVfsVolume        *volume,
+static void                 thunar_tree_model_mount_pre_unmount       (GVolumeMonitor         *volume_monitor,
+                                                                       GMount                 *mount,
                                                                        ThunarTreeModel        *model);
-static void                 thunar_tree_model_volume_pre_unmount      (ThunarVfsVolumeManager *volume_manager,
-                                                                       ThunarVfsVolume        *volume,
+static void                 thunar_tree_model_volume_added            (GVolumeMonitor         *volume_monitor,
+                                                                       GVolume                *volume,
                                                                        ThunarTreeModel        *model);
-static void                 thunar_tree_model_volumes_added           (ThunarVfsVolumeManager *volume_manager,
-                                                                       GList                  *volumes,
+static void                 thunar_tree_model_volume_removed          (GVolumeMonitor         *volume_monitor,
+                                                                       GVolume                *volume,
                                                                        ThunarTreeModel        *model);
-static void                 thunar_tree_model_volumes_removed         (ThunarVfsVolumeManager *volume_manager,
-                                                                       GList                  *volumes,
+static void                 thunar_tree_model_volume_changed          (GVolumeMonitor         *volume_monitor,
+                                                                       GVolume                *volume,
                                                                        ThunarTreeModel        *model);
 static ThunarTreeModelItem *thunar_tree_model_item_new_with_file      (ThunarTreeModel        *model,
                                                                        ThunarFile             *file) G_GNUC_MALLOC;
 static ThunarTreeModelItem *thunar_tree_model_item_new_with_volume    (ThunarTreeModel        *model,
-                                                                       ThunarVfsVolume        *volume) G_GNUC_MALLOC;
+                                                                       GVolume                *volume) G_GNUC_MALLOC;
 static void                 thunar_tree_model_item_free               (ThunarTreeModelItem    *item);
 static void                 thunar_tree_model_item_reset              (ThunarTreeModelItem    *item);
 static void                 thunar_tree_model_item_load_folder        (ThunarTreeModelItem    *item);
@@ -182,7 +183,7 @@
 #endif
 
   /* removable volumes */
-  ThunarVfsVolumeManager     *volume_manager;
+  GVolumeMonitor             *volume_monitor;
   GList                      *hidden_volumes;
 
   ThunarFileMonitor          *file_monitor;
@@ -203,7 +204,7 @@
   guint            load_idle_id;
   ThunarFile      *file;
   ThunarFolder    *folder;
-  ThunarVfsVolume *volume;
+  GVolume         *volume;
   ThunarTreeModel *model;
 
   /* list of children of this node that are
@@ -322,6 +323,7 @@
     g_file_new_for_root () 
   };
   GList               *volumes;
+  GList               *lp;
   GNode               *node;
   guint                n;
 
@@ -343,11 +345,12 @@
   /* allocate the "virtual root node" */
   model->root = g_node_new (NULL);
 
-  /* connect to the volume manager */
-  model->volume_manager = thunar_vfs_volume_manager_get_default ();
-  g_signal_connect (G_OBJECT (model->volume_manager), "volumes-added", G_CALLBACK (thunar_tree_model_volumes_added), model);
-  g_signal_connect (G_OBJECT (model->volume_manager), "volumes-removed", G_CALLBACK (thunar_tree_model_volumes_removed), model);
-  g_signal_connect (G_OBJECT (model->volume_manager), "volume-pre-unmount", G_CALLBACK (thunar_tree_model_volume_pre_unmount), model);
+  /* connect to the volume monitor */
+  model->volume_monitor = g_volume_monitor_get ();
+  g_signal_connect (model->volume_monitor, "mount-pre-unmount", G_CALLBACK (thunar_tree_model_mount_pre_unmount), model);
+  g_signal_connect (model->volume_monitor, "volume-added", G_CALLBACK (thunar_tree_model_volume_added), model);
+  g_signal_connect (model->volume_monitor, "volume-removed", G_CALLBACK (thunar_tree_model_volume_removed), model);
+  g_signal_connect (model->volume_monitor, "volume-changed", G_CALLBACK (thunar_tree_model_volume_changed), model);
 
   /* append the system defined nodes ('Home', 'Trash', 'File System') */
   for (n = 0; n < G_N_ELEMENTS (system_path_list); ++n)
@@ -374,9 +377,13 @@
     }
 
   /* setup the initial volumes */
-  volumes = thunar_vfs_volume_manager_get_volumes (model->volume_manager);
-  if (G_LIKELY (volumes != NULL))
-    thunar_tree_model_volumes_added (model->volume_manager, volumes, model);
+  volumes = g_volume_monitor_get_volumes (model->volume_monitor);
+  for (lp = volumes; lp != NULL; lp = lp->next)
+    {
+      thunar_tree_model_volume_added (model->volume_monitor, lp->data, model);
+      g_object_unref (lp->data);
+    }
+  g_list_free (volumes);
 }
 
 
@@ -385,31 +392,26 @@
 thunar_tree_model_finalize (GObject *object)
 {
   ThunarTreeModel *model = THUNAR_TREE_MODEL (object);
-  GList           *lp;
 
   /* remove the cleanup idle */
   if (model->cleanup_idle_id != 0)
     g_source_remove (model->cleanup_idle_id);
 
   /* disconnect from the file monitor */
-  g_signal_handlers_disconnect_by_func (G_OBJECT (model->file_monitor), thunar_tree_model_file_changed, model);
-  g_object_unref (G_OBJECT (model->file_monitor));
+  g_signal_handlers_disconnect_by_func (model->file_monitor, thunar_tree_model_file_changed, model);
+  g_object_unref (model->file_monitor);
 
   /* release all hidden volumes */
-  for (lp = model->hidden_volumes; lp != NULL; lp = lp->next)
-    {
-      g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_tree_model_volume_changed, model);
-      g_object_unref (G_OBJECT (lp->data));
-    }
+  g_list_foreach (model->hidden_volumes, (GFunc) g_object_unref, NULL);
   g_list_free (model->hidden_volumes);
 
   /* release all resources allocated to the model */
   g_node_traverse (model->root, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_free, NULL);
   g_node_destroy (model->root);
 
-  /* disconnect from the volume manager */
-  g_signal_handlers_disconnect_matched (G_OBJECT (model->volume_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
-  g_object_unref (G_OBJECT (model->volume_manager));
+  /* disconnect from the volume monitor */
+  g_signal_handlers_disconnect_matched (model->volume_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
+  g_object_unref (model->volume_monitor);
 
   (*G_OBJECT_CLASS (thunar_tree_model_parent_class)->finalize) (object);
 }
@@ -492,7 +494,7 @@
       return PANGO_TYPE_ATTR_LIST;
 
     case THUNAR_TREE_MODEL_COLUMN_VOLUME:
-      return THUNAR_VFS_TYPE_VOLUME;
+      return G_TYPE_VOLUME;
 
     default:
       _thunar_assert_not_reached ();
@@ -629,7 +631,7 @@
     case THUNAR_TREE_MODEL_COLUMN_NAME:
       g_value_init (value, G_TYPE_STRING);
       if (G_LIKELY (item != NULL && item->volume != NULL))
-        g_value_set_static_string (value, thunar_vfs_volume_get_name (item->volume));
+        g_value_take_string (value, g_volume_get_name (item->volume));
       else if (G_LIKELY (item != NULL && item->file != NULL))
         g_value_set_static_string (value, thunar_file_get_display_name (item->file));
       else
@@ -645,7 +647,7 @@
       break;
 
     case THUNAR_TREE_MODEL_COLUMN_VOLUME:
-      g_value_init (value, THUNAR_VFS_TYPE_VOLUME);
+      g_value_init (value, G_TYPE_VOLUME);
       g_value_set_object (value, (item != NULL) ? item->volume : NULL);
       break;
 
@@ -974,17 +976,21 @@
 
 
 static void
-thunar_tree_model_volume_changed (ThunarVfsVolume *volume,
+thunar_tree_model_volume_changed (GVolumeMonitor  *volume_monitor,
+                                  GVolume         *volume,
                                   ThunarTreeModel *model)
 {
   ThunarTreeModelItem *item = NULL;
   GtkTreePath         *path;
   GtkTreeIter          iter;
+  GMount              *mount;
+  GFile               *mount_point;
   GNode               *node;
-  GList                list;
   GList               *lp;
 
-  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
+  _thunar_return_if_fail (model->volume_monitor == volume_monitor);
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model));
 
   /* check if the volume is on the hidden list */
@@ -992,7 +998,7 @@
   if (G_LIKELY (lp != NULL))
     {
       /* check if we need to display the volume now */
-      if (thunar_vfs_volume_is_present (volume) && thunar_vfs_volume_is_removable (volume))
+      if (g_volume_is_removable (volume) && g_volume_is_present (volume))
         {
           /* remove the volume from the list of hidden volumes */
           model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp);
@@ -1016,7 +1022,7 @@
           thunar_tree_model_node_insert_dummy (node, model);
 
           /* drop our reference on the volume */
-          g_object_unref (G_OBJECT (volume));
+          g_object_unref (volume);
         }
     }
   else
@@ -1034,36 +1040,39 @@
       _thunar_assert (item->volume == volume);
 
       /* check if we need to hide the volume now */
-      if (!thunar_vfs_volume_is_present (volume) || !thunar_vfs_volume_is_removable (volume))
+      if (!g_volume_is_removable (volume) || !g_volume_is_present (volume))
         {
           /* need to ref here, because the volumes_removed() handler will drop the reference */
-          g_object_ref (G_OBJECT (volume));
+          g_object_ref (volume);
 
-          /* fake a list with only the volume */
-          list.next = list.prev = NULL;
-          list.data = volume;
+          /* use "volume-removed" handler to hide the volume */
+          thunar_tree_model_volume_removed (model->volume_monitor, volume, model);
 
-          /* use "volumes-removed" handler to hide the volume */
-          thunar_tree_model_volumes_removed (model->volume_manager, &list, model);
-
-          /* need to reconnect to the volume as the item removable drops the handler */
-          g_signal_connect (G_OBJECT (volume), "changed", G_CALLBACK (thunar_tree_model_volume_changed), model);
-
           /* move the volume to the hidden list */
           model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume);
         }
       else
         {
           /* check if the volume is mounted and we don't have a file yet */
-          if (thunar_vfs_volume_is_mounted (volume) && item->file == NULL)
+          if (g_volume_is_mounted (volume) && item->file == NULL)
             {
-              /* try to determine the file for the mount point */
-              item->file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (volume), NULL);
+              mount = g_volume_get_mount (volume);
 
-              /* because the volume node is already reffed, we need to load the folder manually here */
-              thunar_tree_model_item_load_folder (item);
+              if (G_LIKELY (mount != NULL))
+                {
+                  mount_point = g_mount_get_root (mount);
+                
+                  /* try to determine the file for the mount point */
+                  item->file = thunar_file_get (mount_point, NULL);
+
+                  /* because the volume node is already reffed, we need to load the folder manually here */
+                  thunar_tree_model_item_load_folder (item);
+
+                  g_object_unref (mount_point);
+                  g_object_unref (mount);
+                }
             }
-          else if (!thunar_vfs_volume_is_mounted (volume) && item->file != NULL)
+          else if (!g_volume_is_mounted (volume) && item->file != NULL)
             {
               /* reset the item for the node */
               thunar_tree_model_item_reset (item);
@@ -1090,21 +1099,31 @@
 
 
 static void
-thunar_tree_model_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager,
-                                      ThunarVfsVolume        *volume,
-                                      ThunarTreeModel        *model)
+thunar_tree_model_mount_pre_unmount (GVolumeMonitor         *volume_monitor,
+                                     GMount                 *mount,
+                                     ThunarTreeModel        *model)
 {
-  GNode *node;
+  GVolume *volume;
+  GNode   *node;
 
-  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
-  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME (volume));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
+  _thunar_return_if_fail (model->volume_monitor == volume_monitor);
+  _thunar_return_if_fail (G_IS_MOUNT (mount));
   _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model));
 
+  /* determine the mount to which this mount belongs */
+  volume = g_mount_get_volume (mount);
+
+  if (volume == NULL)
+    return;
+
   /* lookup the node for the volume (if visible) */
   for (node = model->root->children; node != NULL; node = node->next)
     if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume)
       break;
 
+  g_object_unref (volume);
+
   /* check if we have a node */
   if (G_UNLIKELY (node == NULL))
     return;
@@ -1123,74 +1142,58 @@
 
 
 static void
-thunar_tree_model_volumes_added (ThunarVfsVolumeManager *volume_manager,
-                                 GList                  *volumes,
-                                 ThunarTreeModel        *model)
+thunar_tree_model_volume_added (GVolumeMonitor         *volume_monitor,
+                                GVolume                *volume,
+                                ThunarTreeModel        *model)
 {
-  GList *lp;
-
-  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
+  _thunar_return_if_fail (model->volume_monitor == volume_monitor);
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model));
 
-  /* process all newly added volumes */
-  for (lp = volumes; lp != NULL; lp = lp->next)
-    {
-      /* take a reference on the volume... */
-      g_object_ref (G_OBJECT (lp->data));
+  /* place the volume on the hidden list */
+  model->hidden_volumes = g_list_prepend (model->hidden_volumes, g_object_ref (volume));
 
-      /* ...place the volume on the hidden list... */
-      model->hidden_volumes = g_list_prepend (model->hidden_volumes, lp->data);
-
-      /* ...connect the "changed" signal handler... */
-      g_signal_connect (G_OBJECT (lp->data), "changed", G_CALLBACK (thunar_tree_model_volume_changed), model);
-
-      /* ...and let the "changed" handler place the volume where appropriate */
-      thunar_tree_model_volume_changed (lp->data, model);
-    }
+  /* and let the "volume-changed" handler place the volume where appropriate */
+  thunar_tree_model_volume_changed (volume_monitor, volume, model);
 }
 
 
 
 static void
-thunar_tree_model_volumes_removed (ThunarVfsVolumeManager *volume_manager,
-                                   GList                  *volumes,
-                                   ThunarTreeModel        *model)
+thunar_tree_model_volume_removed (GVolumeMonitor         *volume_monitor,
+                                  GVolume                *volume,
+                                  ThunarTreeModel        *model)
 {
   GNode *node;
-  GList *hp;
   GList *lp;
 
-  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (volume_monitor));
+  _thunar_return_if_fail (model->volume_monitor == volume_monitor);
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model));
 
-  /* process all removed volumes */
-  for (lp = volumes; lp != NULL; lp = lp->next)
+  /* check if the volume is on the hidden list */
+  lp = g_list_find (model->hidden_volumes, volume);
+  if (G_LIKELY (lp != NULL))
     {
-      /* check if the volume is on the hidden list */
-      hp = g_list_find (model->hidden_volumes, lp->data);
-      if (G_LIKELY (hp != NULL))
-        {
-          /* disconnect the "changed" signal handler from the volume */
-          g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_tree_model_volume_changed, model);
+      /* remove the volume from the hidden list and drop our reference */
+      model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp);
+      g_object_unref (volume);
+    }
+  else
+    {
+      /* must be a visible volume then... */
+      for (node = model->root->children; node != NULL; node = node->next)
+        if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume)
+          break;
 
-          /* drop the volume from the hidden list and drop our reference */
-          model->hidden_volumes = g_list_delete_link (model->hidden_volumes, hp);
-          g_object_unref (G_OBJECT (lp->data));
-        }
-      else
-        {
-          /* must be a visible volume then... */
-          for (node = model->root->children; node != NULL; node = node->next)
-            if (THUNAR_TREE_MODEL_ITEM (node->data)->volume == lp->data)
-              break;
+      /* something is broken if we don't have an item here */
+      _thunar_assert (node != NULL);
+      _thunar_assert (THUNAR_TREE_MODEL_ITEM (node->data)->volume == volume);
 
-          /* something is broken if we don't have an item here */
-          _thunar_assert (node != NULL);
-          _thunar_assert (THUNAR_TREE_MODEL_ITEM (node->data)->volume == lp->data);
-
-          /* drop the node from the model */
-          g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_remove, model);
-        }
+      /* drop the node from the model */
+      g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, thunar_tree_model_node_traverse_remove, model);
     }
 }
 
@@ -1213,21 +1216,31 @@
 
 static ThunarTreeModelItem*
 thunar_tree_model_item_new_with_volume (ThunarTreeModel *model,
-                                        ThunarVfsVolume *volume)
+                                        GVolume         *volume)
 {
   ThunarTreeModelItem *item;
-  ThunarVfsPath       *path;
+  GMount              *mount;
+  GFile               *mount_point;
 
   item = _thunar_slice_new0 (ThunarTreeModelItem);
   item->volume = g_object_ref (G_OBJECT (volume));
   item->model = model;
 
   /* check if the volume is mounted */
-  if (thunar_vfs_volume_is_mounted (volume))
+  if (g_volume_is_mounted (volume))
     {
-      /* try to determine the file for the mount point */
-      path = thunar_vfs_volume_get_mount_point (volume);
-      item->file = thunar_file_get_for_path (path, NULL);
+      mount = g_volume_get_mount (volume);
+      
+      if (G_LIKELY (mount != NULL))
+        {
+          mount_point = g_mount_get_root (mount);
+
+          /* try to determine the file for the mount point */
+          item->file = thunar_file_get (mount_point, NULL);
+
+          g_object_unref (mount_point);
+          g_object_unref (mount);
+        }
     }
 
   return item;
@@ -1240,10 +1253,7 @@
 {
   /* disconnect from the volume */
   if (G_UNLIKELY (item->volume != NULL))
-    {
-      g_signal_handlers_disconnect_by_func (G_OBJECT (item->volume), thunar_tree_model_volume_changed, item->model);
-      g_object_unref (G_OBJECT (item->volume));
-    }
+    g_object_unref (item->volume);
 
   /* reset the remaining resources */
   thunar_tree_model_item_reset (item);
@@ -1490,6 +1500,8 @@
 thunar_tree_model_item_load_idle (gpointer user_data)
 {
   ThunarTreeModelItem *item = user_data;
+  GMount              *mount;
+  GFile               *mount_point;
   GList               *files;
 
   _thunar_return_val_if_fail (item->folder == NULL, FALSE);
@@ -1507,10 +1519,20 @@
   GDK_THREADS_ENTER ();
 
   /* check if we don't have a file yet and this is a mounted volume */
-  if (item->file == NULL && item->volume != NULL && thunar_vfs_volume_is_mounted (item->volume))
+  if (item->file == NULL && item->volume != NULL && g_volume_is_mounted (item->volume))
     {
-      /* try to determine the file for the mount point */
-      item->file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (item->volume), NULL);
+      mount = g_volume_get_mount (item->volume);
+
+      if (G_LIKELY (mount != NULL))
+        {
+          mount_point = g_mount_get_root (mount);
+
+          /* try to determine the file for the mount point */
+          item->file = thunar_file_get (mount_point, NULL);
+
+          g_object_unref (mount_point);
+          g_object_unref (mount);
+        }
     }
 
   /* verify that we have a file */

Modified: thunar/branches/migration-to-gio/thunar/thunar-tree-view.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-tree-view.c	2009-04-29 16:28:21 UTC (rev 29915)
+++ thunar/branches/migration-to-gio/thunar/thunar-tree-view.c	2009-04-29 16:28:31 UTC (rev 29916)
@@ -47,6 +47,10 @@
 
 
 
+typedef struct _ThunarTreeViewMountData ThunarTreeViewMountData;
+
+
+
 /* Property identifiers */
 enum
 {
@@ -70,105 +74,117 @@
 
 
 
-static void             thunar_tree_view_class_init                 (ThunarTreeViewClass  *klass);
-static void             thunar_tree_view_navigator_init             (ThunarNavigatorIface *iface);
-static void             thunar_tree_view_init                       (ThunarTreeView       *view);
-static void             thunar_tree_view_finalize                   (GObject              *object);
-static void             thunar_tree_view_get_property               (GObject              *object,
-                                                                     guint                 prop_id,
-                                                                     GValue               *value,
-                                                                     GParamSpec           *pspec);
-static void             thunar_tree_view_set_property               (GObject              *object,
-                                                                     guint                 prop_id,
-                                                                     const GValue         *value,
-                                                                     GParamSpec           *pspec);
-static ThunarFile      *thunar_tree_view_get_current_directory      (ThunarNavigator      *navigator);
-static void             thunar_tree_view_set_current_directory      (ThunarNavigator      *navigator,
-                                                                     ThunarFile           *current_directory);
-static void             thunar_tree_view_realize                    (GtkWidget            *widget);
-static void             thunar_tree_view_unrealize                  (GtkWidget            *widget);
-static gboolean         thunar_tree_view_button_press_event         (GtkWidget            *widget,
-                                                                     GdkEventButton       *event);
-static gboolean         thunar_tree_view_button_release_event       (GtkWidget            *widget,
-                                                                     GdkEventButton       *event);
-static void             thunar_tree_view_drag_data_received         (GtkWidget            *widget,
-                                                                     GdkDragContext       *context,
-                                                                     gint                  x,
-                                                                     gint                  y,
-                                                                     GtkSelectionData     *selection_data,
-                                                                     guint                 info,
-                                                                     guint                 time);
-static gboolean         thunar_tree_view_drag_drop                  (GtkWidget            *widget,
-                                                                     GdkDragContext       *context,
-                                                                     gint                  x,
-                                                                     gint                  y,
-                                                                     guint                 time);
-static gboolean         thunar_tree_view_drag_motion                (GtkWidget            *widget,
-                                                                     GdkDragContext       *context,
-                                                                     gint                  x,
-                                                                     gint                  y,
-                                                                     guint                 time);
-static void             thunar_tree_view_drag_leave                 (GtkWidget            *widget,
-                                                                     GdkDragContext       *context,
-                                                                     guint                 time);
-static gboolean         thunar_tree_view_popup_menu                 (GtkWidget            *widget);
-static void             thunar_tree_view_row_activated              (GtkTreeView          *tree_view,
-                                                                     GtkTreePath          *path,
-                                                                     GtkTreeViewColumn    *column);
-static gboolean         thunar_tree_view_test_expand_row            (GtkTreeView          *tree_view,
-                                                                     GtkTreeIter          *iter,
-                                                                     GtkTreePath          *path);
-static void             thunar_tree_view_row_collapsed              (GtkTreeView          *tree_view,
-                                                                     GtkTreeIter          *iter,
-                                                                     GtkTreePath          *path);
-static gboolean         thunar_tree_view_delete_selected_files      (ThunarTreeView       *view);
-static void             thunar_tree_view_context_menu               (ThunarTreeView       *view,
-                                                                     GdkEventButton       *event,
-                                                                     GtkTreeModel         *model,
-                                                                     GtkTreeIter          *iter);
-static GdkDragAction    thunar_tree_view_get_dest_actions           (ThunarTreeView       *view,
-                                                                     GdkDragContext       *context,
-                                                                     gint                  x,
-                                                                     gint                  y,
-                                                                     guint                 time,
-                                                                     ThunarFile          **file_return);
-static gboolean         thunar_tree_view_find_closest_ancestor      (ThunarTreeView       *view,
-                                                                     GtkTreePath          *path,
-                                                                     GtkTreePath         **ancestor_return,
-                                                                     gboolean             *exact_return);
-static ThunarFile      *thunar_tree_view_get_selected_file          (ThunarTreeView       *view);
-static ThunarVfsVolume *thunar_tree_view_get_selected_volume        (ThunarTreeView       *view);
-static void             thunar_tree_view_action_copy                (ThunarTreeView       *view);
-static void             thunar_tree_view_action_create_folder       (ThunarTreeView       *view);
-static void             thunar_tree_view_action_cut                 (ThunarTreeView       *view);
-static void             thunar_tree_view_action_delete              (ThunarTreeView       *view);
-static void             thunar_tree_view_action_rename              (ThunarTreeView       *view);
-static void             thunar_tree_view_action_eject               (ThunarTreeView       *view);
-static void             thunar_tree_view_action_empty_trash         (ThunarTreeView       *view);
-static gboolean         thunar_tree_view_action_mount               (ThunarTreeView       *view);
-static void             thunar_tree_view_action_open                (ThunarTreeView       *view);
-static void             thunar_tree_view_action_open_in_new_window  (ThunarTreeView       *view);
-static void             thunar_tree_view_action_paste_into_folder   (ThunarTreeView       *view);
-static void             thunar_tree_view_action_properties          (ThunarTreeView       *view);
-static void             thunar_tree_view_action_unmount             (ThunarTreeView       *view);
-static GClosure        *thunar_tree_view_new_files_closure          (ThunarTreeView       *view);
-static void             thunar_tree_view_new_files                  (ThunarJob            *job,
-                                                                     GList                *path_list,
-                                                                     ThunarTreeView       *view);
-static gboolean         thunar_tree_view_visible_func               (ThunarTreeModel      *model,
-                                                                     ThunarFile           *file,
-                                                                     gpointer              user_data);
-static gboolean         thunar_tree_view_selection_func             (GtkTreeSelection     *selection,
-                                                                     GtkTreeModel         *model,
-                                                                     GtkTreePath          *path,
-                                                                     gboolean              path_currently_selected,
-                                                                     gpointer              user_data);
-static gboolean         thunar_tree_view_cursor_idle                (gpointer              user_data);
-static void             thunar_tree_view_cursor_idle_destroy        (gpointer              user_data);
-static gboolean         thunar_tree_view_drag_scroll_timer          (gpointer              user_data);
-static void             thunar_tree_view_drag_scroll_timer_destroy  (gpointer              user_data);
-static gboolean         thunar_tree_view_expand_timer               (gpointer              user_data);
-static void             thunar_tree_view_expand_timer_destroy       (gpointer              user_data);
+static void                     thunar_tree_view_class_init                   (ThunarTreeViewClass     *klass);
+static void                     thunar_tree_view_navigator_init               (ThunarNavigatorIface    *iface);
+static void                     thunar_tree_view_init                         (ThunarTreeView          *view);
+static void                     thunar_tree_view_finalize                     (GObject                 *object);
+static void                     thunar_tree_view_get_property                 (GObject                 *object,
+                                                                               guint                    prop_id,
+                                                                               GValue                  *value,
+                                                                               GParamSpec              *pspec);
+static void                     thunar_tree_view_set_property                 (GObject                 *object,
+                                                                               guint                    prop_id,
+                                                                               const GValue            *value,
+                                                                               GParamSpec              *pspec);
+static ThunarFile              *thunar_tree_view_get_current_directory        (ThunarNavigator         *navigator);
+static void                     thunar_tree_view_set_current_directory        (ThunarNavigator         *navigator,
+                                                                               ThunarFile              *current_directory);
+static void                     thunar_tree_view_realize                      (GtkWidget               *widget);
+static void                     thunar_tree_view_unrealize                    (GtkWidget               *widget);
+static gboolean                 thunar_tree_view_button_press_event           (GtkWidget               *widget,
+                                                                               GdkEventButton          *event);
+static gboolean                 thunar_tree_view_button_release_event         (GtkWidget               *widget,
+                                                                               GdkEventButton          *event);
+static void                     thunar_tree_view_drag_data_received           (GtkWidget               *widget,
+                                                                               GdkDragContext          *context,
+                                                                               gint                     x,
+                                                                               gint                     y,
+                                                                               GtkSelectionData        *selection_data,
+                                                                               guint                    info,
+                                                                               guint                    time);
+static gboolean                 thunar_tree_view_drag_drop                    (GtkWidget               *widget,
+                                                                               GdkDragContext          *context,
+                                                                               gint                     x,
+                                                                               gint                     y,
+                                                                               guint                    time);
+static gboolean                 thunar_tree_view_drag_motion                  (GtkWidget               *widget,
+                                                                               GdkDragContext          *context,
+                                                                               gint                     x,
+                                                                               gint                     y,
+                                                                               guint                    time);
+static void                     thunar_tree_view_drag_leave                   (GtkWidget               *widget,
+                                                                               GdkDragContext          *context,
+                                                                               guint                    time);
+static gboolean                 thunar_tree_view_popup_menu                   (GtkWidget               *widget);
+static void                     thunar_tree_view_row_activated                (GtkTreeView             *tree_view,
+                                                                               GtkTreePath             *path,
+                                                                               GtkTreeViewColumn       *column);
+static gboolean                 thunar_tree_view_test_expand_row              (GtkTreeView             *tree_view,
+                                                                               GtkTreeIter             *iter,
+                                                                               GtkTreePath             *path);
+static void                     thunar_tree_view_row_collapsed                (GtkTreeView             *tree_view,
+                                                                               GtkTreeIter             *iter,
+                                                                               GtkTreePath             *path);
+static gboolean                 thunar_tree_view_delete_selected_files        (ThunarTreeView          *view);
+static void                     thunar_tree_view_context_menu                 (ThunarTreeView          *view,
+                                                                               GdkEventButton          *event,
+                                                                               GtkTreeModel            *model,
+                                                                               GtkTreeIter             *iter);
+static GdkDragAction            thunar_tree_view_get_dest_actions             (ThunarTreeView          *view,
+                                                                               GdkDragContext          *context,
+                                                                               gint                     x,
+                                                                               gint                     y,
+                                                                               guint                    time,
+                                                                               ThunarFile             **file_return);
+static gboolean                 thunar_tree_view_find_closest_ancestor        (ThunarTreeView          *view,
+                                                                               GtkTreePath             *path,
+                                                                               GtkTreePath            **ancestor_return,
+                                                                               gboolean                *exact_return);
+static ThunarFile              *thunar_tree_view_get_selected_file            (ThunarTreeView          *view);
+static GVolume                 *thunar_tree_view_get_selected_volume          (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_copy                  (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_create_folder         (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_cut                   (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_delete                (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_rename                (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_eject                 (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_empty_trash           (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_mount                 (ThunarTreeView          *view);
+static void                     thunar_tree_view_mount_finish                 (GObject                 *object,
+                                                                               GAsyncResult            *result,
+                                                                               gpointer                 user_data);
+static void                     thunar_tree_view_mount                        (ThunarTreeView          *view,
+                                                                               gboolean                 open_after_mounting,
+                                                                               gboolean                 open_in_new_window);
+static void                     thunar_tree_view_action_open                  (ThunarTreeView          *view);
+static void                     thunar_tree_view_open_selection               (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_open_in_new_window    (ThunarTreeView          *view);
+static void                     thunar_tree_view_open_selection_in_new_window (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_paste_into_folder     (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_properties            (ThunarTreeView          *view);
+static GClosure                *thunar_tree_view_new_files_closure            (ThunarTreeView          *view);
+static void                     thunar_tree_view_new_files                    (ThunarJob               *job,
+                                                                               GList                   *path_list,
+                                                                               ThunarTreeView          *view);
+static gboolean                 thunar_tree_view_visible_func                 (ThunarTreeModel         *model,
+                                                                               ThunarFile              *file,
+                                                                               gpointer                 user_data);
+static gboolean                 thunar_tree_view_selection_func               (GtkTreeSelection        *selection,
+                                                                               GtkTreeModel            *model,
+                                                                               GtkTreePath             *path,
+                                                                               gboolean                 path_currently_selected,
+                                                                               gpointer                 user_data);
+static gboolean                 thunar_tree_view_cursor_idle                  (gpointer                 user_data);
+static void                     thunar_tree_view_cursor_idle_destroy          (gpointer                 user_data);
+static gboolean                 thunar_tree_view_drag_scroll_timer            (gpointer                 user_data);
+static void                     thunar_tree_view_drag_scroll_timer_destroy    (gpointer                 user_data);
+static gboolean                 thunar_tree_view_expand_timer                 (gpointer                 user_data);
+static void                     thunar_tree_view_expand_timer_destroy         (gpointer                 user_data);
+static ThunarTreeViewMountData *thunar_tree_view_mount_data_new               (ThunarTreeView          *view,
+                                                                               GtkTreePath             *path,
+                                                                               gboolean                 open_after_mounting,
+                                                                               gboolean                 open_in_new_window);
+static void                     thunar_tree_view_mount_data_free              (ThunarTreeViewMountData *data);
 
 
 
@@ -227,8 +243,16 @@
   gint                    expand_timer_id;
 };
 
+struct _ThunarTreeViewMountData
+{
+  ThunarTreeView *view;
+  GtkTreePath    *path;
+  gboolean        open_after_mounting;
+  gboolean        open_in_new_window;
+};
 
 
+
 /* Target types for dropping into the tree view */
 static const GtkTargetEntry drop_targets[] = {
   { "text/uri-list", 0, TARGET_TEXT_URI_LIST },
@@ -953,11 +977,12 @@
                                   GtkTreeIter *iter,
                                   GtkTreePath *path)
 {
-  ThunarVfsVolume *volume;
-  ThunarTreeView  *view = THUNAR_TREE_VIEW (tree_view);
-  GtkWidget       *window;
-  gboolean         expandable = TRUE;
-  GError          *error = NULL;
+  ThunarTreeViewMountData *data;
+  GMountOperation         *mount_operation;
+  ThunarTreeView          *view = THUNAR_TREE_VIEW (tree_view);
+  GtkWidget               *window;
+  gboolean                 expandable = TRUE;
+  GVolume                 *volume;
 
   /* determine the volume for the iterator */
   gtk_tree_model_get (GTK_TREE_MODEL (view->model), iter, THUNAR_TREE_MODEL_COLUMN_VOLUME, &volume, -1);
@@ -966,19 +991,25 @@
   if (G_UNLIKELY (volume != NULL))
     {
       /* check if we need to mount the volume first */
-      if (!thunar_vfs_volume_is_mounted (volume))
+      if (!g_volume_is_mounted (volume))
         {
-          /* determine the toplevel window */
+          /* we need to mount the volume before we can expand the row */
+          expandable = FALSE;
+
+          /* allocate a mount data struct */
+          data = thunar_tree_view_mount_data_new (view, path, FALSE, FALSE);
+
+          /* allocate a GTK+ mount operation */
           window = gtk_widget_get_toplevel (GTK_WIDGET (view));
+          mount_operation = gtk_mount_operation_new (GTK_WINDOW (window));
 
-          /* try to mount the volume */
-          expandable = thunar_vfs_volume_mount (volume, window, &error);
-          if (G_UNLIKELY (!expandable))
-            {
-              /* display an error dialog to inform the user */
-              thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume));
-              g_error_free (error);
-            }
+          /* try to mount the volume and expand the row on success. the
+           * data is destroyed in the finish callback */
+          g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL,
+                          thunar_tree_view_mount_finish, data);
+
+          /* release the mount operation */
+          g_object_unref (mount_operation);
         }
 
       /* release the volume */
@@ -1039,15 +1070,15 @@
                                GtkTreeModel   *model,
                                GtkTreeIter    *iter)
 {
-  ThunarVfsVolume *volume;
-  ThunarFile      *parent_file;
-  ThunarFile      *file;
-  GtkWidget       *image;
-  GtkWidget       *menu;
-  GtkWidget       *item;
-  GtkWidget       *window;
-  GList           *providers, *lp;
-  GList           *actions = NULL, *tmp;
+  GVolume    *volume;
+  ThunarFile *parent_file;
+  ThunarFile *file;
+  GtkWidget  *image;
+  GtkWidget  *menu;
+  GtkWidget  *item;
+  GtkWidget  *window;
+  GList      *providers, *lp;
+  GList      *actions = NULL, *tmp;
 
   /* verify that we're connected to the clipboard manager */
   if (G_UNLIKELY (view->clipboard == NULL))
@@ -1090,13 +1121,13 @@
     {
       /* append the "Mount Volume" menu action */
       item = gtk_image_menu_item_new_with_mnemonic (_("_Mount Volume"));
-      gtk_widget_set_sensitive (item, !thunar_vfs_volume_is_mounted (volume));
+      gtk_widget_set_sensitive (item, !g_volume_is_mounted (volume));
       g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_mount), view);
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
       gtk_widget_show (item);
 
       /* check if the volume is ejectable */
-      if (thunar_vfs_volume_is_ejectable (volume))
+      if (g_volume_is_removable (volume))
         {
           /* append the "Eject Volume" menu action */
           item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume"));
@@ -1104,15 +1135,6 @@
           gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
           gtk_widget_show (item);
         }
-      else
-        {
-          /* append the "Unmount Volume" menu item */
-          item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume"));
-          gtk_widget_set_sensitive (item, thunar_vfs_volume_is_mounted (volume));
-          g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_unmount), view);
-          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-          gtk_widget_show (item);
-        }
 
       /* append a menu separator */
       item = gtk_separator_menu_item_new ();
@@ -1465,6 +1487,12 @@
 
   /* determine file for the selected row */
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+  
+  /* avoid dealing with invalid selections (may occur when the mount_finish()
+   * handler is called and the tree view has been hidden already) */
+  if (!GTK_IS_TREE_SELECTION (selection))
+    return NULL;
+
   if (gtk_tree_selection_get_selected (selection, &model, &iter))
     gtk_tree_model_get (model, &iter, THUNAR_TREE_MODEL_COLUMN_FILE, &file, -1);
 
@@ -1473,11 +1501,11 @@
 
 
 
-static ThunarVfsVolume*
+static GVolume*
 thunar_tree_view_get_selected_volume (ThunarTreeView *view)
 {
   GtkTreeSelection *selection;
-  ThunarVfsVolume  *volume = NULL;
+  GVolume          *volume = NULL;
   GtkTreeModel     *model;
   GtkTreeIter       iter;
 
@@ -1653,11 +1681,84 @@
 
 
 static void
+thunar_tree_view_action_eject_finish (GObject      *object,
+                                      GAsyncResult *result,
+                                      gpointer      user_data)
+{
+  ThunarTreeView *view = THUNAR_TREE_VIEW (user_data);
+  GtkWidget      *window;
+  GVolume        *volume = G_VOLUME (object);
+  GError         *error = NULL;
+  gchar          *volume_name;
+
+  _thunar_return_if_fail (G_IS_VOLUME (object));
+  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+
+  /* check if there was an error */
+  if (!g_volume_eject_finish (volume, result, &error))
+    {
+      /* ignore GIO errors already handled */
+      if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED)
+        {
+          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
+
+          /* display an error dialog to inform the user */
+          volume_name = g_volume_get_name (volume);
+          thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), volume_name);
+          g_free (volume_name);
+
+          g_error_free (error);
+        }
+    }
+
+  g_object_unref (view);
+}
+
+
+
+static void
+thunar_tree_view_action_unmount_finish (GObject      *object,
+                                        GAsyncResult *result,
+                                        gpointer      user_data)
+{
+  ThunarTreeView *view = THUNAR_TREE_VIEW (user_data);
+  GtkWidget      *window;
+  GMount         *mount = G_MOUNT (object);
+  GError         *error = NULL;
+  gchar          *mount_name;
+
+  _thunar_return_if_fail (G_IS_MOUNT (object));
+  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+
+  /* check if there was an error */
+  if (!g_mount_unmount_finish (mount, result, &error))
+    {
+      /* ignore GIO errors already handled */
+      if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED)
+        {
+          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
+
+          /* display an error dialog to inform the user */
+          mount_name = g_mount_get_name (mount);
+          thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), mount_name);
+          g_free (mount_name);
+
+          g_error_free (error);
+        }
+    }
+
+  g_object_unref (view);
+}
+
+
+
+static void
 thunar_tree_view_action_eject (ThunarTreeView *view)
 {
-  ThunarVfsVolume *volume;
-  GtkWidget       *window;
-  GError          *error = NULL;
+  GVolume   *volume;
+  GMount    *mount;
 
   _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
 
@@ -1665,19 +1766,32 @@
   volume = thunar_tree_view_get_selected_volume (view);
   if (G_LIKELY (volume != NULL))
     {
-      /* determine the toplevel window */
-      window = gtk_widget_get_toplevel (GTK_WIDGET (view));
-
-      /* try to eject the volume */
-      if (!thunar_vfs_volume_eject (volume, window, &error))
+      /* determine what the appropriate method is: eject or unmount */
+      if (g_volume_can_eject (volume))
         {
-          /* display an error dialog to inform the user */
-          thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), thunar_vfs_volume_get_name (volume));
-          g_error_free (error);
+          /* try to to eject the volume asynchronously */
+          g_volume_eject (volume, G_MOUNT_UNMOUNT_NONE, NULL, 
+                          thunar_tree_view_action_eject_finish, 
+                          g_object_ref (view));
         }
+      else
+        {
+          /* determine the mount of the volume */
+          mount = g_volume_get_mount (volume);
+          if (G_LIKELY (mount != NULL))
+            {
+              /* the volume is mounted, try to unmount the mount */
+              g_mount_unmount (mount, G_MOUNT_UNMOUNT_NONE, NULL,
+                               thunar_tree_view_action_unmount_finish, 
+                               g_object_ref (view));
 
+              /* release the mount */
+              g_object_unref (mount);
+            }
+        }
+
       /* release the volume */
-      g_object_unref (G_OBJECT (volume));
+      g_object_unref (volume);
     }
 }
 
@@ -1698,41 +1812,109 @@
 
 
 
-static gboolean
+static void
 thunar_tree_view_action_mount (ThunarTreeView *view)
 {
-  ThunarVfsVolume *volume;
-  GtkWidget       *window;
-  gboolean         result = TRUE;
-  GError          *error = NULL;
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+  thunar_tree_view_mount (view, FALSE, FALSE);
+}
 
-  _thunar_return_val_if_fail (THUNAR_IS_TREE_VIEW (view), FALSE);
 
+
+static void
+thunar_tree_view_mount_finish (GObject      *object,
+                               GAsyncResult *result,
+                               gpointer      user_data)
+{
+  ThunarTreeViewMountData *data = user_data;
+  GtkWidget               *window;
+  GVolume                 *volume = G_VOLUME (object);
+  GError                  *error = NULL;
+  gchar                   *volume_name;
+
+  _thunar_return_if_fail (G_IS_VOLUME (object));
+  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
+  _thunar_return_if_fail (data != NULL && THUNAR_IS_TREE_VIEW (data->view));
+
+  /* check if there was an error */
+  if (!g_volume_mount_finish (volume, result, &error))
+    {
+      /* ignore GIO already handled errors or errors due to pending mount actions */
+      if (error->domain != G_IO_ERROR 
+          || (error->code != G_IO_ERROR_FAILED_HANDLED 
+              && error->code != G_IO_ERROR_ALREADY_MOUNTED
+              && error->code != G_IO_ERROR_PENDING))
+        {
+          window = gtk_widget_get_toplevel (GTK_WIDGET (data->view));
+
+          /* display an error dialog to inform the user */
+          volume_name = g_volume_get_name (volume);
+          thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), volume_name);
+          g_free (volume_name);
+
+          /* free the error */
+          g_error_free (error);
+        }
+    }
+  else
+    {
+      if (G_LIKELY (data->open_after_mounting))
+        {
+          if (data->open_in_new_window)
+            thunar_tree_view_open_selection_in_new_window (data->view);
+          else
+            thunar_tree_view_open_selection (data->view);
+        }
+      else if (data->path != NULL)
+        {
+          gtk_tree_view_expand_row (GTK_TREE_VIEW (data->view), data->path, FALSE);
+        }
+    }
+
+  thunar_tree_view_mount_data_free (data);
+}
+
+
+
+static void
+thunar_tree_view_mount (ThunarTreeView *view,
+                        gboolean        open_after_mounting,
+                        gboolean        open_in_new_window)
+{
+  ThunarTreeViewMountData *data;
+  GMountOperation         *mount_operation;
+  GtkWidget               *window;
+  GVolume                 *volume;
+
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+
   /* determine the selected volume */
   volume = thunar_tree_view_get_selected_volume (view);
-  if (G_UNLIKELY (volume != NULL))
+  if (volume != NULL)
     {
-      /* check if the volume is not already mounted */
-      if (!thunar_vfs_volume_is_mounted (volume))
+      /* check if we need to mount the volume at all */
+      if (!g_volume_is_mounted (volume))
         {
-          /* determine the toplevel window */
+          /* allocate mount data */
+          data = thunar_tree_view_mount_data_new (view, NULL, open_after_mounting, 
+                                                  open_in_new_window);
+
+          /* allocate a GTK+ mount operation */
           window = gtk_widget_get_toplevel (GTK_WIDGET (view));
+          mount_operation = gtk_mount_operation_new (GTK_WINDOW (window));
 
-          /* try to mount the volume */
-          result = thunar_vfs_volume_mount (volume, window, &error);
-          if (G_UNLIKELY (!result))
-            {
-              /* display an error dialog to inform the user */
-              thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume));
-              g_error_free (error);
-            }
+          /* try to mount the volume and expand the row on success. the
+           * data is destroyed in the finish callback */
+          g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_operation, NULL,
+                          thunar_tree_view_mount_finish, data);
+
+          /* release the mount operation */
+          g_object_unref (mount_operation);
         }
 
       /* release the volume */
-      g_object_unref (G_OBJECT (volume));
+      g_object_unref (volume);
     }
-
-  return result;
 }
 
 
@@ -1741,20 +1923,46 @@
 thunar_tree_view_action_open (ThunarTreeView *view)
 {
   ThunarFile *file;
+  GVolume    *volume;
 
   _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
 
-  /* if its a volume, make sure its mounted */
-  if (!thunar_tree_view_action_mount (view))
-    return;
+  /* determine the selected volume and file */
+  volume = thunar_tree_view_get_selected_volume (view);
+  file = thunar_tree_view_get_selected_file (view);
 
+  if (volume != NULL)
+    {
+      if (g_volume_is_mounted (volume))
+        thunar_tree_view_open_selection (view);
+      else
+        thunar_tree_view_mount (view, TRUE, FALSE);
+      
+      g_object_unref (volume);
+    }
+  else if (file != NULL)
+    {
+      thunar_tree_view_open_selection (view);
+      g_object_unref (file);
+    }
+}
+
+
+
+static void
+thunar_tree_view_open_selection (ThunarTreeView *view)
+{
+  ThunarFile *file;
+
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+
   /* determine the selected file */
   file = thunar_tree_view_get_selected_file (view);
   if (G_LIKELY (file != NULL))
     {
       /* open that folder in the main view */
       thunar_navigator_change_directory (THUNAR_NAVIGATOR (view), file);
-      g_object_unref (G_OBJECT (file));
+      g_object_unref (file);
     }
 }
 
@@ -1763,24 +1971,51 @@
 static void
 thunar_tree_view_action_open_in_new_window (ThunarTreeView *view)
 {
+  ThunarFile *file;
+  GVolume    *volume;
+
+  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
+
+  /* determine the selected volume and file */
+  volume = thunar_tree_view_get_selected_volume (view);
+  file = thunar_tree_view_get_selected_file (view);
+
+  if (volume != NULL)
+    {
+      if (g_volume_is_mounted (volume))
+        thunar_tree_view_open_selection_in_new_window (view);
+      else
+        thunar_tree_view_mount (view, TRUE, FALSE);
+      
+      g_object_unref (volume);
+    }
+  else if (file != NULL)
+    {
+      thunar_tree_view_open_selection_in_new_window (view);
+      g_object_unref (file);
+    }
+}
+
+
+
+static void
+thunar_tree_view_open_selection_in_new_window (ThunarTreeView *view)
+{
   ThunarApplication *application;
   ThunarFile        *file;
 
   _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
 
-  /* if its a volume, make sure its mounted */
-  if (!thunar_tree_view_action_mount (view))
-    return;
-
   /* determine the selected file */
   file = thunar_tree_view_get_selected_file (view);
   if (G_LIKELY (file != NULL))
     {
       /* open a new window for the selected folder */
       application = thunar_application_get ();
-      thunar_application_open_window (application, file, gtk_widget_get_screen (GTK_WIDGET (view)));
-      g_object_unref (G_OBJECT (application));
-      g_object_unref (G_OBJECT (file));
+      thunar_application_open_window (application, file, 
+                                      gtk_widget_get_screen (GTK_WIDGET (view)));
+      g_object_unref (application);
+      g_object_unref (file);
     }
 }
 
@@ -1843,37 +2078,6 @@
 
 
 
-static void
-thunar_tree_view_action_unmount (ThunarTreeView *view)
-{
-  ThunarVfsVolume *volume;
-  GtkWidget       *window;
-  GError          *error = NULL;
-
-  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
-
-  /* determine the selected volume */
-  volume = thunar_tree_view_get_selected_volume (view);
-  if (G_LIKELY (volume != NULL))
-    {
-      /* determine the toplevel window */
-      window = gtk_widget_get_toplevel (GTK_WIDGET (view));
-
-      /* try to unmount the volume */
-      if (!thunar_vfs_volume_unmount (volume, window, &error))
-        {
-          /* display an error dialog */
-          thunar_dialogs_show_error (window, error, _("Failed to unmount \"%s\""), thunar_vfs_volume_get_name (volume));
-          g_error_free (error);
-        }
-
-      /* release the volume */
-      g_object_unref (G_OBJECT (volume));
-    }
-}
-
-
-
 static GClosure*
 thunar_tree_view_new_files_closure (ThunarTreeView *view)
 {
@@ -1948,13 +2152,13 @@
                                  gboolean          path_currently_selected,
                                  gpointer          user_data)
 {
-  ThunarVfsVolume *volume;
-  GtkTreeIter      iter;
-  ThunarFile      *file;
-  gboolean         result = FALSE;
+  GtkTreeIter  iter;
+  ThunarFile  *file;
+  gboolean     result = FALSE;
+  GVolume     *volume;
 
   /* every row may be unselected at any time */
-  if (G_UNLIKELY (path_currently_selected))
+  if (path_currently_selected)
     return TRUE;
 
   /* determine the iterator for the path */
@@ -1968,7 +2172,7 @@
           result = TRUE;
 
           /* release file */
-          g_object_unref (G_OBJECT (file));
+          g_object_unref (file);
         }
       else
         {
@@ -1980,7 +2184,7 @@
               result = TRUE;
 
               /* release volume */
-              g_object_unref (G_OBJECT (volume));
+              g_object_unref (volume);
             }
         }
     }
@@ -2198,6 +2402,38 @@
 
 
 
+static ThunarTreeViewMountData *
+thunar_tree_view_mount_data_new (ThunarTreeView *view,
+                                 GtkTreePath    *path,
+                                 gboolean        open_after_mounting,
+                                 gboolean        open_in_new_window)
+{
+  ThunarTreeViewMountData *data;
+
+  data = _thunar_slice_new0 (ThunarTreeViewMountData);
+  data->path = path == NULL ? NULL : gtk_tree_path_copy (path);
+  data->view = g_object_ref (view);
+  data->open_after_mounting = open_after_mounting;
+  data->open_in_new_window = open_in_new_window;
+
+  return data;
+}
+
+
+
+static void
+thunar_tree_view_mount_data_free (ThunarTreeViewMountData *data)
+{
+  _thunar_return_if_fail (data != NULL && THUNAR_IS_TREE_VIEW (data->view));
+
+  if (data->path != NULL)
+    gtk_tree_path_free (data->path);
+  g_object_unref (data->view);
+  _thunar_slice_free (ThunarTreeViewMountData, data);
+}
+
+
+
 /**
  * thunar_tree_view_new:
  *




More information about the Xfce4-commits mailing list