From 36ee7425723bbd110efc761c56e144adfca57d5f Mon Sep 17 00:00:00 2001
From: Benedikt Meurer <benny@xfce.org>
Date: Mon, 13 Feb 2006 17:53:40 +0000
Subject: [PATCH] 2006-02-13	Benedikt Meurer <benny@xfce.org>

	* thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Fix
	  typo in hidden file detection.
	* thunar-vfs/thunar-vfs-volume.{c,h}: Add a few new volume types.
	* docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml: Update API
	  docs.
	* thunar-vfs/thunar-vfs-volume-hal.{c,h}, thunar-vfs/Makefile.am,
	  configure.in.in: Import the Linux/HAL implementation of the volume
	  manager. It's still a bit rough, but it seems to work ok. Works only
	  with pmount-hal currently, but that shouldn't be a problem. Bug #999.
	* thunar/thunar-shortcuts-model.c: Handle the addition/removal of
	  volumes and do not open a file for volume shortcuts as that may
	  prevent the volume from being unmounted properly.
	* thunar-vfs/thunar-vfs-volume.c: Setup a watch cursor on the given
	  window when ejecting, mounting or unmounting a volume, so the user
	  gets some feedback during the time it takes to perform the operation.
	* po/POTFILES.in: Add new file.
	* po/Thunar.pot, po/*.po: Merge new strings.




(Old svn revision: 19857)
---
 ChangeLog                                     |   20 +
 configure.in.in                               |   19 +-
 .../thunar-vfs/tmpl/thunar-vfs-volume.sgml    |   10 +-
 po/POTFILES.in                                |    1 +
 po/Thunar.pot                                 |   16 +-
 po/ca.po                                      |   16 +-
 po/de.po                                      |   16 +-
 po/el.po                                      |   16 +-
 po/es.po                                      |   16 +-
 po/fr.po                                      |   16 +-
 po/hu.po                                      |   16 +-
 po/it.po                                      |   16 +-
 po/ja.po                                      |   16 +-
 po/nl.po                                      |   16 +-
 po/pl.po                                      |   16 +-
 po/pt_BR.po                                   |   16 +-
 po/ru.po                                      |   16 +-
 thunar-vfs/Makefile.am                        |    6 +
 thunar-vfs/thunar-vfs-info.c                  |    2 +-
 thunar-vfs/thunar-vfs-volume-hal.c            | 1022 +++++++++++++++++
 thunar-vfs/thunar-vfs-volume-hal.h            |   55 +
 thunar-vfs/thunar-vfs-volume.c                |  154 ++-
 thunar-vfs/thunar-vfs-volume.h                |   30 +-
 thunar/thunar-shortcuts-model.c               |  258 +++--
 24 files changed, 1659 insertions(+), 126 deletions(-)
 create mode 100644 thunar-vfs/thunar-vfs-volume-hal.c
 create mode 100644 thunar-vfs/thunar-vfs-volume-hal.h

diff --git a/ChangeLog b/ChangeLog
index d935d04c3..362289674 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2006-02-13	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-info.c(_thunar_vfs_info_new_internal): Fix
+	  typo in hidden file detection.
+	* thunar-vfs/thunar-vfs-volume.{c,h}: Add a few new volume types.
+	* docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml: Update API
+	  docs.
+	* thunar-vfs/thunar-vfs-volume-hal.{c,h}, thunar-vfs/Makefile.am,
+	  configure.in.in: Import the Linux/HAL implementation of the volume
+	  manager. It's still a bit rough, but it seems to work ok. Works only
+	  with pmount-hal currently, but that shouldn't be a problem. Bug #999.
+	* thunar/thunar-shortcuts-model.c: Handle the addition/removal of
+	  volumes and do not open a file for volume shortcuts as that may
+	  prevent the volume from being unmounted properly.
+	* thunar-vfs/thunar-vfs-volume.c: Setup a watch cursor on the given
+	  window when ejecting, mounting or unmounting a volume, so the user
+	  gets some feedback during the time it takes to perform the operation.
+	* po/POTFILES.in: Add new file.
+	* po/Thunar.pot, po/*.po: Merge new strings.
+
 2006-02-13	Benedikt Meurer <benny@xfce.org>
 
 	* thunar/thunar-enum-types.{c,h}, thunar/thunar-list-model.h: Rename
diff --git a/configure.in.in b/configure.in.in
index 0ac9df160..3111fd80a 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -102,7 +102,7 @@ dnl **********************************
 dnl *** Check for standard headers ***
 dnl **********************************
 AC_CHECK_HEADERS([ctype.h dirent.h errno.h fcntl.h fnmatch.h fstab.h grp.h \
-                  locale.h math.h memory.h mmintrin.h pwd.h regex.h sched.h setjmp.h \
+                  locale.h math.h memory.h mmintrin.h mntent.h pwd.h regex.h sched.h setjmp.h \
                   stdarg.h stdlib.h string.h sys/xattr.h sys/extattr.h \
                   sys/cdio.h sys/mman.h sys/mount.h sys/param.h sys/stat.h \
                   sys/statfs.h sys/statvfs.h sys/time.h sys/uio.h \
@@ -242,6 +242,23 @@ case "$target_os" in
 *bsd*)
   FLAVOUR="bsd"
   ;;
+*linux*)
+  # on Linux, we try to use HAL first, and fallback to generic
+  XDT_CHECK_PACKAGE([HAL], [hal-storage], [0.4],
+  [
+    # we also need D-BUS GLib bindings, but 0.23 will do
+    XDT_CHECK_PACKAGE([HAL_DBUS], [dbus-glib-1], [0.23],
+    [
+      FLAVOUR="hal"
+    ],
+    [
+      FLAVOUR="sysv"
+    ])
+  ],
+  [
+    FLAVOUR="sysv"
+  ])
+  ;;
 *)
   FLAVOUR="sysv"
   ;;
diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml
index f88e6f579..ce5eed3c9 100644
--- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml
+++ b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml
@@ -24,10 +24,18 @@ ThunarVfsVolume
 
 @THUNAR_VFS_VOLUME_KIND_UNKNOWN: 
 @THUNAR_VFS_VOLUME_KIND_CDROM: 
-@THUNAR_VFS_VOLUME_KIND_DVD: 
+@THUNAR_VFS_VOLUME_KIND_CDR: 
+@THUNAR_VFS_VOLUME_KIND_CDRW: 
+@THUNAR_VFS_VOLUME_KIND_DVDROM: 
+@THUNAR_VFS_VOLUME_KIND_DVDRAM: 
+@THUNAR_VFS_VOLUME_KIND_DVDR: 
+@THUNAR_VFS_VOLUME_KIND_DVDRW: 
+@THUNAR_VFS_VOLUME_KIND_DVDPLUSR: 
+@THUNAR_VFS_VOLUME_KIND_DVDPLUSRW: 
 @THUNAR_VFS_VOLUME_KIND_FLOPPY: 
 @THUNAR_VFS_VOLUME_KIND_HARDDISK: 
 @THUNAR_VFS_VOLUME_KIND_USBSTICK: 
+@THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER: 
 
 <!-- ##### ENUM ThunarVfsVolumeStatus ##### -->
 <para>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 51c6f8e05..bd67c9dce 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -29,6 +29,7 @@ thunar-vfs/thunar-vfs-unlink-job.c
 thunar-vfs/thunar-vfs-user.c
 thunar-vfs/thunar-vfs-util.c
 thunar-vfs/thunar-vfs-volume-bsd.c
+thunar-vfs/thunar-vfs-volume-hal.c
 thunar-vfs/thunar-vfs-volume-sysv.c
 thunar-vfs/thunar-vfs-xfer.c
 thunar-vfs/thunar-vfs.c
diff --git a/po/Thunar.pot b/po/Thunar.pot
index e07e7444c..509cc9612 100644
--- a/po/Thunar.pot
+++ b/po/Thunar.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -235,9 +235,23 @@ msgstr ""
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr ""
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr ""
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr ""
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/ca.po b/po/ca.po
index b94ac460f..34cf0aca1 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-29 15:14+0900\n"
 "Last-Translator: Pau Rul·lan Ferragut <paurullan@bulma.net>\n"
 "Language-Team: Catalan\n"
@@ -254,10 +254,24 @@ msgstr "Usuari `%s' desconegut"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "Desconegut fitxer propietari"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "No s'ha pogut determinar l'informació de `%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Ha fallat"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/de.po b/po/de.po
index 1f95db167..a02c7ed33 100644
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-02-05 23:10+0100\n"
 "Last-Translator: Benedikt Meurer <benny@xfce.org>\n"
 "Language-Team: German <de@li.org>\n"
@@ -242,9 +242,23 @@ msgstr "Unbekannter Benutzer »%s«"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr "Unbekannter Fehler"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Andere Anwendung..."
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Konnte »%s« nicht umbenennen"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/el.po b/po/el.po
index dfcb07d01..86dec3df8 100644
--- a/po/el.po
+++ b/po/el.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-02-12 03:05+0200\n"
 "Last-Translator: Stavros Giannouris <stavrosg2002@freemail.gr>\n"
 "Language-Team: Greek <nls@tux.hellug.gr>\n"
@@ -252,9 +252,23 @@ msgstr "Άγνωστος χρήστης `%s'"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr "Άγνωστο σφάλμα"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Ο προσδιορισμός των πληροφοριών αρχείου για το `%s' απέτυχε"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Η διαγραφή του \"%s\" απέτυχε: %s"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/es.po b/po/es.po
index 0de4f67e5..44f685dec 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2005-10-14 23:57+0900\n"
 "Last-Translator: Pablo Hernández-M. Saiz <homeless3d@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
@@ -253,9 +253,23 @@ msgstr ""
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr ""
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Imposible renombrar %s."
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Imposible renombrar %s."
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/fr.po b/po/fr.po
index 631c4f627..fea067aa8 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-01 15:02+0100\n"
 "Last-Translator: Stephane Roy <sroy@j2n.net>\n"
 "Language-Team: French <traduc@traduc.org>\n"
@@ -253,10 +253,24 @@ msgstr "Élément <%s> inconnu"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "Élément <%s> inconnu"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Échec à la détermination d'informations sur le fichier `%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Échec au changement de nom de `%s'"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/hu.po b/po/hu.po
index c6e5a3318..522efbda9 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2005-10-06 22:02+0900\n"
 "Last-Translator: SZERVÁC Attila <sas@321.hu>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
@@ -251,9 +251,23 @@ msgstr ""
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr ""
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Nem sikerült meghatározni a szülő URI-t ehhez: %s"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Nem törölhető: %s"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/it.po b/po/it.po
index 6554f285a..fa1313808 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-21 10:58+0100\n"
 "Last-Translator: Roberto Pariset <r.pariset@gmail.com>\n"
 "Language-Team: GUFI <traduzioni@gufi.org>\n"
@@ -256,10 +256,24 @@ msgstr "Utente `%s' sconosciuto"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "Utente `%s' sconosciuto"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Impossibile reperire informazioni per il file `%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Impossibile rinominare `%s'"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/ja.po b/po/ja.po
index 34cfe7fbe..12d14edef 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -14,7 +14,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-02-11 20:29+0900\n"
 "Last-Translator: Daichi Kawahata <daichi@xfce.org>\n"
 "Language-Team: Japanese <xfce-users-jp@ml.fdiary.net>\n"
@@ -259,9 +259,23 @@ msgstr "ユーザー「%s」は不明です。"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr "原因不明のエラーが発生しました。"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "「%s」のファイル情報を確定するのに失敗しました。"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "「%s」を開くのに失敗しました: %s"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/nl.po b/po/nl.po
index 5a069b81e..4f97a106f 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-31 14:07+0100\n"
 "Last-Translator: Vincent Tunru <imnotb@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@@ -260,10 +260,24 @@ msgstr "Onbekende gebruiker '%s'"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "Onbekende eigenaar"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Fout bij het ophalen van bestandsinfo van `%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Fout bij het wijzigen van de naam van `%s'"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/pl.po b/po/pl.po
index 06e749806..e0c738a85 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-13 14:21+0100\n"
 "Last-Translator: Tomasz Michał Łukaszewski <T.Lukaszewski@aster.pl>\n"
 "Language-Team: Polish <pl@li.org>\n"
@@ -252,10 +252,24 @@ msgstr ""
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "data nieznana"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Nie udało się odczytać atrybutów pliku '%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Nie udało się zmienić nazwy %s."
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index d7a0c95cb..7df695657 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-02-10 22:34-0200\n"
 "Last-Translator: Rodrigo Coacci <rcoacci@gmail.com>\n"
 "Language-Team: os-cillation <info@os-cillation.com>\n"
@@ -251,9 +251,23 @@ msgstr "Usuário desconhecido `%s'"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 msgid "Unknown error"
 msgstr "Erro desconhecido"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Falha em determinar informação de arquivo para `%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Falha ao abrir \"%s\": %s"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/po/ru.po b/po/ru.po
index 4e1e1fe49..026a9b7b9 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thunar 0.2.1svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 13:23+0100\n"
+"POT-Creation-Date: 2006-02-13 18:53+0100\n"
 "PO-Revision-Date: 2006-01-29 17:47+0500\n"
 "Last-Translator: Andrey Fedoseev <andrey.fedoseev@gmail.com>\n"
 "Language-Team: Russian <ru@li.org>\n"
@@ -254,10 +254,24 @@ msgstr "Неизвестный пользователь '%s'"
 
 #. no useful information, *narf*
 #: ../thunar-vfs/thunar-vfs-volume-bsd.c:303
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:218
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:276
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:391
 #, fuzzy
 msgid "Unknown error"
 msgstr "Неизвестный пользователь '%s'"
 
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:332
+#, fuzzy, c-format
+msgid "Unable to determine the mount point for %s"
+msgstr "Не удалось определить информацию о файле '%s'"
+
+#. if we cannot read /proc/mounts, we cannot where the volume was mounted
+#: ../thunar-vfs/thunar-vfs-volume-hal.c:340
+#, fuzzy, c-format
+msgid "Failed to open /proc/mounts: %s"
+msgstr "Не удалось переименовать `%s'"
+
 #: ../thunar-vfs/thunar-vfs-xfer.c:157
 #, c-format
 msgid "copy of %s"
diff --git a/thunar-vfs/Makefile.am b/thunar-vfs/Makefile.am
index 77a688e94..8064f33f0 100644
--- a/thunar-vfs/Makefile.am
+++ b/thunar-vfs/Makefile.am
@@ -112,6 +112,8 @@ libthunar_vfs_1_la_CFLAGS =						\
 	$(EXO_CFLAGS)							\
 	$(GCONF_CFLAGS)							\
 	$(GTHREAD_CFLAGS)						\
+	$(HAL_CFLAGS)							\
+	$(HAL_DBUS_CFLAGS)						\
 	$(LIBFAM_CFLAGS)						\
 	$(LIBJPEG_CFLAGS)						\
 	$(LIBPNG_CFLAGS)						\
@@ -128,6 +130,8 @@ libthunar_vfs_1_la_LIBADD =						\
 	$(EXO_LIBS)							\
 	$(GCONF_LIBS)							\
 	$(GTHREAD_LIBS)							\
+	$(HAL_LIBS)							\
+	$(HAL_DBUS_LIBS)						\
 	$(LIBFAM_LIBS)							\
 	$(LIBJPEG_LIBS)							\
 	$(LIBPNG_LIBS)							\
@@ -162,6 +166,8 @@ EXTRA_DIST =								\
 	thunar-vfs-marshal.list						\
 	thunar-vfs-volume-bsd.c						\
 	thunar-vfs-volume-bsd.h						\
+	thunar-vfs-volume-hal.c						\
+	thunar-vfs-volume-hal.h						\
 	thunar-vfs-volume-sysv.c					\
 	thunar-vfs-volume-sysv.h
 
diff --git a/thunar-vfs/thunar-vfs-info.c b/thunar-vfs/thunar-vfs-info.c
index 31b472604..08ba28512 100644
--- a/thunar-vfs/thunar-vfs-info.c
+++ b/thunar-vfs/thunar-vfs-info.c
@@ -789,7 +789,7 @@ _thunar_vfs_info_new_internal (ThunarVfsPath *path,
     }
 
   /* check whether we have a hidden file here */
-  if ((s - (const guchar *) name) > 2 && (*name == '.' || *(s - 1) == '~'))
+  if ((s - (const guchar *) name) > 1 && (*name == '.' || *(s - 1) == '~'))
     info->flags = THUNAR_VFS_FILE_FLAGS_HIDDEN;
   else
     info->flags = THUNAR_VFS_FILE_FLAGS_NONE;
diff --git a/thunar-vfs/thunar-vfs-volume-hal.c b/thunar-vfs/thunar-vfs-volume-hal.c
new file mode 100644
index 000000000..7b4bc8a6b
--- /dev/null
+++ b/thunar-vfs/thunar-vfs-volume-hal.c
@@ -0,0 +1,1022 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#include <stdio.h>
+
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <exo/exo.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+
+#include <thunar-vfs/thunar-vfs-volume-hal.h>
+#include <thunar-vfs/thunar-vfs-alias.h>
+
+
+
+static void                  thunar_vfs_volume_hal_class_init       (ThunarVfsVolumeHalClass *klass);
+static void                  thunar_vfs_volume_hal_volume_init      (ThunarVfsVolumeIface    *iface);
+static void                  thunar_vfs_volume_hal_init             (ThunarVfsVolumeHal      *volume_hal);
+static void                  thunar_vfs_volume_hal_finalize         (GObject                 *object);
+static ThunarVfsVolumeKind   thunar_vfs_volume_hal_get_kind         (ThunarVfsVolume         *volume);
+static const gchar          *thunar_vfs_volume_hal_get_name         (ThunarVfsVolume         *volume);
+static ThunarVfsVolumeStatus thunar_vfs_volume_hal_get_status       (ThunarVfsVolume         *volume);
+static ThunarVfsPath        *thunar_vfs_volume_hal_get_mount_point  (ThunarVfsVolume         *volume);
+static gboolean              thunar_vfs_volume_hal_eject            (ThunarVfsVolume         *volume,
+                                                                     GtkWidget               *window,
+                                                                     GError                 **error);
+static gboolean              thunar_vfs_volume_hal_mount            (ThunarVfsVolume         *volume,
+                                                                     GtkWidget               *window,
+                                                                     GError                 **error);
+static gboolean              thunar_vfs_volume_hal_unmount          (ThunarVfsVolume         *volume,
+                                                                     GtkWidget               *window,
+                                                                     GError                 **error);
+static void                  thunar_vfs_volume_hal_update           (ThunarVfsVolumeHal      *volume_hal,
+                                                                     LibHalContext           *context,
+                                                                     HalVolume               *hv,
+                                                                     HalDrive                *hd);
+
+
+
+struct _ThunarVfsVolumeHalClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarVfsVolumeHal
+{
+  GObject __parent__;
+
+  gchar                *udi;
+  gchar                *drive_udi;
+
+  gchar                *device_file;
+  gchar                *device_label;
+  ThunarVfsPath        *mount_point;
+  ThunarVfsVolumeKind   kind;
+  ThunarVfsVolumeStatus status;
+};
+
+
+
+G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeHal,
+                         thunar_vfs_volume_hal,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME,
+                                                thunar_vfs_volume_hal_volume_init));
+
+
+
+static void
+thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_volume_hal_finalize;
+}
+
+
+
+static void
+thunar_vfs_volume_hal_volume_init (ThunarVfsVolumeIface *iface)
+{
+  iface->get_kind = thunar_vfs_volume_hal_get_kind;
+  iface->get_name = thunar_vfs_volume_hal_get_name;
+  iface->get_status = thunar_vfs_volume_hal_get_status;
+  iface->get_mount_point = thunar_vfs_volume_hal_get_mount_point;
+  iface->eject = thunar_vfs_volume_hal_eject;
+  iface->mount = thunar_vfs_volume_hal_mount;
+  iface->unmount = thunar_vfs_volume_hal_unmount;
+}
+
+
+
+static void
+thunar_vfs_volume_hal_init (ThunarVfsVolumeHal *volume_hal)
+{
+}
+
+
+
+static void
+thunar_vfs_volume_hal_finalize (GObject *object)
+{
+  ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (object);
+
+  g_free (volume_hal->udi);
+  g_free (volume_hal->drive_udi);
+
+  g_free (volume_hal->device_file);
+  g_free (volume_hal->device_label);
+
+  /* release the mount point (if any) */
+  if (G_LIKELY (volume_hal->mount_point != NULL))
+    thunar_vfs_path_unref (volume_hal->mount_point);
+
+  (*G_OBJECT_CLASS (thunar_vfs_volume_hal_parent_class)->finalize) (object);
+}
+
+
+
+static ThunarVfsVolumeKind
+thunar_vfs_volume_hal_get_kind (ThunarVfsVolume *volume)
+{
+  return THUNAR_VFS_VOLUME_HAL (volume)->kind;
+}
+
+
+
+static const gchar*
+thunar_vfs_volume_hal_get_name (ThunarVfsVolume *volume)
+{
+  return THUNAR_VFS_VOLUME_HAL (volume)->device_label;
+}
+
+
+
+static ThunarVfsVolumeStatus
+thunar_vfs_volume_hal_get_status (ThunarVfsVolume *volume)
+{
+  return THUNAR_VFS_VOLUME_HAL (volume)->status;
+}
+
+
+
+static ThunarVfsPath*
+thunar_vfs_volume_hal_get_mount_point (ThunarVfsVolume *volume)
+{
+  return THUNAR_VFS_VOLUME_HAL (volume)->mount_point;
+}
+
+
+
+static gboolean
+thunar_vfs_volume_hal_eject (ThunarVfsVolume *volume,
+                             GtkWidget       *window,
+                             GError         **error)
+{
+  ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume);
+  gboolean            result;
+  gchar              *standard_error;
+  gchar              *command_line;
+  gchar              *quoted;
+  gint                exit_status;
+
+  /* generate the mount command */
+  quoted = g_path_get_basename (volume_hal->device_file);
+  command_line = g_strconcat ("eject ", quoted, NULL);
+  g_free (quoted);
+
+  /* execute the mount command */
+  result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, error);
+  if (G_LIKELY (result))
+    {
+      /* check if the command failed */
+      if (G_UNLIKELY (exit_status != 0))
+        {
+          /* drop additional whitespace from the stderr output */
+          g_strstrip (standard_error);
+
+          /* check if stderr output is usable as error message */
+          if (G_LIKELY (*standard_error != '\0'))
+            {
+              /* use standard error message if not empty */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, standard_error);
+            }
+          else
+            {
+              /* no useful information, *narf* */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unknown error"));
+            }
+
+          /* and yes, we failed */
+          result = FALSE;
+        }
+
+      /* release the stderr output */
+      g_free (standard_error);
+    }
+
+  /* cleanup */
+  g_free (command_line);
+
+  return result;
+}
+
+
+
+static gboolean
+thunar_vfs_volume_hal_mount (ThunarVfsVolume *volume,
+                             GtkWidget       *window,
+                             GError         **error)
+{
+  ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume);
+  ThunarVfsPath      *path;
+  struct mntent      *mntent;
+  gboolean            result;
+  gchar              *standard_error;
+  gchar              *command_line;
+  gchar              *quoted;
+  FILE               *fp;
+  gint                exit_status;
+
+  /* generate the mount command */
+  quoted = g_shell_quote (volume_hal->udi);
+  command_line = g_strconcat ("pmount-hal ", quoted, NULL);
+  g_free (quoted);
+
+  /* execute the mount command */
+  result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, error);
+  if (G_LIKELY (result))
+    {
+      /* check if the command failed */
+      if (G_UNLIKELY (exit_status != 0))
+        {
+          /* drop additional whitespace from the stderr output */
+          g_strstrip (standard_error);
+
+          /* check if stderr output is usable as error message */
+          if (G_LIKELY (*standard_error != '\0'))
+            {
+              /* use standard error message if not empty */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, standard_error);
+            }
+          else
+            {
+              /* no useful information, *narf* */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unknown error"));
+            }
+
+          /* and yes, we failed */
+          result = FALSE;
+        }
+
+      /* release the stderr output */
+      g_free (standard_error);
+    }
+
+  /* cleanup */
+  g_free (command_line);
+
+  /* check if we were successfull */
+  if (G_LIKELY (result))
+    {
+      /* try to figure out where the device was mounted */
+      fp = setmntent ("/proc/mounts", "r");
+      if (G_LIKELY (fp != NULL))
+        {
+          /* assume that we failed */
+          result = FALSE;
+
+          /* lookup the mount entry for our device */
+          for (;;)
+            {
+              /* read the next entry */
+              mntent = getmntent (fp);
+              if (mntent == NULL)
+                break;
+
+              /* check if this is the entry we are looking for */
+              if (exo_str_is_equal (mntent->mnt_fsname, volume_hal->device_file))
+                {
+                  /* transform the mount point to a path */
+                  path = thunar_vfs_path_new (mntent->mnt_dir, NULL);
+                  if (G_LIKELY (path != NULL))
+                    {
+                      /* we must have been mounted successfully */
+                      volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT;
+                      result = TRUE;
+
+                      /* replace the existing mount point */
+                      thunar_vfs_path_unref (volume_hal->mount_point);
+                      volume_hal->mount_point = path;
+
+                      /* tell everybody that we have a new state */
+                      thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal));
+                    }
+                  break;
+                }
+            }
+
+          /* check if we were unable to figure out the mount point */
+          if (G_UNLIKELY (!result))
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unable to determine the mount point for %s"), volume_hal->device_file);
+
+          /* close the file handle */
+          fclose (fp);
+        }
+      else
+        {
+          /* if we cannot read /proc/mounts, we cannot where the volume was mounted */
+          g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("Failed to open /proc/mounts: %s"), g_strerror (errno));
+          result = FALSE;
+        }
+    }
+
+  return result;
+}
+
+
+
+static gboolean
+thunar_vfs_volume_hal_unmount (ThunarVfsVolume *volume,
+                               GtkWidget       *window,
+                               GError         **error)
+{
+  ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume);
+  gboolean            result;
+  gchar               absolute_path[THUNAR_VFS_PATH_MAXSTRLEN];
+  gchar              *standard_error;
+  gchar              *command_line;
+  gchar              *quoted;
+  gint                exit_status;
+
+  /* determine the absolute path to the mount point */
+  if (thunar_vfs_path_to_string (volume_hal->mount_point, absolute_path, sizeof (absolute_path), error) < 0)
+    return FALSE;
+
+  /* generate the mount command */
+  quoted = g_shell_quote (absolute_path);
+  command_line = g_strconcat ("pumount ", quoted, NULL);
+  g_free (quoted);
+
+  /* execute the mount command */
+  result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, error);
+  if (G_LIKELY (result))
+    {
+      /* check if the command failed */
+      if (G_UNLIKELY (exit_status != 0))
+        {
+          /* drop additional whitespace from the stderr output */
+          g_strstrip (standard_error);
+
+          /* check if stderr output is usable as error message */
+          if (G_LIKELY (*standard_error != '\0'))
+            {
+              /* use standard error message if not empty */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, standard_error);
+            }
+          else
+            {
+              /* no useful information, *narf* */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unknown error"));
+            }
+
+          /* and yes, we failed */
+          result = FALSE;
+        }
+
+      /* release the stderr output */
+      g_free (standard_error);
+    }
+
+  /* cleanup */
+  g_free (command_line);
+
+  return result;
+}
+
+
+
+static void
+thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal,
+                              LibHalContext      *context,
+                              HalVolume          *hv,
+                              HalDrive           *hd)
+{
+  HalStoragePolicy *policy;
+  struct mntent    *mntent;
+  const gchar      *desired_mount_point;
+  const gchar      *volume_label;
+  gchar            *mount_root;
+  gchar            *basename;
+  gchar            *filename;
+  FILE             *fp;
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_HAL (volume_hal));
+  g_return_if_fail (hv != NULL);
+  g_return_if_fail (hd != NULL);
+
+  /* just allocate a policy (doesn't seem to be very useful) */
+  policy = hal_storage_policy_new ();
+
+  /* reset the volume status */
+  volume_hal->status = 0;
+
+  /* determine the new device file */
+  g_free (volume_hal->device_file);
+  volume_hal->device_file = g_strdup (hal_volume_get_device_file (hv));
+
+  /* determine the new label */
+  g_free (volume_hal->device_label);
+  volume_label = hal_volume_get_label (hv);
+  if (G_LIKELY (volume_label != NULL && *volume_label != '\0'))
+    {
+      /* just use the label provided by HAL */
+      volume_hal->device_label = g_strdup (volume_label);
+    }
+  else
+    {
+      /* use the basename of the device file as label */
+      volume_hal->device_label = g_path_get_basename (volume_hal->device_file);
+    }
+
+  /* release the previous mount point (if any) */
+  if (G_LIKELY (volume_hal->mount_point != NULL))
+    {
+      thunar_vfs_path_unref (volume_hal->mount_point);
+      volume_hal->mount_point = NULL;
+    }
+
+  /* determine the type of the volume */
+  switch (hal_drive_get_type (hd))
+    {
+    case HAL_DRIVE_TYPE_CDROM:
+      /* check which kind of CD-ROM/DVD we have */
+      switch (hal_volume_get_disc_type (hv))
+        {
+        case HAL_VOLUME_DISC_TYPE_CDROM:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDROM;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_CDR:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDR;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_CDRW:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_CDRW;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDROM:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDROM;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDRAM:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDRAM;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDR:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDR;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDRW:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDRW;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDPLUSR:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDPLUSR;
+          break;
+
+        case HAL_VOLUME_DISC_TYPE_DVDPLUSRW:
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_DVDPLUSRW;
+          break;
+
+        default:
+          /* unsupported disc type */
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_UNKNOWN;
+          break;
+        }
+      break;
+
+    case HAL_DRIVE_TYPE_FLOPPY:
+      volume_hal->kind = THUNAR_VFS_VOLUME_KIND_FLOPPY;
+      break;
+
+    case HAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
+      volume_hal->kind = THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER;
+      break;
+
+    case HAL_DRIVE_TYPE_MEMORY_STICK:
+    case HAL_DRIVE_TYPE_REMOVABLE_DISK:
+      /* check if the drive is connected to the USB bus */
+      if (hal_drive_get_bus (hd) == HAL_DRIVE_BUS_USB)
+        {
+          /* we consider the drive to be an USB stick */
+          volume_hal->kind = THUNAR_VFS_VOLUME_KIND_USBSTICK;
+          break;
+        }
+      /* FALL-THROUGH */
+
+    default:
+      /* fallback to harddisk drive */
+      volume_hal->kind = THUNAR_VFS_VOLUME_KIND_HARDDISK;
+      break;
+    }
+
+  /* non-disc drives are always present, otherwise it must be a data disc to be usable */
+  if (!hal_volume_is_disc (hv) || hal_volume_disc_has_data (hv))
+    volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_PRESENT;
+
+  /* check if the volume is currently mounted */
+  if (hal_volume_is_mounted (hv))
+    {
+      /* try to determine the new mount point */
+      volume_hal->mount_point = thunar_vfs_path_new (hal_volume_get_mount_point (hv), NULL);
+
+      /* we only mark the volume as mounted if we have a valid mount point */
+      if (G_LIKELY (volume_hal->mount_point != NULL))
+        volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT;
+    }
+
+  /* check if we have to figure out the mount point ourself */
+  if (G_UNLIKELY (volume_hal->mount_point == NULL))
+    {
+      /* ask HAL for the default mount root (fallback to /media) */
+      mount_root = hal_drive_policy_default_get_mount_root (context);
+      if (G_UNLIKELY (mount_root == NULL || !g_path_is_absolute (mount_root)))
+        {
+          /* fallback to /media (seems to be sane) */
+          g_free (mount_root);
+          mount_root = g_strdup ("/media");
+        }
+
+      /* lets see, maybe /etc/fstab knows where to mount */
+      fp = setmntent ("/etc/fstab", "r");
+      if (G_LIKELY (fp != NULL))
+        {
+          /* check all entries */
+          for (;;)
+            {
+              /* read the next entry */
+              mntent = getmntent (fp);
+              if (mntent == NULL)
+                break;
+
+              /* check if the entry is for our device */
+              if (exo_str_is_equal (mntent->mnt_fsname, volume_hal->device_file))
+                {
+                  /* transform to a path object */
+                  volume_hal->mount_point = thunar_vfs_path_new (mntent->mnt_dir, NULL);
+                  break;
+                }
+            }
+
+          /* close the /etc/fstab file handle */
+          endmntent (fp);
+        }
+
+      /* if we still don't have a mount point, ask HAL */
+      if (G_UNLIKELY (volume_hal->mount_point == NULL))
+        {
+          /* determine the desired mount point and prepend the mount root */
+          desired_mount_point = hal_volume_policy_get_desired_mount_point (hd, hv, policy);
+          if (G_LIKELY (desired_mount_point != NULL && *desired_mount_point != '\0'))
+            {
+              filename = g_build_filename (mount_root, desired_mount_point, NULL);
+              volume_hal->mount_point = thunar_vfs_path_new (filename, NULL);
+              g_free (filename);
+            }
+        }
+
+      /* ok, last fallback, just use <mount-root>/<device> */
+      if (G_UNLIKELY (volume_hal->mount_point == NULL))
+        {
+          /* <mount-root>/<device> looks like a good idea */
+          basename = g_path_get_basename (volume_hal->device_file);
+          filename = g_build_filename (mount_root, basename, NULL);
+          volume_hal->mount_point = thunar_vfs_path_new (filename, NULL);
+          g_free (filename);
+          g_free (basename);
+        }
+
+      /* release the mount root */
+      g_free (mount_root);
+    }
+
+  /* if we get here, we must have a valid mount point */
+  g_assert (volume_hal->mount_point != NULL);
+
+  /* emit the "changed" signal */
+  thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal));
+
+  /* and release the policy again */
+  hal_storage_policy_free (policy);
+}
+
+
+
+
+static void                thunar_vfs_volume_manager_hal_class_init               (ThunarVfsVolumeManagerHalClass *klass);
+static void                thunar_vfs_volume_manager_hal_manager_init             (ThunarVfsVolumeManagerIface    *iface);
+static void                thunar_vfs_volume_manager_hal_init                     (ThunarVfsVolumeManagerHal      *manager_hal);
+static void                thunar_vfs_volume_manager_hal_finalize                 (GObject                        *object);
+static ThunarVfsVolume    *thunar_vfs_volume_manager_hal_get_volume_by_info       (ThunarVfsVolumeManager         *manager,
+                                                                                   const ThunarVfsInfo            *info);
+static GList              *thunar_vfs_volume_manager_hal_get_volumes              (ThunarVfsVolumeManager         *manager);
+static ThunarVfsVolumeHal *thunar_vfs_volume_manager_hal_get_volume_by_udi        (ThunarVfsVolumeManagerHal      *manager_hal,
+                                                                                   const gchar                    *udi);
+static void                thunar_vfs_volume_manager_hal_update_volume_by_udi     (ThunarVfsVolumeManagerHal      *manager_hal,
+                                                                                   const gchar                    *udi);
+static void                thunar_vfs_volume_manager_hal_main_loop_integration    (LibHalContext                  *context,
+                                                                                   DBusConnection                 *dbus_connection);
+static void                thunar_vfs_volume_manager_hal_device_added             (LibHalContext                  *context,
+                                                                                   const gchar                    *udi);
+static void                thunar_vfs_volume_manager_hal_device_removed           (LibHalContext                  *context,
+                                                                                   const gchar                    *udi);
+static void                thunar_vfs_volume_manager_hal_device_new_capability    (LibHalContext                  *context,
+                                                                                   const gchar                    *udi,
+                                                                                   const gchar                    *capability);
+static void                thunar_vfs_volume_manager_hal_device_lost_capability   (LibHalContext                  *context,
+                                                                                   const gchar                    *udi,
+                                                                                   const gchar                    *capability);
+static void                thunar_vfs_volume_manager_hal_device_property_modified (LibHalContext                  *context,
+                                                                                   const gchar                    *udi,
+                                                                                   const gchar                    *key,
+                                                                                   dbus_bool_t                     is_removed,
+                                                                                   dbus_bool_t                     is_added);
+
+
+
+struct _ThunarVfsVolumeManagerHalClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarVfsVolumeManagerHal
+{
+  GObject        __parent__;
+  LibHalContext *context;
+  GList         *volumes;
+};
+
+
+
+G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeManagerHal,
+                         thunar_vfs_volume_manager_hal,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME_MANAGER,
+                                                thunar_vfs_volume_manager_hal_manager_init));
+
+
+
+static void
+thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_volume_manager_hal_finalize;
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_manager_init (ThunarVfsVolumeManagerIface *iface)
+{
+  iface->get_volume_by_info = thunar_vfs_volume_manager_hal_get_volume_by_info;
+  iface->get_volumes = thunar_vfs_volume_manager_hal_get_volumes;
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_init (ThunarVfsVolumeManagerHal *manager_hal)
+{
+  /* the HAL virtual function table */
+  static const LibHalFunctions HAL_FUNCTIONS =
+  {
+    thunar_vfs_volume_manager_hal_main_loop_integration,
+    thunar_vfs_volume_manager_hal_device_added,
+    thunar_vfs_volume_manager_hal_device_removed,
+    thunar_vfs_volume_manager_hal_device_new_capability,
+    thunar_vfs_volume_manager_hal_device_lost_capability,
+    thunar_vfs_volume_manager_hal_device_property_modified,
+    NULL,
+  };
+
+  gchar **udis;
+  gint    n_udis;
+  gint    n;
+
+  /* allocate the HAL context */
+  manager_hal->context = hal_initialize (&HAL_FUNCTIONS, FALSE);
+  if (G_LIKELY (manager_hal->context != NULL))
+    {
+      /* connect our manager object to the HAL context */
+      hal_ctx_set_user_data (manager_hal->context, manager_hal);
+
+      /* lookup all volumes currently known to HAL */
+      udis = hal_find_device_by_capability (manager_hal->context, "volume", &n_udis);
+      if (G_LIKELY (udis != NULL))
+        {
+          /* add volumes for all given UDIs */
+          for (n = 0; n < n_udis; ++n)
+            thunar_vfs_volume_manager_hal_device_added (manager_hal->context, udis[n]);
+
+          /* release the UDIs */
+          hal_free_string_array (udis);
+        }
+
+      /* watch all devices for changes */
+      hal_device_property_watch_all (manager_hal->context);
+    }
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_finalize (GObject *object)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = THUNAR_VFS_VOLUME_MANAGER_HAL (object);
+  GList                     *lp;
+
+  /* release all active volumes */
+  for (lp = manager_hal->volumes; lp != NULL; lp = lp->next)
+    g_object_unref (G_OBJECT (lp->data));
+  g_list_free (manager_hal->volumes);
+
+  /* shutdown the HAL context */
+  if (G_LIKELY (manager_hal->context != NULL))
+    hal_shutdown (manager_hal->context);
+
+  (*G_OBJECT_CLASS (thunar_vfs_volume_manager_hal_parent_class)->finalize) (object);
+}
+
+
+
+static ThunarVfsVolume*
+thunar_vfs_volume_manager_hal_get_volume_by_info (ThunarVfsVolumeManager *manager,
+                                                  const ThunarVfsInfo    *info)
+{
+  // FIXME: No idea how to implement this on Linux right now.
+  return NULL;
+}
+
+
+
+static GList*
+thunar_vfs_volume_manager_hal_get_volumes (ThunarVfsVolumeManager *manager)
+{
+  return THUNAR_VFS_VOLUME_MANAGER_HAL (manager)->volumes;
+}
+
+
+
+static ThunarVfsVolumeHal*
+thunar_vfs_volume_manager_hal_get_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal,
+                                                 const gchar               *udi)
+{
+  GList *lp;
+
+  for (lp = manager_hal->volumes; lp != NULL; lp = lp->next)
+    if (exo_str_is_equal (THUNAR_VFS_VOLUME_HAL (lp->data)->udi, udi))
+      return THUNAR_VFS_VOLUME_HAL (lp->data);
+
+  return NULL;
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_update_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal,
+                                                    const gchar               *udi)
+{
+  ThunarVfsVolumeHal *volume_hal;
+  const gchar        *drive_udi;
+  HalVolume          *hv = NULL;
+  HalDrive           *hd = NULL;
+
+  /* check if we have a volume for the UDI */
+  volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi);
+  if (G_UNLIKELY (volume_hal == NULL))
+    return;
+
+  /* check if we have a volume here */
+  hv = hal_volume_from_udi (manager_hal->context, udi);
+  if (G_UNLIKELY (hv == NULL))
+    {
+      /* the device is no longer a volume, so drop it */
+      thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi);
+      return;
+    }
+
+  /* determine the UDI of the drive to which this volume belongs */
+  drive_udi = hal_volume_get_storage_device_udi (hv);
+  if (G_LIKELY (drive_udi != NULL))
+    {
+      /* determine the drive for the volume */
+      hd = hal_drive_from_udi (manager_hal->context, drive_udi);
+    }
+
+  /* check if we have the drive for the volume */
+  if (G_LIKELY (hd != NULL))
+    {
+      /* update the volume with the new HAL drive/volume */
+      thunar_vfs_volume_hal_update (volume_hal, manager_hal->context, hv, hd);
+
+      /* release the drive */
+      hal_drive_free (hd);
+    }
+  else
+    {
+      /* unable to determine the drive, volume gone? */
+      thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi);
+    }
+
+  /* release the volume */
+  hal_volume_free (hv);
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_main_loop_integration (LibHalContext  *context,
+                                                     DBusConnection *dbus_connection)
+{
+  /* ok, this is easy, just add the D-BUS connection to the GLib main loop */
+  dbus_connection_setup_with_g_main (dbus_connection, NULL);
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_device_added (LibHalContext *context,
+                                            const gchar   *udi)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = hal_ctx_get_user_data (context);
+  ThunarVfsVolumeHal        *volume_hal;
+  const gchar               *drive_udi;
+  HalVolume                 *hv;
+  HalDrive                  *hd;
+  GList                      volume_list;
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  g_return_if_fail (manager_hal->context == context);
+
+  /* check if we have a volume here */
+  hv = hal_volume_from_udi (context, udi);
+  if (G_UNLIKELY (hv == NULL))
+    return;
+
+  /* we don't care for anything other than mountable filesystems */
+  if (G_UNLIKELY (hal_volume_get_fsusage (hv) != HAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM))
+    {
+      hal_volume_free (hv);
+      return;
+    }
+
+  /* determine the UDI of the drive to which this volume belongs */
+  drive_udi = hal_volume_get_storage_device_udi (hv);
+  if (G_LIKELY (drive_udi != NULL))
+    {
+      /* determine the drive for the volume */
+      hd = hal_drive_from_udi (context, drive_udi);
+      if (G_LIKELY (hd != NULL))
+        {
+          /* check if we already have a volume object for the UDI */
+          volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi);
+          if (G_LIKELY (volume_hal == NULL))
+            {
+              /* otherwise, we allocate a new volume object */
+              volume_hal = g_object_new (THUNAR_VFS_TYPE_VOLUME_HAL, NULL);
+              volume_hal->udi = g_strdup (udi);
+              volume_hal->drive_udi = g_strdup (drive_udi);
+            }
+
+          /* update the volume object with the new data from the HAL volume/drive */
+          thunar_vfs_volume_hal_update (volume_hal, context, hv, hd);
+
+          /* add the volume object to our list if we allocated a new one */
+          if (g_list_find (manager_hal->volumes, volume_hal) == NULL)
+            {
+              /* just prepend the volume object... */
+              manager_hal->volumes = g_list_prepend (manager_hal->volumes, volume_hal);
+
+              /* ...and emit "volumes-added" */
+              volume_list.data = volume_hal;
+              volume_list.next = NULL;
+              volume_list.prev = NULL;
+              thunar_vfs_volume_manager_volumes_added (THUNAR_VFS_VOLUME_MANAGER (manager_hal), &volume_list);
+            }
+
+          /* release the HAL drive */
+          hal_drive_free (hd);
+        }
+    }
+
+  /* release the HAL volume */
+  hal_volume_free (hv);
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_device_removed (LibHalContext *context,
+                                              const gchar   *udi)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = hal_ctx_get_user_data (context);
+  ThunarVfsVolumeHal        *volume_hal;
+  GList                      volume_list;
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  g_return_if_fail (manager_hal->context == context);
+
+  /* check if we already have a volume object for the UDI */
+  volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi);
+  if (G_LIKELY (volume_hal != NULL))
+    {
+      /* remove that volume from our list */
+      manager_hal->volumes = g_list_remove (manager_hal->volumes, volume_hal);
+
+      /* tell listeners that we dropped the volume */
+      volume_list.data = volume_hal;
+      volume_list.next = NULL;
+      volume_list.prev = NULL;
+      thunar_vfs_volume_manager_volumes_removed (THUNAR_VFS_VOLUME_MANAGER (manager_hal), &volume_list);
+
+      /* drop our reference on the volume */
+      g_object_unref (G_OBJECT (volume_hal));
+    }
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_device_new_capability (LibHalContext *context,
+                                                     const gchar   *udi,
+                                                     const gchar   *capability)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = hal_ctx_get_user_data (context);
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  g_return_if_fail (manager_hal->context == context);
+
+  /* update the volume for the device (if any) */
+  thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi);
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_device_lost_capability (LibHalContext *context,
+                                                      const gchar   *udi,
+                                                      const gchar   *capability)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = hal_ctx_get_user_data (context);
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  g_return_if_fail (manager_hal->context == context);
+
+  /* update the volume for the device (if any) */
+  thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi);
+}
+
+
+
+static void
+thunar_vfs_volume_manager_hal_device_property_modified (LibHalContext *context,
+                                                        const gchar   *udi,
+                                                        const gchar   *key,
+                                                        dbus_bool_t    is_removed,
+                                                        dbus_bool_t    is_added)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = hal_ctx_get_user_data (context);
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  g_return_if_fail (manager_hal->context == context);
+
+  /* update the volume for the device (if any) */
+  thunar_vfs_volume_manager_hal_update_volume_by_udi (manager_hal, udi);
+}
+
+
+
+GType
+_thunar_vfs_volume_manager_impl_get_type (void)
+{
+  return THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL;
+}
+
+
+
+
+
diff --git a/thunar-vfs/thunar-vfs-volume-hal.h b/thunar-vfs/thunar-vfs-volume-hal.h
new file mode 100644
index 000000000..658e7e54b
--- /dev/null
+++ b/thunar-vfs/thunar-vfs-volume-hal.h
@@ -0,0 +1,55 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __THUNAR_VFS_VOLUME_HAL_H__
+#define __THUNAR_VFS_VOLUME_HAL_H__
+
+#include <thunar-vfs/thunar-vfs-volume.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _ThunarVfsVolumeHalClass ThunarVfsVolumeHalClass;
+typedef struct _ThunarVfsVolumeHal      ThunarVfsVolumeHal;
+
+#define THUNAR_VFS_TYPE_VOLUME_HAL            (thunar_vfs_volume_hal_get_type ())
+#define THUNAR_VFS_VOLUME_HAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHal))
+#define THUNAR_VFS_VOLUME_HAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHalClass))
+#define THUNAR_VFS_IS_VOLUME_HAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_HAL))
+#define THUNAR_VFS_IS_VOLUME_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_HAL))
+#define THUNAR_VFS_VOLUME_HAL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_HAL, ThunarVfsVolumeHalClass))
+
+GType thunar_vfs_volume_hal_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+
+typedef struct _ThunarVfsVolumeManagerHalClass ThunarVfsVolumeManagerHalClass;
+typedef struct _ThunarVfsVolumeManagerHal      ThunarVfsVolumeManagerHal;
+
+#define THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL            (thunar_vfs_volume_manager_hal_get_type ())
+#define THUNAR_VFS_VOLUME_MANAGER_HAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHal))
+#define THUNAR_VFS_VOLUME_MANAGER_HAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHalClass))
+#define THUNAR_VFS_IS_VOLUME_MANAGER_HAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL))
+#define THUNAR_VFS_IS_VOLUME_MANAGER_HAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL))
+#define THUNAR_VFS_VOLUME_MANAGER_HAL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL, ThunarVfsVolumeManagerHalClass))
+
+GType thunar_vfs_volume_manager_hal_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__THUNAR_VFS_VOLUME_HAL_H__ */
diff --git a/thunar-vfs/thunar-vfs-volume.c b/thunar-vfs/thunar-vfs-volume.c
index 3853dc7f8..5e40efd5a 100644
--- a/thunar-vfs/thunar-vfs-volume.c
+++ b/thunar-vfs/thunar-vfs-volume.c
@@ -42,7 +42,7 @@ static void thunar_vfs_volume_base_init  (gpointer klass);
 
 
 
-static guint volume_signals[THUNAR_VFS_VOLUME_CHANGED];
+static guint volume_signals[THUNAR_VFS_VOLUME_LAST_SIGNAL];
 
 
 
@@ -202,15 +202,7 @@ thunar_vfs_volume_is_disc (ThunarVfsVolume *volume)
 
   kind = thunar_vfs_volume_get_kind (volume);
 
-  switch (kind)
-    {
-    case THUNAR_VFS_VOLUME_KIND_CDROM:
-    case THUNAR_VFS_VOLUME_KIND_DVD:
-      return TRUE;
-
-    default:
-      return FALSE;
-    }
+  return (kind >= THUNAR_VFS_VOLUME_KIND_CDROM && kind <= THUNAR_VFS_VOLUME_KIND_DVDPLUSRW);
 }
 
 
@@ -295,9 +287,17 @@ thunar_vfs_volume_is_removable (ThunarVfsVolume *volume)
   switch (kind)
     {
     case THUNAR_VFS_VOLUME_KIND_CDROM:
-    case THUNAR_VFS_VOLUME_KIND_DVD:
+    case THUNAR_VFS_VOLUME_KIND_CDR:
+    case THUNAR_VFS_VOLUME_KIND_CDRW:
+    case THUNAR_VFS_VOLUME_KIND_DVDROM:
+    case THUNAR_VFS_VOLUME_KIND_DVDRAM:
+    case THUNAR_VFS_VOLUME_KIND_DVDR:
+    case THUNAR_VFS_VOLUME_KIND_DVDRW:
+    case THUNAR_VFS_VOLUME_KIND_DVDPLUSR:
+    case THUNAR_VFS_VOLUME_KIND_DVDPLUSRW:
     case THUNAR_VFS_VOLUME_KIND_FLOPPY:
     case THUNAR_VFS_VOLUME_KIND_USBSTICK:
+    case THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER:
       return TRUE;
 
     default:
@@ -342,16 +342,52 @@ thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume,
   kind = thunar_vfs_volume_get_kind (volume);
   switch (kind)
     {
-    case THUNAR_VFS_VOLUME_KIND_DVD:
-      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-dvd"))
-        return "gnome-dev-dvd";
-      /* FALL-THROUGH */
-
+cdrom:
     case THUNAR_VFS_VOLUME_KIND_CDROM:
       if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-cdrom"))
         return "gnome-dev-cdrom";
       break;
 
+    case THUNAR_VFS_VOLUME_KIND_CDR:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdr"))
+        return "gnome-dev-disc-cdr";
+      goto cdrom;
+
+    case THUNAR_VFS_VOLUME_KIND_CDRW:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdrw"))
+        return "gnome-dev-disc-cdrw";
+      goto cdrom;
+
+dvdrom:
+    case THUNAR_VFS_VOLUME_KIND_DVDROM:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrom"))
+        return "gnome-dev-dvdrom";
+      else if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-dvd"))
+        return "gnome-dev-dvd";
+      goto cdrom;
+
+    case THUNAR_VFS_VOLUME_KIND_DVDRAM:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdram"))
+        return "gnome-dev-disc-dvdram";
+      goto dvdrom;
+
+dvdr:
+    case THUNAR_VFS_VOLUME_KIND_DVDR:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdr"))
+        return "gnome-dev-disc-dvdr";
+      goto dvdrom;
+
+    case THUNAR_VFS_VOLUME_KIND_DVDRW:
+    case THUNAR_VFS_VOLUME_KIND_DVDPLUSRW:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrw"))
+        return "gnome-dev-disc-dvdrw";
+      goto dvdrom;
+
+    case THUNAR_VFS_VOLUME_KIND_DVDPLUSR:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdr-plus"))
+        return "gnome-dev-disc-dvdr-plus";
+      goto dvdr;
+
     case THUNAR_VFS_VOLUME_KIND_FLOPPY:
       if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-floppy"))
         return "gnome-dev-floppy";
@@ -369,6 +405,11 @@ thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume,
         return "gnome-dev-harddisk-usb";
       break;
 
+    case THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-ipod"))
+        return "gnome-dev-ipod";
+      break;
+
     default:
       break;
     }
@@ -404,10 +445,33 @@ thunar_vfs_volume_eject (ThunarVfsVolume *volume,
                          GtkWidget       *window,
                          GError         **error)
 {
+  GdkCursor *cursor;
+  gboolean   result;
+
   g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE);
-  return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->eject) (volume, window, error);
+
+  /* setup a watch cursor on the window */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    {
+      /* setup the watch cursor */
+      cursor = gdk_cursor_new (GDK_WATCH);
+      gdk_window_set_cursor (window->window, cursor);
+      gdk_cursor_unref (cursor);
+
+      /* flush the changes */
+      gdk_flush ();
+    }
+
+  /* try to mount the volume */
+  result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->eject) (volume, window, error);
+
+  /* reset the cursor */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    gdk_window_set_cursor (window->window, NULL);
+
+  return result;
 }
 
 
@@ -439,10 +503,33 @@ thunar_vfs_volume_mount (ThunarVfsVolume *volume,
                          GtkWidget       *window,
                          GError         **error)
 {
+  GdkCursor *cursor;
+  gboolean   result;
+
   g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE);
-  return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->mount) (volume, window, error);
+
+  /* setup a watch cursor on the window */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    {
+      /* setup the watch cursor */
+      cursor = gdk_cursor_new (GDK_WATCH);
+      gdk_window_set_cursor (window->window, cursor);
+      gdk_cursor_unref (cursor);
+
+      /* flush the changes */
+      gdk_flush ();
+    }
+
+  /* try to mount the volume */
+  result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->mount) (volume, window, error);
+
+  /* reset the cursor */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    gdk_window_set_cursor (window->window, NULL);
+
+  return result;
 }
 
 
@@ -474,10 +561,33 @@ thunar_vfs_volume_unmount (ThunarVfsVolume *volume,
                            GtkWidget       *window,
                            GError         **error)
 {
+  GdkCursor *cursor;
+  gboolean   result;
+
   g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE);
-  return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->unmount) (volume, window, error);
+
+  /* setup a watch cursor on the window */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    {
+      /* setup the watch cursor */
+      cursor = gdk_cursor_new (GDK_WATCH);
+      gdk_window_set_cursor (window->window, cursor);
+      gdk_cursor_unref (cursor);
+
+      /* flush the changes */
+      gdk_flush ();
+    }
+
+  /* try to mount the volume */
+  result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->unmount) (volume, window, error);
+
+  /* reset the cursor */
+  if (window != NULL && GTK_WIDGET_REALIZED (window))
+    gdk_window_set_cursor (window->window, NULL);
+
+  return result;
 }
 
 
@@ -509,7 +619,7 @@ enum
 
 
 
-static void thunar_vfs_volume_manager_base_init  (gpointer klass);
+static void thunar_vfs_volume_manager_base_init (gpointer klass);
 
 
 
@@ -571,7 +681,7 @@ thunar_vfs_volume_manager_base_init (gpointer klass)
        * different condition!
        **/
       manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_ADDED] =
-        g_signal_new ("volumes-added",
+        g_signal_new (I_("volumes-added"),
                       G_TYPE_FROM_INTERFACE (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (ThunarVfsVolumeManagerIface, volumes_added),
@@ -588,7 +698,7 @@ thunar_vfs_volume_manager_base_init (gpointer klass)
        * been detached from the system.
        **/
       manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_REMOVED] =
-        g_signal_new ("volumes-removed",
+        g_signal_new (I_("volumes-removed"),
                       G_TYPE_FROM_INTERFACE (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (ThunarVfsVolumeManagerIface, volumes_removed),
diff --git a/thunar-vfs/thunar-vfs-volume.h b/thunar-vfs/thunar-vfs-volume.h
index e767a6159..8d7b02563 100644
--- a/thunar-vfs/thunar-vfs-volume.h
+++ b/thunar-vfs/thunar-vfs-volume.h
@@ -37,12 +37,20 @@ typedef struct _ThunarVfsVolume      ThunarVfsVolume;
 
 /**
  * ThunarVfsVolumeKind:
- * @THUNAR_VFS_VOLUME_KIND_UNKNOWN  : Unknown volume.
- * @THUNAR_VFS_VOLUME_KIND_CDROM    : CD drives.
- * @THUNAR_VFS_VOLUME_KIND_DVD      : DVD drives.
- * @THUNAR_VFS_VOLUME_KIND_FLOPPY   : Floppy drives.
- * @THUNAR_VFS_VOLUME_KIND_HARDDISK : Hard disk drives.
- * @THUNAR_VFS_VOLUME_KIND_USBSTICK : USB sticks.
+ * @THUNAR_VFS_VOLUME_KIND_UNKNOWN      : Unknown volume.
+ * @THUNAR_VFS_VOLUME_KIND_CDROM        : CD-ROMs.
+ * @THUNAR_VFS_VOLUME_KIND_CDR          : CD-Rs.
+ * @THUNAR_VFS_VOLUME_KIND_CDRW         : CD-RWs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDROM       : DVD-ROMs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDRAM       : DVD-RAMs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDR         : DVD-Rs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDRW        : DVD-RWs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDPLUSR     : DVD+Rs.
+ * @THUNAR_VFS_VOLUME_KIND_DVDPLUSRW    : DVD+RWs.
+ * @THUNAR_VFS_VOLUME_KIND_FLOPPY       : Floppy drives.
+ * @THUNAR_VFS_VOLUME_KIND_HARDDISK     : Hard disk drives.
+ * @THUNAR_VFS_VOLUME_KIND_USBSTICK     : USB sticks.
+ * @THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER : Portable audio players (i.e. iPod).
  *
  * Describes the type of a VFS volume.
  **/
@@ -50,10 +58,18 @@ typedef enum
 {
   THUNAR_VFS_VOLUME_KIND_UNKNOWN,
   THUNAR_VFS_VOLUME_KIND_CDROM,
-  THUNAR_VFS_VOLUME_KIND_DVD,
+  THUNAR_VFS_VOLUME_KIND_CDR,
+  THUNAR_VFS_VOLUME_KIND_CDRW,
+  THUNAR_VFS_VOLUME_KIND_DVDROM,
+  THUNAR_VFS_VOLUME_KIND_DVDRAM,
+  THUNAR_VFS_VOLUME_KIND_DVDR,
+  THUNAR_VFS_VOLUME_KIND_DVDRW,
+  THUNAR_VFS_VOLUME_KIND_DVDPLUSR,
+  THUNAR_VFS_VOLUME_KIND_DVDPLUSRW,
   THUNAR_VFS_VOLUME_KIND_FLOPPY,
   THUNAR_VFS_VOLUME_KIND_HARDDISK,
   THUNAR_VFS_VOLUME_KIND_USBSTICK,
+  THUNAR_VFS_VOLUME_KIND_AUDIO_PLAYER,
 } ThunarVfsVolumeKind;
 
 /**
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 475222e00..ef0844ebd 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -94,6 +94,8 @@ static gboolean           thunar_shortcuts_model_drag_data_delete   (GtkTreeDrag
 static void               thunar_shortcuts_model_add_shortcut       (ThunarShortcutsModel      *model,
                                                                      ThunarShortcut            *shortcut,
                                                                      GtkTreePath               *path);
+static void               thunar_shortcuts_model_remove_shortcut    (ThunarShortcutsModel      *model,
+                                                                     ThunarShortcut            *shortcut);
 static void               thunar_shortcuts_model_load               (ThunarShortcutsModel      *model);
 static void               thunar_shortcuts_model_save               (ThunarShortcutsModel      *model);
 static void               thunar_shortcuts_model_monitor            (ThunarVfsMonitor          *monitor,
@@ -108,6 +110,12 @@ static void               thunar_shortcuts_model_file_destroy       (ThunarFile
                                                                      ThunarShortcutsModel      *model);
 static void               thunar_shortcuts_model_volume_changed     (ThunarVfsVolume           *volume,
                                                                      ThunarShortcutsModel      *model);
+static void               thunar_shortcuts_model_volumes_added      (ThunarVfsVolumeManager    *volume_manager,
+                                                                     GList                     *volumes,
+                                                                     ThunarShortcutsModel      *model);
+static void               thunar_shortcuts_model_volumes_removed    (ThunarVfsVolumeManager    *volume_manager,
+                                                                     GList                     *volumes,
+                                                                     ThunarShortcutsModel      *model);
 static void               thunar_shortcut_free                      (ThunarShortcut            *shortcut,
                                                                      ThunarShortcutsModel      *model);
 
@@ -247,7 +255,11 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
   GList           *lp;
 
   model->stamp = g_random_int ();
+
+  /* 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_shortcuts_model_volumes_added), model);
+  g_signal_connect (G_OBJECT (model->volume_manager), "volumes-removed", G_CALLBACK (thunar_shortcuts_model_volumes_removed), model);
 
   /* will be used to append the shortcuts to the list */
   path = gtk_tree_path_new_from_indices (0, -1);
@@ -301,26 +313,24 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
 
           if (thunar_vfs_volume_is_present (volume))
             {
-              fpath = thunar_vfs_volume_get_mount_point (volume);
-              file = thunar_file_get_for_path (fpath, NULL);
-              if (G_LIKELY (file != NULL))
-                {
-                  /* generate the shortcut */
-                  shortcut = g_new (ThunarShortcut, 1);
-                  shortcut->type = THUNAR_SHORTCUT_REMOVABLE_MEDIA;
-                  shortcut->file = file;
-                  shortcut->name = NULL;
-                  shortcut->volume = volume;
-
-                  /* link the shortcut to the list */
-                  thunar_shortcuts_model_add_shortcut (model, shortcut, path);
-                  gtk_tree_path_next (path);
-                  continue;
-                }
-            }
+              /* generate the shortcut (w/o a file, else we might
+               * prevent the volume from being unmounted)
+               */
+              shortcut = g_new (ThunarShortcut, 1);
+              shortcut->type = THUNAR_SHORTCUT_REMOVABLE_MEDIA;
+              shortcut->file = NULL;
+              shortcut->name = NULL;
+              shortcut->volume = volume;
 
-          /* schedule the volume for later checking, there's no medium present */
-          model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume);
+              /* link the shortcut to the list */
+              thunar_shortcuts_model_add_shortcut (model, shortcut, path);
+              gtk_tree_path_next (path);
+            }
+          else
+            {
+              /* schedule the volume for later checking, there's no medium present */
+              model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume);
+            }
         }
     }
 
@@ -371,6 +381,7 @@ thunar_shortcuts_model_finalize (GObject *object)
   g_object_unref (G_OBJECT (model->monitor));
 
   /* unlink 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));
 
   (*G_OBJECT_CLASS (thunar_shortcuts_model_parent_class)->finalize) (object);
@@ -475,6 +486,7 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
 {
   ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
   ThunarShortcut       *shortcut;
+  ThunarFile           *file;
 
   g_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
   g_return_if_fail (iter->stamp == model->stamp);
@@ -498,7 +510,17 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_FILE:
       g_value_init (value, THUNAR_TYPE_FILE);
-      g_value_set_object (value, shortcut->file);
+      if (shortcut->volume != NULL && shortcut->file == NULL)
+        {
+          /* try to determine the file on-demand */
+          file = thunar_file_get_for_path (thunar_vfs_volume_get_mount_point (shortcut->volume), NULL);
+          if (G_LIKELY (file != NULL))
+            g_value_take_object (value, file);
+        }
+      else
+        {
+          g_value_set_object (value, shortcut->file);
+        }
       break;
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME:
@@ -692,6 +714,35 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
 
 
 
+static void
+thunar_shortcuts_model_remove_shortcut (ThunarShortcutsModel *model,
+                                        ThunarShortcut       *shortcut)
+{
+  GtkTreePath *path;
+  gint         index;
+
+  /* determine the index of the shortcut */
+  index = g_list_index (model->shortcuts, shortcut);
+  if (G_LIKELY (index >= 0))
+    {
+      /* unlink the shortcut from the model */
+      model->shortcuts = g_list_remove (model->shortcuts, shortcut);
+
+      /* tell everybody that we have lost a shortcut */
+      path = gtk_tree_path_new_from_indices (index, -1);
+      gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+      gtk_tree_path_free (path);
+
+      /* actually free the shortcut */
+      thunar_shortcut_free (shortcut, model);
+
+      /* the shortcuts list was changed, so write the gtk bookmarks file */
+      thunar_shortcuts_model_save (model);
+    }
+}
+
+
+
 static void
 thunar_shortcuts_model_load (ThunarShortcutsModel *model)
 {
@@ -929,15 +980,13 @@ thunar_shortcuts_model_file_destroy (ThunarFile           *file,
                                      ThunarShortcutsModel *model)
 {
   ThunarShortcut *shortcut = NULL;
-  GtkTreePath     *path;
-  GList           *lp;
-  gint             index;
+  GList          *lp;
 
   g_return_if_fail (THUNAR_IS_FILE (file));
   g_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
 
   /* lookup the shortcut matching the file */
-  for (index = 0, lp = model->shortcuts; lp != NULL; ++index, lp = lp->next)
+  for (lp = model->shortcuts; lp != NULL; lp = lp->next)
     {
       shortcut = THUNAR_SHORTCUT (lp->data);
       if (shortcut->file == file)
@@ -948,19 +997,8 @@ thunar_shortcuts_model_file_destroy (ThunarFile           *file,
   g_assert (lp != NULL);
   g_assert (THUNAR_IS_FILE (shortcut->file));
 
-  /* unlink the shortcut from the model */
-  model->shortcuts = g_list_delete_link (model->shortcuts, lp);
-
-  /* tell everybody that we have lost a shortcut */
-  path = gtk_tree_path_new_from_indices (index, -1);
-  gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
-  gtk_tree_path_free (path);
-
-  /* actually free the shortcut */
-  thunar_shortcut_free (shortcut, model);
-
-  /* the shortcuts list was changed, so write the gtk bookmarks file */
-  thunar_shortcuts_model_save (model);
+  /* drop the shortcut from the model */
+  thunar_shortcuts_model_remove_shortcut (model, shortcut);
 }
 
 
@@ -970,10 +1008,8 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume      *volume,
                                        ThunarShortcutsModel *model)
 {
   ThunarShortcut *shortcut = NULL;
-  ThunarVfsPath   *fpath;
   GtkTreePath     *path;
   GtkTreeIter      iter;
-  ThunarFile      *file;
   GList           *lp;
   gint             index;
 
@@ -987,34 +1023,29 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume      *volume,
       /* check if we need to display the volume now */
       if (thunar_vfs_volume_is_present (volume))
         {
-          fpath = thunar_vfs_volume_get_mount_point (volume);
-          file = thunar_file_get_for_path (fpath, NULL);
-          if (G_LIKELY (file != NULL))
-            {
-              /* remove the volume from the list of hidden volumes */
-              model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp);
-
-              /* find the insert position */
-              for (index = 0, lp = model->shortcuts; lp != NULL; ++index, lp = lp->next)
-                {
-                  shortcut = THUNAR_SHORTCUT (lp->data);
-                  if (shortcut->type == THUNAR_SHORTCUT_SEPARATOR
-                      || shortcut->type == THUNAR_SHORTCUT_USER_DEFINED)
-                    break;
-                }
-
-              /* allocate a new shortcut */
-              shortcut = g_new (ThunarShortcut, 1);
-              shortcut->type = THUNAR_SHORTCUT_REMOVABLE_MEDIA;
-              shortcut->file = file;
-              shortcut->name = NULL;
-              shortcut->volume = volume;
+          /* remove the volume from the list of hidden volumes */
+          model->hidden_volumes = g_list_delete_link (model->hidden_volumes, lp);
 
-              /* the volume is present now, so we have to display it */
-              path = gtk_tree_path_new_from_indices (index, -1);
-              thunar_shortcuts_model_add_shortcut (model, shortcut, path);
-              gtk_tree_path_free (path);
+          /* find the insert position */
+          for (index = 0, lp = model->shortcuts; lp != NULL; ++index, lp = lp->next)
+            {
+              shortcut = THUNAR_SHORTCUT (lp->data);
+              if (shortcut->type == THUNAR_SHORTCUT_SEPARATOR
+                  || shortcut->type == THUNAR_SHORTCUT_USER_DEFINED)
+                break;
             }
+
+          /* allocate a new shortcut */
+          shortcut = g_new (ThunarShortcut, 1);
+          shortcut->type = THUNAR_SHORTCUT_REMOVABLE_MEDIA;
+          shortcut->file = NULL;
+          shortcut->name = NULL;
+          shortcut->volume = volume;
+
+          /* the volume is present now, so we have to display it */
+          path = gtk_tree_path_new_from_indices (index, -1);
+          thunar_shortcuts_model_add_shortcut (model, shortcut, path);
+          gtk_tree_path_free (path);
         }
     }
   else
@@ -1040,29 +1071,19 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume      *volume,
           /* move the volume to the hidden list */
           model->hidden_volumes = g_list_prepend (model->hidden_volumes, volume);
 
-          /* we misuse the file_destroy handler to get rid of the volume entry */
-          thunar_shortcuts_model_file_destroy (shortcut->file, model);
+          /* remove the shortcut from the user interface */
+          thunar_shortcuts_model_remove_shortcut (model, shortcut);
 
-          /* need to reconnect to the volume, as the file_destroy removes the handler */
-          g_signal_connect (G_OBJECT (volume), "changed",
-                            G_CALLBACK (thunar_shortcuts_model_volume_changed), model);
+          /* need to reconnect to the volume, as the shortcut removal drops the handler */
+          g_signal_connect (G_OBJECT (volume), "changed", G_CALLBACK (thunar_shortcuts_model_volume_changed), model);
         }
       else
         {
-          /* we may need to update the file as the mount point may have changed */
-          fpath = thunar_vfs_volume_get_mount_point (volume);
-          file = thunar_file_get_for_path (fpath, NULL);
-          if (G_LIKELY (file != NULL))
-            {
-              /* replace the current shortcut file with the new one */
-              g_object_unref (G_OBJECT (shortcut->file));
-              shortcut->file = file;
-            }
-
-          /* tell the view that the volume has changed in some way */
+          /* generate an iterator for the path */
           iter.stamp = model->stamp;
           iter.user_data = lp;
 
+          /* tell the view that the volume has changed in some way */
           path = gtk_tree_path_new_from_indices (index, -1);
           gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
           gtk_tree_path_free (path);
@@ -1072,6 +1093,81 @@ thunar_shortcuts_model_volume_changed (ThunarVfsVolume      *volume,
 
 
 
+static void
+thunar_shortcuts_model_volumes_added (ThunarVfsVolumeManager *volume_manager,
+                                      GList                  *volumes,
+                                      ThunarShortcutsModel   *model)
+{
+  GList *lp;
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
+  g_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  g_return_if_fail (model->volume_manager == volume_manager);
+
+  /* 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, lp->data);
+
+      /* ...connect the "changed" signal handler ... */
+      g_signal_connect (G_OBJECT (lp->data), "changed", G_CALLBACK (thunar_shortcuts_model_volume_changed), model);
+
+      /* ...and let the "changed" handler place the volume where appropriate */
+      thunar_shortcuts_model_volume_changed (lp->data, model);
+    }
+}
+
+
+
+static void
+thunar_shortcuts_model_volumes_removed (ThunarVfsVolumeManager *volume_manager,
+                                        GList                  *volumes,
+                                        ThunarShortcutsModel   *model)
+{
+  GList *hp;
+  GList *lp;
+
+  g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
+  g_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  g_return_if_fail (model->volume_manager == volume_manager);
+  
+  /* process all removed volumes */
+  for (lp = volumes; lp != NULL; lp = lp->next)
+    {
+      /* disconnect the "changed" signal handler from the volume */
+      g_signal_handlers_disconnect_by_func (G_OBJECT (lp->data), thunar_shortcuts_model_volume_changed, model);
+
+      /* check if the volume is on the hidden list */
+      hp = g_list_find (model->hidden_volumes, lp->data);
+      if (G_LIKELY (hp != NULL))
+        {
+          /* 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 an active shortcut then... */
+          for (hp = model->shortcuts; hp != NULL; hp = hp->next)
+            if (THUNAR_SHORTCUT (hp->data)->volume == lp->data)
+              break;
+
+          /* something is broken if we don't have a shortcut here */
+          g_assert (hp != NULL);
+          g_assert (THUNAR_SHORTCUT (hp->data)->volume == lp->data);
+
+          /* drop the shortcut from the model */
+          thunar_shortcuts_model_remove_shortcut (model, hp->data);
+        }
+    }
+}
+
+
+
 static void
 thunar_shortcut_free (ThunarShortcut       *shortcut,
                       ThunarShortcutsModel *model)
-- 
GitLab