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

Jannis Pohlmann jannis at xfce.org
Mon May 11 03:37:08 CEST 2009


Author: jannis
Date: 2009-05-11 01:37:08 +0000 (Mon, 11 May 2009)
New Revision: 29935

Added:
   thunar/branches/migration-to-gio/thunar/thunar-exec.c
   thunar/branches/migration-to-gio/thunar/thunar-exec.h
Modified:
   thunar/branches/migration-to-gio/ChangeLog
   thunar/branches/migration-to-gio/thunar/Makefile.am
   thunar/branches/migration-to-gio/thunar/main.c
   thunar/branches/migration-to-gio/thunar/thunar-dialogs.c
   thunar/branches/migration-to-gio/thunar/thunar-dialogs.h
   thunar/branches/migration-to-gio/thunar/thunar-file.c
   thunar/branches/migration-to-gio/thunar/thunar-file.h
   thunar/branches/migration-to-gio/thunar/thunar-folder.c
   thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c
   thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h
   thunar/branches/migration-to-gio/thunar/thunar-icon-factory.c
   thunar/branches/migration-to-gio/thunar/thunar-list-model.c
   thunar/branches/migration-to-gio/thunar/thunar-location-button.c
   thunar/branches/migration-to-gio/thunar/thunar-location-dialog.c
   thunar/branches/migration-to-gio/thunar/thunar-metafile.c
   thunar/branches/migration-to-gio/thunar/thunar-metafile.h
   thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c
   thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.h
   thunar/branches/migration-to-gio/thunar/thunar-renamer-model.c
   thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.c
   thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.h
   thunar/branches/migration-to-gio/thunar/thunar-tree-model.h
   thunar/branches/migration-to-gio/thunar/thunar-window.c
Log:
	* thunar/Makefile.am, thunar/thunar-exec.{c,h}: Import thunar_exec_*()
	  functions from ThunarVFS. A part of that can probably be replaced
	  with calls to libxfce4ui.
	* thunar/thunar-dialogs.{c,h}: Rename left-out THUNAR_VFS_JOB_RESPONSE*
	  defines to THUNAR_JOB_RESPONSE*. Remove thunar-vfs.h include.
	* thunar/thunar-file.{c,h}: Remove the ThunarVfsInfo struct member of
	  ThunarFile. In all function calls, make sure that we don't crash if
	  we can't load the GFileInfo for the file. Cache the basename and
	  display name of the file in thunar_file_load(). If no GFileInfo is
	  available, try to guess them from the GFile. Use the new methods for
	  querying a GKeyFile for a GFile to determine the custom icon name,
	  if available. Cache that one, too. Remove thunar_file_get_for_info(),
	  thunar_file_get_for_path(), rewrite  thunar_file_get_for_uri(),
	  rewrite thunar_file_get_parent(), thunar_file_execute() (based on
	  thunar_exec_*() functions), thunar_file_rename() (based on
	  g_file_set_display_name()), replace/disable ThunarVfsFileType
	  references in thunar_file_get_mode_string(), return TRUE from
	  thunar_file_is_executable() for .desktop files, rewrite
	  thunar_file_is_renamable(), thunar_file_get_custom_icon(),
	  thunar_file_set_custom_icon(), thunar_file_reload(), remove
	  thunar_file_cache_lookup_path(), thunar_file_list_to_path_list(),
	  thunar_file_get_path() and thunar_file_get_mime_info(). Make
	  thunar_file_get_info() return the GFileInfo. Rewrite
	  thunarx_file_info_get_vfs_info() which for now creates a new
	  ThunarVfsInfo and returns it. Callers now have to release the
	  ThunarVfsInfo later. Add GMount member to ThunarFile.
	* thunar/thunar-folder.c: Make sure to set the job to NULL after
	  unref'ing it. Otherwise thunar_folder_get_loading() will always
	  return TRUE and the watch cursor won't disappear.
	* thunar/thunar-gio-extensions.{c,h}: Add new functions
	  g_file_query_key_file() and g_file_write_key_file(). Also add
	  g_file_get_location() which returns a path for local files and an
	  URI for the rest, and g_mount_is_same_drive() which checks whether
	  two GMounts belong to the same GDrive.
	* thunar/thunar-icon-factory.c, thunar/thunar-renamer-model.c,
	  thunar/thunar-thumbnail-generator.{c,h}: Migrate to the new
	  thunarx_file_info_get_vfs_info() function.
	* thunar/thunar-list-model.c: Make sure not to crash when trying to
	  compare two ThunarFile of which at least one has no GFileInfo.
	* thunar/thunar-metafile.{c,h}: Remove thunar-vfs.h include.
	* thunar/thunar-progress-dialog.{c,h}: Use ThunarJob instead of ExoJob
	  whenever it is appropriate. Remove thunar-vfs.h include.
	* thunar/thunar-window.c: Rewrite
	  thunar_window_current_directory_destroy() so that it simply searches
	  for the first parent directory that still exists and falls back to
	  $HOME otherwise.

Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/ChangeLog	2009-05-11 01:37:08 UTC (rev 29935)
@@ -1,3 +1,52 @@
+2009-05-11	Jannis Pohlmann <jannis at xfce.org>
+
+	* thunar/Makefile.am, thunar/thunar-exec.{c,h}: Import thunar_exec_*()
+	  functions from ThunarVFS. A part of that can probably be replaced
+	  with calls to libxfce4ui.
+	* thunar/thunar-dialogs.{c,h}: Rename left-out THUNAR_VFS_JOB_RESPONSE*
+	  defines to THUNAR_JOB_RESPONSE*. Remove thunar-vfs.h include.
+	* thunar/thunar-file.{c,h}: Remove the ThunarVfsInfo struct member of
+	  ThunarFile. In all function calls, make sure that we don't crash if
+	  we can't load the GFileInfo for the file. Cache the basename and 
+	  display name of the file in thunar_file_load(). If no GFileInfo is 
+	  available, try to guess them from the GFile. Use the new methods for
+	  querying a GKeyFile for a GFile to determine the custom icon name,
+	  if available. Cache that one, too. Remove thunar_file_get_for_info(),
+	  thunar_file_get_for_path(), rewrite  thunar_file_get_for_uri(),
+	  rewrite thunar_file_get_parent(), thunar_file_execute() (based on
+	  thunar_exec_*() functions), thunar_file_rename() (based on
+	  g_file_set_display_name()), replace/disable ThunarVfsFileType
+	  references in thunar_file_get_mode_string(), return TRUE from
+	  thunar_file_is_executable() for .desktop files, rewrite
+	  thunar_file_is_renamable(), thunar_file_get_custom_icon(),
+	  thunar_file_set_custom_icon(), thunar_file_reload(), remove
+	  thunar_file_cache_lookup_path(), thunar_file_list_to_path_list(),
+	  thunar_file_get_path() and thunar_file_get_mime_info(). Make
+	  thunar_file_get_info() return the GFileInfo. Rewrite 
+	  thunarx_file_info_get_vfs_info() which for now creates a new
+	  ThunarVfsInfo and returns it. Callers now have to release the 
+	  ThunarVfsInfo later. Add GMount member to ThunarFile.
+	* thunar/thunar-folder.c: Make sure to set the job to NULL after
+	  unref'ing it. Otherwise thunar_folder_get_loading() will always
+	  return TRUE and the watch cursor won't disappear.
+	* thunar/thunar-gio-extensions.{c,h}: Add new functions
+	  g_file_query_key_file() and g_file_write_key_file(). Also add
+	  g_file_get_location() which returns a path for local files and an
+	  URI for the rest, and g_mount_is_same_drive() which checks whether
+	  two GMounts belong to the same GDrive. 
+	* thunar/thunar-icon-factory.c, thunar/thunar-renamer-model.c,
+	  thunar/thunar-thumbnail-generator.{c,h}: Migrate to the new 
+	  thunarx_file_info_get_vfs_info() function.
+	* thunar/thunar-list-model.c: Make sure not to crash when trying to
+	  compare two ThunarFile of which at least one has no GFileInfo.
+	* thunar/thunar-metafile.{c,h}: Remove thunar-vfs.h include.
+	* thunar/thunar-progress-dialog.{c,h}: Use ThunarJob instead of ExoJob
+	  whenever it is appropriate. Remove thunar-vfs.h include.
+	* thunar/thunar-window.c: Rewrite
+	  thunar_window_current_directory_destroy() so that it simply searches
+	  for the first parent directory that still exists and falls back to
+	  $HOME otherwise.
+
 2009-05-07	Jannis Pohlmann <jannis at xfce.org>
 
 	* Makefile.am, thunar/thunar-misc-jobs.{c,h}: Add new file for

Modified: thunar/branches/migration-to-gio/thunar/Makefile.am
===================================================================
--- thunar/branches/migration-to-gio/thunar/Makefile.am	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/Makefile.am	2009-05-11 01:37:08 UTC (rev 29935)
@@ -11,6 +11,7 @@
 	-DLIBEXECDIR=\"$(libexecdir)\"					\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
 	-DTHUNAR_VERSION_API=\"$(THUNAR_VERSION_API)\"			\
+	-DSN_API_NOT_YET_FROZEN						\
 	$(PLATFORM_CPPFLAGS)
 
 bin_SCRIPTS =								\
@@ -70,6 +71,8 @@
 	thunar-emblem-chooser.h						\
 	thunar-enum-types.c						\
 	thunar-enum-types.h						\
+	thunar-exec.c							\
+	thunar-exec.h							\
 	thunar-file.c							\
 	thunar-file.h							\
 	thunar-file-monitor.c						\
@@ -217,6 +220,7 @@
 	$(GTHREAD_CFLAGS)						\
 	$(GIO_CFLAGS)							\
 	$(LIBSM_CFLAGS)							\
+	$(LIBSTARTUP_NOTIFICATION_CFLAGS)				\
 	$(PLATFORM_CFLAGS)
 
 Thunar_LDFLAGS =							\
@@ -231,6 +235,7 @@
 	$(EXO_LIBS)							\
 	$(GTHREAD_LIBS)							\
 	$(GIO_LIBS)							\
+	$(LIBSTARTUP_NOTIFICATION_LIBS)					\
 	$(LIBSM_LIBS)
 
 Thunar_DEPENDENCIES =							\

Modified: thunar/branches/migration-to-gio/thunar/main.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/main.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/main.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -33,6 +33,8 @@
 #include <gio/gdesktopappinfo.h>
 #endif
 
+#include <thunar-vfs/thunar-vfs.h>
+
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-dbus-client.h>
 #include <thunar/thunar-dbus-service.h>

Modified: thunar/branches/migration-to-gio/thunar/thunar-dialogs.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dialogs.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-dialogs.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -404,8 +404,8 @@
   gint         response;
   gint         n, m;
 
-  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_VFS_JOB_RESPONSE_CANCEL);
-  _thunar_return_val_if_fail (g_utf8_validate (question, -1, NULL), THUNAR_VFS_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (g_utf8_validate (question, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL);
 
   /* try to separate the question into primary and secondary parts */
   separator = strstr (question, ": ");
@@ -465,27 +465,27 @@
 
       switch (response)
         {
-        case THUNAR_VFS_JOB_RESPONSE_YES:
+        case THUNAR_JOB_RESPONSE_YES:
           mnemonic = _("_Yes");
           break;
 
-        case THUNAR_VFS_JOB_RESPONSE_YES_ALL:
+        case THUNAR_JOB_RESPONSE_YES_ALL:
           mnemonic = _("Yes to _all");
           break;
 
-        case THUNAR_VFS_JOB_RESPONSE_NO:
+        case THUNAR_JOB_RESPONSE_NO:
           mnemonic = _("_No");
           break;
 
-        case THUNAR_VFS_JOB_RESPONSE_NO_ALL:
+        case THUNAR_JOB_RESPONSE_NO_ALL:
           mnemonic = _("N_o to all");
           break;
 
-        case THUNAR_VFS_JOB_RESPONSE_RETRY:
+        case THUNAR_JOB_RESPONSE_RETRY:
           mnemonic = _("_Retry");
           break;
 
-        case THUNAR_VFS_JOB_RESPONSE_CANCEL:
+        case THUNAR_JOB_RESPONSE_CANCEL:
           response = GTK_RESPONSE_CANCEL;
           mnemonic = _("_Cancel");
           break;
@@ -509,7 +509,7 @@
 
   /* transform the result as required */
   if (G_UNLIKELY (response <= 0))
-    response = THUNAR_VFS_JOB_RESPONSE_CANCEL;
+    response = THUNAR_JOB_RESPONSE_CANCEL;
 
   /* cleanup */
   g_string_free (secondary, TRUE);

Modified: thunar/branches/migration-to-gio/thunar/thunar-dialogs.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dialogs.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-dialogs.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -20,7 +20,7 @@
 #ifndef __THUNAR_DIALOGS_H__
 #define __THUNAR_DIALOGS_H__
 
-#include <thunar-vfs/thunar-vfs.h>
+#include <thunar/thunar-enum-types.h>
 #include <thunar/thunar-file.h>
 
 G_BEGIN_DECLS;

Added: thunar/branches/migration-to-gio/thunar/thunar-exec.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-exec.c	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-exec.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -0,0 +1,576 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of 
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write to the Free 
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <thunar/thunar-exec.h>
+#include <thunar/thunar-private.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+#endif
+
+
+
+static void     te_string_append_quoted      (GString     *string,
+                                              const gchar *unquoted);
+static gboolean te_string_append_quoted_file (GString     *string,
+                                              GFile       *file,
+                                              GError     **error);
+static void     te_string_append_quoted_uri  (GString     *string,
+                                              GFile       *file);
+
+
+
+static void
+te_string_append_quoted (GString     *string,
+                         const gchar *unquoted)
+{
+  gchar *quoted;
+
+  quoted = g_shell_quote (unquoted);
+  g_string_append (string, quoted);
+  g_free (quoted);
+}
+
+
+
+static gboolean
+te_string_append_quoted_file (GString *string,
+                              GFile   *file,
+                              GError **error)
+{
+  gboolean success = FALSE;
+  gchar   *path;
+
+  /* append the absolute, local, quoted path to the string */
+  path = g_file_get_path (file);
+  if (G_LIKELY (path != NULL))
+    {
+      te_string_append_quoted (string, path);
+      success = TRUE;
+      g_free (path);
+    }
+
+  return success;
+}
+
+
+
+static void
+te_string_append_quoted_uri (GString *string,
+                             GFile   *file)
+{
+  gchar *uri;
+
+  /* append the quoted URI for the path */
+  uri = g_file_get_uri (file);
+  te_string_append_quoted (string, uri);
+  g_free (uri);
+}
+
+
+
+/**
+ * thunar_exec_parse:
+ * @exec      : the value of the <literal>Exec</literal> field.
+ * @file_list : the list of #GFile<!---->s.
+ * @icon      : value of the <literal>Icon</literal> field or %NULL.
+ * @name      : translated value for the <literal>Name</literal> field or %NULL.
+ * @path      : full path to the desktop file or %NULL.
+ * @terminal  : whether to execute the command in a terminal.
+ * @argc      : return location for the number of items placed into @argv.
+ * @argv      : return location for the argument vector.
+ * @error     : return location for errors or %NULL.
+ *
+ * Substitutes <literal>Exec</literal> parameter variables according
+ * to the <ulink href="http://freedesktop.org/wiki/Standards_2fdesktop_2dentry_2dspec"
+ * type="http">Desktop Entry Specification</ulink> and returns the
+ * parsed argument vector (in @argv) and the number of items placed
+ * into @argv (in @argc).
+ *
+ * The @icon, @name and @path fields are optional and may be %NULL
+ * if you don't know their values. The @icon parameter should be
+ * the value of the <literal>Icon</literal> field from the desktop
+ * file, the @name parameter should be the translated <literal>Name</literal>
+ * value, while the @path parameter should refer to the full path
+ * to the desktop file, whose <literal>Exec</literal> field is
+ * being parsed here.
+ *
+ * Return value: %TRUE on success, else %FALSE.
+ **/
+gboolean
+thunar_exec_parse (const gchar *exec,
+                   GList       *file_list,
+                   const gchar *icon,
+                   const gchar *name,
+                   const gchar *uri,
+                   gboolean     terminal,
+                   gint        *argc,
+                   gchar     ***argv,
+                   GError     **error)
+{
+  const gchar *p;
+  gboolean     result = FALSE;
+  GString     *command_line = g_string_new (NULL);
+  GList       *lp;
+
+  /* prepend terminal command if required */
+  if (G_UNLIKELY (terminal))
+    g_string_append (command_line, "exo-open --launch TerminalEmulator ");
+
+  for (p = exec; *p != '\0'; ++p)
+    {
+      if (p[0] == '%' && p[1] != '\0')
+        {
+          switch (*++p)
+            {
+            case 'f':
+              /* append the absolute local path of the first path object */
+              if (file_list != NULL && !te_string_append_quoted_file (command_line, file_list->data, error))
+                goto done;
+              break;
+
+            case 'F':
+              for (lp = file_list; lp != NULL; lp = lp->next)
+                {
+                  if (G_LIKELY (lp != file_list))
+                    g_string_append_c (command_line, ' ');
+                  if (!te_string_append_quoted_file (command_line, lp->data, error))
+                    goto done;
+                }
+              break;
+
+            case 'u':
+              if (G_LIKELY (file_list != NULL))
+                te_string_append_quoted_uri (command_line, file_list->data);
+              break;
+
+            case 'U':
+              for (lp = file_list; lp != NULL; lp = lp->next)
+                {
+                  if (G_LIKELY (lp != file_list))
+                    g_string_append_c (command_line, ' ');
+                  te_string_append_quoted_uri (command_line, lp->data);
+                }
+              break;
+
+            case 'i':
+              if (G_LIKELY (icon != NULL))
+                {
+                  g_string_append (command_line, "--icon ");
+                  te_string_append_quoted (command_line, icon);
+                }
+              break;
+
+            case 'c':
+              if (G_LIKELY (name != NULL))
+                te_string_append_quoted (command_line, name);
+              break;
+
+            case 'k':
+              if (G_LIKELY (uri != NULL))
+                te_string_append_quoted (command_line, uri);
+              break;
+
+            case '%':
+              g_string_append_c (command_line, '%');
+              break;
+            }
+        }
+      else
+        {
+          g_string_append_c (command_line, *p);
+        }
+    }
+
+  result = g_shell_parse_argv (command_line->str, argc, argv, error);
+
+done:
+  g_string_free (command_line, TRUE);
+  return result;
+}
+
+
+
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+#include <libsn/sn.h>
+
+/* the max. timeout for an application to startup */
+#define TSN_STARTUP_TIMEOUT (30 * 1000)
+
+typedef struct
+{
+  SnLauncherContext *sn_launcher;
+  guint              timeout_id;
+  guint              watch_id;
+  GPid               pid;
+} TsnStartupData;
+
+static gboolean
+tvsn_startup_timeout (gpointer data)
+{
+  TsnStartupData *startup_data = data;
+  GTimeVal        now;
+  gdouble         elapsed;
+  glong           tv_sec;
+  glong           tv_usec;
+
+  GDK_THREADS_ENTER ();
+
+  /* determine the amount of elapsed time */
+  g_get_current_time (&now);
+  sn_launcher_context_get_last_active_time (startup_data->sn_launcher, &tv_sec, &tv_usec);
+  elapsed = (((gdouble) now.tv_sec - tv_sec) * G_USEC_PER_SEC + (now.tv_usec - tv_usec)) / 1000.0;
+
+  /* check if the timeout was reached */
+  if (elapsed >= TSN_STARTUP_TIMEOUT)
+    {
+      /* abort the startup notification */
+      sn_launcher_context_complete (startup_data->sn_launcher);
+      sn_launcher_context_unref (startup_data->sn_launcher);
+      startup_data->sn_launcher = NULL;
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  /* keep the startup timeout if not elapsed */
+  return (elapsed < TSN_STARTUP_TIMEOUT);
+}
+
+static void
+tvsn_startup_timeout_destroy (gpointer data)
+{
+  TsnStartupData *startup_data = data;
+
+  _thunar_return_if_fail (startup_data->sn_launcher == NULL);
+
+  /* cancel the watch (if any) */
+  if (startup_data->watch_id != 0)
+    g_source_remove (startup_data->watch_id);
+
+  /* make sure we don't leave zombies (see bug #2983 for details) */
+  g_child_watch_add_full (G_PRIORITY_LOW, startup_data->pid,
+                          (GChildWatchFunc) g_spawn_close_pid,
+                          NULL, NULL);
+
+  /* release the startup data */
+  _thunar_slice_free (TsnStartupData, startup_data);
+}
+
+static void
+tvsn_startup_watch (GPid     pid,
+                    gint     status,
+                    gpointer data)
+{
+  TsnStartupData *startup_data = data;
+
+  _thunar_return_if_fail (startup_data->sn_launcher != NULL);
+  _thunar_return_if_fail (startup_data->watch_id != 0);
+  _thunar_return_if_fail (startup_data->pid == pid);
+
+  /* abort the startup notification (application exited) */
+  sn_launcher_context_complete (startup_data->sn_launcher);
+  sn_launcher_context_unref (startup_data->sn_launcher);
+  startup_data->sn_launcher = NULL;
+
+  /* cancel the startup notification timeout */
+  g_source_remove (startup_data->timeout_id);
+}
+
+static gint
+tvsn_get_active_workspace_number (GdkScreen *screen)
+{
+  GdkWindow *root;
+  gulong     bytes_after_ret = 0;
+  gulong     nitems_ret = 0;
+  guint     *prop_ret = NULL;
+  Atom       _NET_CURRENT_DESKTOP;
+  Atom       _WIN_WORKSPACE;
+  Atom       type_ret = None;
+  gint       format_ret;
+  gint       ws_num = 0;
+
+  gdk_error_trap_push ();
+
+  root = gdk_screen_get_root_window (screen);
+
+  /* determine the X atom values */
+  _NET_CURRENT_DESKTOP = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_NET_CURRENT_DESKTOP", False);
+  _WIN_WORKSPACE = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_WIN_WORKSPACE", False);
+
+  if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root),
+                          _NET_CURRENT_DESKTOP, 0, 32, False, XA_CARDINAL,
+                          &type_ret, &format_ret, &nitems_ret, &bytes_after_ret,
+                          (gpointer) &prop_ret) != Success)
+    {
+      if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root),
+                              _WIN_WORKSPACE, 0, 32, False, XA_CARDINAL,
+                              &type_ret, &format_ret, &nitems_ret, &bytes_after_ret,
+                              (gpointer) &prop_ret) != Success)
+        {
+          if (G_UNLIKELY (prop_ret != NULL))
+            {
+              XFree (prop_ret);
+              prop_ret = NULL;
+            }
+        }
+    }
+
+  if (G_LIKELY (prop_ret != NULL))
+    {
+      if (G_LIKELY (type_ret != None && format_ret != 0))
+        ws_num = *prop_ret;
+      XFree (prop_ret);
+    }
+
+  gdk_error_trap_pop ();
+
+  return ws_num;
+}
+#endif
+
+
+
+/**
+ * thunar_exec_on_screen:
+ * @screen            : a #GdkScreen.
+ * @working_directory : child's current working directory or %NULL to inherit parent's.
+ * @argv              : child's argument vector.
+ * @envp              : child's environment vector or %NULL to inherit parent's.
+ * @flags             : flags from #GSpawnFlags.
+ * @startup_notify    : whether to use startup notification.
+ * @icon_name         : application icon or %NULL.
+ * @error             : return location for errors or %NULL.
+ *
+ * Like gdk_spawn_on_screen(), but also supports startup notification
+ * (if Thunar was built with startup notification support).
+ *
+ * Return value: %TRUE on success, %FALSE if @error is set.
+ **/
+gboolean
+thunar_exec_on_screen (GdkScreen   *screen,
+                       const gchar *working_directory,
+                       gchar      **argv,
+                       gchar      **envp,
+                       GSpawnFlags  flags,
+                       gboolean     startup_notify,
+                       const gchar *icon_name,
+                       GError     **error)
+{
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+  SnLauncherContext *sn_launcher = NULL;
+  TsnStartupData    *startup_data;
+  SnDisplay         *sn_display = NULL;
+  gint               sn_workspace;
+#endif
+  extern gchar     **environ;
+  gboolean           succeed;
+  gchar             *display_name;
+  gchar            **cenvp = envp;
+  gint               n_cenvp, n;
+  GPid               pid;
+
+  /* setup the child environment (stripping $DESKTOP_STARTUP_ID and $DISPLAY) */
+  if (G_LIKELY (envp == NULL))
+    envp = (gchar **) environ;
+  for (n = 0; envp[n] != NULL; ++n) ;
+  cenvp = g_new0 (gchar *, n + 3);
+  for (n_cenvp = n = 0; envp[n] != NULL; ++n)
+    if (strncmp (envp[n], "DESKTOP_STARTUP_ID", 18) != 0 && strncmp (envp[n], "DISPLAY", 7) != 0)
+      cenvp[n_cenvp++] = g_strdup (envp[n]);
+
+  /* add the real display name for the screen */
+  display_name = gdk_screen_make_display_name (screen);
+  cenvp[n_cenvp++] = g_strconcat ("DISPLAY=", display_name, NULL);
+  g_free (display_name);
+
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+  /* initialize the sn launcher context */
+  if (G_LIKELY (startup_notify))
+    {
+      sn_display = sn_display_new (GDK_SCREEN_XDISPLAY (screen),
+                                   (SnDisplayErrorTrapPush) gdk_error_trap_push,
+                                   (SnDisplayErrorTrapPop) gdk_error_trap_pop);
+
+      if (G_LIKELY (sn_display != NULL))
+        {
+          sn_launcher = sn_launcher_context_new (sn_display, GDK_SCREEN_XNUMBER (screen));
+
+          if (G_LIKELY (sn_launcher != NULL && !sn_launcher_context_get_initiated (sn_launcher)))
+            {
+              /* initiate the sn launcher context */
+              sn_workspace = tvsn_get_active_workspace_number (screen);
+              sn_launcher_context_set_binary_name (sn_launcher, argv[0]);
+              sn_launcher_context_set_workspace (sn_launcher, sn_workspace);
+              sn_launcher_context_set_icon_name (sn_launcher, (icon_name != NULL) ? icon_name : "applications-other");
+              sn_launcher_context_initiate (sn_launcher, g_get_prgname (), argv[0], gtk_get_current_event_time ());
+
+              /* add the real startup id to the child environment */
+              cenvp[n_cenvp++] = g_strconcat ("DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id (sn_launcher), NULL);
+
+              /* we want to watch the child process */
+              flags |= G_SPAWN_DO_NOT_REAP_CHILD;
+            }
+        }
+    }
+#endif
+
+  /* try to spawn the new process */
+  succeed = g_spawn_async (working_directory, argv, cenvp, flags, NULL, NULL, &pid, error);
+
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+  /* handle the sn launcher context */
+  if (G_LIKELY (sn_launcher != NULL))
+    {
+      if (G_UNLIKELY (!succeed))
+        {
+          /* abort the sn sequence */
+          sn_launcher_context_complete (sn_launcher);
+          sn_launcher_context_unref (sn_launcher);
+        }
+      else
+        {
+          /* schedule a startup notification timeout */
+          startup_data = _thunar_slice_new (TsnStartupData);
+          startup_data->sn_launcher = sn_launcher;
+          startup_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, TSN_STARTUP_TIMEOUT, tvsn_startup_timeout,
+                                                         startup_data, tvsn_startup_timeout_destroy);
+          startup_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, tvsn_startup_watch, startup_data, NULL);
+          startup_data->pid = pid;
+        }
+    }
+  else if (G_LIKELY (succeed))
+    {
+      /* make sure we don't leave zombies (see bug #2983 for details) */
+      g_child_watch_add_full (G_PRIORITY_LOW, pid, (GChildWatchFunc) g_spawn_close_pid, NULL, NULL);
+
+    }
+
+  /* release the sn display */
+  if (G_LIKELY (sn_display != NULL))
+    sn_display_unref (sn_display);
+#endif
+
+  /* release the child environment */
+  g_strfreev (cenvp);
+
+  return succeed;
+}
+
+
+
+/**
+ * thunar_exec_sync:
+ * @command_fmt : the command to execute (can be a printf
+ *                format string).
+ * @error       : return location for errors or %NULL.
+ * @...         : additional parameters to fill into 
+ *                @command_fmt.
+ *
+ * Executes the given @command_fmt and returns %TRUE if the
+ * command terminated successfully. Else, the @error is set
+ * to the standard error output.
+ *
+ * Return value: %TRUE if the @command_line was executed
+ *               successfully, %FALSE if @error is set.
+ **/
+gboolean
+thunar_exec_sync (const gchar *command_fmt,
+                  GError     **error,
+                  ...)
+{
+  gboolean result;
+  va_list  args;
+  gchar   *standard_error;
+  gchar   *command_line;
+  gint     exit_status;
+
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (command_fmt != NULL, FALSE);
+
+  /* determine the command line */
+  va_start (args, error);
+  command_line = g_strdup_vprintf (command_fmt, args);
+  va_end (args);
+
+  /* try to execute the command line */
+  result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, error);
+  if (G_UNLIKELY (result))
+    {
+      /* check if the command failed */
+      if (G_UNLIKELY (exit_status != 0))
+        {
+          /* drop additional whitespace from the stderr output */
+          g_strstrip (standard_error);
+
+          /* strip all trailing dots from the stderr output */
+          while (*standard_error != '\0' && standard_error[strlen (standard_error) - 1] == '.')
+            standard_error[strlen (standard_error) - 1] = '\0';
+
+          /* generate an error from the stderr output */
+          if (G_LIKELY (*standard_error != '\0'))
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", standard_error);
+          else
+            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;
+}

Added: thunar/branches/migration-to-gio/thunar/thunar-exec.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-exec.h	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-exec.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -0,0 +1,54 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of 
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write to the Free 
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __THUNAR_VFS_EXEC_H__
+#define __THUNAR_VFS_EXEC_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS;
+
+gboolean thunar_exec_parse     (const gchar  *exec,
+                                GList        *path_list,
+                                const gchar  *icon,
+                                const gchar  *name,
+                                const gchar  *path,
+                                gboolean      terminal,
+                                gint         *argc,
+                                gchar      ***argv,
+                                GError      **error) G_GNUC_INTERNAL;
+
+gboolean thunar_exec_on_screen (GdkScreen    *screen,
+                                const gchar  *working_directory,
+                                gchar       **argv,
+                                gchar       **envp,
+                                GSpawnFlags   flags,
+                                gboolean      startup_notify,
+                                const gchar  *icon_name,
+                                GError      **error) G_GNUC_INTERNAL;
+
+gboolean thunar_exec_sync      (const gchar  *command_line,
+                                GError      **error,
+                                ...) G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__THUNAR_VFS_EXEC_H__ */

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -47,8 +47,11 @@
 
 #include <gio/gio.h>
 
+#include <thunar-vfs/thunar-vfs.h>
+
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-chooser-dialog.h>
+#include <thunar/thunar-exec.h>
 #include <thunar/thunar-file.h>
 #include <thunar/thunar-file-monitor.h>
 #include <thunar/thunar-gio-extensions.h>
@@ -323,19 +326,27 @@
     g_object_unref (G_OBJECT (metafile));
 
   /* release file info */
-  if (file->ginfo != NULL)
-    g_object_unref (file->ginfo);
+  if (file->info != NULL)
+    g_object_unref (file->info);
 
   /* release filesystem info */
   if (file->filesystem_info != NULL)
     g_object_unref (file->filesystem_info);
 
+  /* release the mount */
+  if (file->mount != NULL)
+    g_object_unref (file->mount);
+
+  /* free the custom icon name */
+  g_free (file->custom_icon_name);
+  
+  /* free display name and basename */
+  g_free (file->display_name);
+  g_free (file->basename);
+
   /* release file */
   g_object_unref (file->gfile);
 
-  /* release the file info */
-  thunar_vfs_info_unref (file->info);
-
   (*G_OBJECT_CLASS (thunar_file_parent_class)->finalize) (object);
 }
 
@@ -386,8 +397,10 @@
 static gchar*
 thunar_file_info_get_mime_type (ThunarxFileInfo *file_info)
 {
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (THUNAR_FILE (file_info)->ginfo), NULL);
-  return g_strdup (g_file_info_get_content_type (THUNAR_FILE (file_info)->ginfo));
+  if (THUNAR_FILE (file_info)->info == NULL)
+    return NULL;
+
+  return g_strdup (g_file_info_get_content_type (THUNAR_FILE (file_info)->info));
 }
 
 
@@ -396,8 +409,10 @@
 thunar_file_info_has_mime_type (ThunarxFileInfo *file_info,
                                 const gchar     *mime_type)
 {
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (THUNAR_FILE (file_info)->ginfo), FALSE);
-  return g_content_type_is_a (mime_type, g_file_info_get_content_type (THUNAR_FILE (file_info)->ginfo));
+  if (THUNAR_FILE (file_info)->info == NULL)
+    return FALSE;
+
+  return g_content_type_is_a (mime_type, g_file_info_get_content_type (THUNAR_FILE (file_info)->info));
 }
 
 
@@ -410,10 +425,27 @@
 
 
 
-static ThunarVfsInfo*
+static ThunarVfsInfo *
 thunar_file_info_get_vfs_info (ThunarxFileInfo *file_info)
 {
-  return thunar_vfs_info_ref (THUNAR_FILE (file_info)->info);
+  ThunarVfsInfo *info = NULL;
+  ThunarVfsPath *path;
+  gchar         *uri;
+
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file_info), NULL);
+
+  uri = g_file_get_uri (THUNAR_FILE (file_info)->gfile);
+  path = thunar_vfs_path_new (uri, NULL);
+
+  if (path != NULL)
+    {
+      info = thunar_vfs_info_new_for_path (path, NULL);
+      thunar_vfs_path_unref (path);
+    }
+
+  g_free (uri);
+
+  return info;
 }
 
 
@@ -604,10 +636,7 @@
 thunar_file_get (GFile   *gfile,
                  GError **error)
 {
-  ThunarVfsInfo *info;
-  ThunarVfsPath *path;
-  ThunarFile    *file;
-  gchar         *uri;
+  ThunarFile *file;
 
   _thunar_return_val_if_fail (G_IS_FILE (gfile), NULL);
 
@@ -616,29 +645,19 @@
   if (G_UNLIKELY (file != NULL))
     {
       /* take a reference for the caller */
-      g_object_ref (G_OBJECT (file));
+      g_object_ref (file);
     }
   else
     {
-      uri = g_file_get_uri (gfile);
-      path = thunar_vfs_path_new (uri, error);
-      g_free (uri);
-
-      if (G_UNLIKELY (path == NULL))
-        return NULL;
-
-      info = thunar_vfs_info_new_for_path (path, error);
-      thunar_vfs_path_unref (path);
-
-      if (G_UNLIKELY (info == NULL))
-        return NULL;
-
       /* allocate a new object */
       file = g_object_new (THUNAR_TYPE_FILE, NULL);
       file->gfile = g_object_ref (gfile);
-      file->ginfo = NULL;
+      file->info = NULL;
+      file->mount = NULL;
       file->filesystem_info = NULL;
-      file->info = info;
+      file->custom_icon_name = NULL;
+      file->display_name = NULL;
+      file->basename = NULL;
 
       thunar_file_load (file, NULL, error);
 
@@ -654,148 +673,6 @@
 
 
 /**
- * thunar_file_get_for_info:
- * @info : a #ThunarVfsInfo.
- *
- * Looks up the #ThunarFile corresponding to @info. Use
- * this function if want to specify the #ThunarVfsInfo
- * to use for a #ThunarFile instead of thunar_file_get_for_path(),
- * which would determine the #ThunarVfsInfo once again.
- *
- * The caller is responsible to call g_object_unref()
- * when done with the returned object.
- *
- * Return value: the #ThunarFile for @info.
- **/
-ThunarFile*
-thunar_file_get_for_info (ThunarVfsInfo *info)
-{
-  ThunarFile *file;
-  GFile      *gfile;
-  gchar      *uri;
-
-  _thunar_return_val_if_fail (info != NULL, NULL);
-
-  uri = thunar_vfs_path_dup_uri (info->path);
-  gfile = g_file_new_for_uri (uri);
-  g_free (uri);
-
-  /* check if we already have a cached version of that file */
-  file = thunar_file_cache_lookup (gfile);
-  if (G_UNLIKELY (file != NULL))
-    {
-      /* take a reference for the caller */
-      g_object_ref (G_OBJECT (file));
-
-      /* apply the new info */
-      if (!thunar_vfs_info_matches (file->info, info))
-        {
-          thunar_vfs_info_unref (file->info);
-
-          file->info = thunar_vfs_info_ref (info);
-
-          g_object_unref (file->gfile);
-
-          if (file->ginfo != NULL)
-            g_object_unref (file->ginfo);
-
-          if (file->filesystem_info != NULL)
-            g_object_unref (file->filesystem_info);
-
-          file->gfile = g_object_ref (gfile);
-          file->ginfo = NULL;
-          file->filesystem_info = NULL;
-
-          thunar_file_load (file, NULL, NULL);
-
-          thunar_file_changed (file);
-        }
-    }
-  else
-    {
-      /* allocate a new object */
-      file = g_object_new (THUNAR_TYPE_FILE, NULL);
-      file->info = thunar_vfs_info_ref (info);
-
-      file->gfile = g_object_ref (gfile);
-      file->ginfo = NULL;
-      file->filesystem_info = NULL;
-
-      thunar_file_load (file, NULL, NULL);
-
-      /* insert the file into the cache */
-      G_LOCK (file_cache_mutex);
-      g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
-      G_UNLOCK (file_cache_mutex);
-    }
-
-  g_object_unref (gfile);
-
-  return file;
-}
-
-
-
-/**
- * thunar_file_get_for_path:
- * @path  : a #ThunarVfsPath.
- * @error : error return location.
- *
- * Tries to query the file referred to by @path. Returns %NULL
- * if the file could not be queried and @error will point
- * to an error describing the problem, else the #ThunarFile
- * instance will be returned, which needs to freed using
- * g_object_unref() when no longer needed.
- *
- * Note that this function is not thread-safe and may only
- * be called from the main thread.
- *
- * Return value: the #ThunarFile instance or %NULL on error.
- **/
-ThunarFile*
-thunar_file_get_for_path (ThunarVfsPath *path,
-                          GError       **error)
-{
-  ThunarVfsInfo *info;
-  ThunarFile    *file;
-  GFile         *gfile;
-  gchar         *uri;
-
-  _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
-  uri = thunar_vfs_path_dup_uri (path);
-  gfile = g_file_new_for_uri (uri);
-  g_free (uri);
-
-  /* see if we have the corresponding file cached already */
-  file = thunar_file_cache_lookup (gfile);
-  g_object_unref (gfile);
-
-  if (file == NULL)
-    {
-      /* determine the file info */
-      info = thunar_vfs_info_new_for_path (path, error);
-      if (G_UNLIKELY (info == NULL))
-        return NULL;
-
-      /* allocate the new file object */
-      file = thunar_file_get_for_info (info);
-
-      /* release our reference to the info */
-      thunar_vfs_info_unref (info);
-    }
-  else
-    {
-      /* take another reference on the cached file */
-      g_object_ref (G_OBJECT (file));
-    }
-
-  return file;
-}
-
-
-
-/**
  * thunar_file_get_for_uri:
  * @uri   : an URI or an absolute filename.
  * @error : return location for errors or %NULL.
@@ -813,23 +690,16 @@
 thunar_file_get_for_uri (const gchar *uri,
                          GError     **error)
 {
-  ThunarVfsPath *path;
-  ThunarFile    *file;
+  ThunarFile *file;
+  GFile      *path;
 
   _thunar_return_val_if_fail (uri != NULL, NULL);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  /* determine the path for the URI */
-  path = thunar_vfs_path_new (uri, error);
-  if (G_UNLIKELY (path == NULL))
-    return NULL;
+  path = g_file_new_for_commandline_arg (uri);
+  file = thunar_file_get (path, error);
+  g_object_unref (path);
 
-  /* determine the file for the path */
-  file = thunar_file_get_for_path (path, error);
-
-  /* release the path */
-  thunar_vfs_path_unref (path);
-
   return file;
 }
 
@@ -854,37 +724,115 @@
                   GCancellable *cancellable,
                   GError      **error)
 {
+  GKeyFile *key_file;
+  gchar    *uri;
+
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
 
-  if (file->ginfo != NULL)
+  /* release the current file info */
+  if (file->info != NULL)
     {
-      g_object_unref (file->ginfo);
-      file->ginfo = NULL;
+      g_object_unref (file->info);
+      file->info = NULL;
     }
 
+  /* release the current filesystem info */
   if (file->filesystem_info != NULL)
     {
       g_object_unref (file->filesystem_info);
       file->filesystem_info = NULL;
     }
 
-  file->ginfo = g_file_query_info (file->gfile,
+  /* release the current mount */
+  if (file->mount != NULL)
+    {
+      g_object_unref (file->mount);
+      file->mount = NULL;
+    }
+
+  /* free the custom icon name */
+  g_free (file->custom_icon_name);
+
+  /* free display name and basename */
+  g_free (file->display_name);
+  g_free (file->basename);
+
+  /* query a new file info */
+  file->info = g_file_query_info (file->gfile,
                                    THUNAR_FILE_G_FILE_INFO_NAMESPACE,
                                    G_FILE_QUERY_INFO_NONE,
                                    cancellable,
                                    error);
 
+  /* query a new filesystem info */
   file->filesystem_info = g_file_query_filesystem_info (file->gfile,
                                                         THUNAR_FILE_G_FILE_INFO_FILESYSTEM_NAMESPACE,
                                                         cancellable,
                                                         NULL);
 
-  /* FIXME This is just temporary */
-  g_assert (file->ginfo != NULL);
+  /* try to detect the corresponding mount */
+  file->mount = g_file_find_enclosing_mount (file->gfile, cancellable, NULL);
 
-  return (file->ginfo != NULL);
+  /* determine the basename */
+  file->basename = g_file_get_basename (file->gfile);
+
+  _thunar_assert (file->basename != NULL);
+
+  /* determine the custom icon name for .desktop files */
+  if (thunar_file_is_desktop_file (file))
+    {
+      /* query a key file for the .desktop file */
+      key_file = g_file_query_key_file (file->gfile, cancellable, NULL);
+      if (key_file != NULL)
+        {
+          /* read the icon name from the .desktop file */
+          file->custom_icon_name = g_key_file_get_string (key_file, 
+                                                          G_KEY_FILE_DESKTOP_GROUP,
+                                                          G_KEY_FILE_DESKTOP_KEY_ICON,
+                                                          NULL);
+          
+          if (file->custom_icon_name != NULL && *file->custom_icon_name != '\0')
+            {
+              /* drop any suffix (e.g. '.png') from themed icons */
+              if (!g_path_is_absolute (file->custom_icon_name))
+                {
+                  gchar *p;
+                  p = strrchr (file->custom_icon_name, '.');
+                  if (p != NULL)
+                    *p = '\0';
+                }
+            }
+
+          /* free the key file */
+          g_key_file_free (key_file);
+        }
+      else
+        {
+          /* cannot parse the key file, no custom icon */
+          file->custom_icon_name = NULL;
+        }
+    }
+  else
+    {
+      /* not a .desktop file, no custom icon */
+      file->custom_icon_name = NULL;
+    }
+
+  /* determine the display name */
+  if (file->info != NULL)
+    {
+      file->display_name = g_strdup (g_file_info_get_display_name (file->info));
+    }
+  else
+    {
+      uri = g_file_get_uri (file->gfile);
+      file->display_name = g_filename_display_name (uri);
+      g_free (uri);
+    }
+
+  return (file->info != NULL);
 }
 
 /**
@@ -909,13 +857,10 @@
 {
   ThunarFile *parent = NULL;
   GFile      *parent_file;
-  gchar      *uri;
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  /* TODO Rewrite based on thunar_file_get() */
-
   parent_file = g_file_get_parent (file->gfile);
 
   if (parent_file == NULL)
@@ -924,10 +869,7 @@
       return NULL;
     }
 
-  uri = g_file_get_uri (parent_file);
-  parent = thunar_file_get_for_uri (uri, error);
-  g_free (uri);
-
+  parent = thunar_file_get (parent_file, error);
   g_object_unref (parent_file);
 
   return parent;
@@ -939,8 +881,7 @@
  * thunar_file_execute:
  * @file      : a #ThunarFile instance.
  * @screen    : a #GdkScreen.
- * @path_list : the list of #ThunarVfsPath<!---->s to supply to @file on
- *              execution.
+ * @file_list : the list of #GFile<!---->s to supply to @file on execution.
  * @error     : return location for errors or %NULL.
  *
  * Tries to execute @file on the specified @screen. If @file is executable
@@ -952,13 +893,151 @@
 gboolean
 thunar_file_execute (ThunarFile *file,
                      GdkScreen  *screen,
-                     GList      *path_list,
+                     GList      *file_list,
                      GError    **error)
 {
+  gboolean  snotify = FALSE;
+  gboolean  terminal;
+  gboolean  result = FALSE;
+  GKeyFile *key_file;
+  GError   *err = NULL;
+  GFile    *parent;
+  gchar    *icon = NULL;
+  gchar    *name;
+  gchar    *type;
+  gchar    *url;
+  gchar    *location;
+  gchar    *escaped_location;
+  gchar   **argv = NULL;
+  gchar    *exec;
+  gchar    *directory;
+
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
   _thunar_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-  return thunar_vfs_info_execute (file->info, screen, path_list, NULL, error);
+
+  location = g_file_get_location (file->gfile);
+
+  if (thunar_file_is_desktop_file (file))
+    {
+      key_file = g_file_query_key_file (file->gfile, NULL, &err);
+
+      if (key_file == NULL)
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
+                       _("Failed to parse the desktop file: %s"), err->message);
+          g_error_free (err);
+          return FALSE;
+        }
+
+      type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                    G_KEY_FILE_DESKTOP_KEY_TYPE, NULL);
+
+      if (G_LIKELY (exo_str_is_equal (type, "Application")))
+        {
+          exec = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                        G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
+          if (G_LIKELY (exec != NULL))
+            {
+              /* parse other fields */
+              name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                                   G_KEY_FILE_DESKTOP_KEY_NAME, NULL,
+                                                   NULL);
+              icon = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                            G_KEY_FILE_DESKTOP_KEY_ICON, NULL);
+              terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                                 G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL);
+              snotify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                                G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, 
+                                                NULL);
+
+              result = thunar_exec_parse (exec, file_list, icon, name, location, 
+                                          terminal, NULL, &argv, error);
+              
+              g_free (name);
+              g_free (icon);
+              g_free (exec);
+            }
+          else
+            {
+              /* TRANSLATORS: `Exec' is a field name in a .desktop file. 
+               * Don't translate it. */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, 
+                           _("No Exec field specified"));
+            }
+        }
+      else if (exo_str_is_equal (type, "Link"))
+        {
+          url = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                       G_KEY_FILE_DESKTOP_KEY_URL, NULL);
+          if (G_LIKELY (url != NULL))
+            {
+              /* pass the URL to exo-open which will fire up the appropriate viewer */
+              argv = g_new (gchar *, 3);
+              argv[0] = g_strdup ("exo-open");
+              argv[1] = url;
+              argv[2] = NULL;
+              result = TRUE;
+            }
+          else
+            {
+              /* TRANSLATORS: `URL' is a field name in a .desktop file.
+               * Don't translate it. */
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, 
+                           _("No URL field specified"));
+            }
+        }
+      else
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, 
+                       _("Invalid desktop file"));
+        }
+
+      g_free (type);
+      g_key_file_free (key_file);
+    }
+  else
+    {
+      /* fake the Exec line */
+      escaped_location = g_shell_quote (location);
+      exec = g_strconcat (escaped_location, " %F", NULL);
+      result = thunar_exec_parse (exec, file_list, NULL, NULL, NULL, FALSE, NULL, &argv,
+                                  error);
+      g_free (escaped_location);
+      g_free (exec);
+    }
+
+  if (G_LIKELY (result))
+    {
+      /* determine the working directory */
+      if (G_LIKELY (file_list != NULL))
+        {
+          /* use the directory of the first list item */
+          parent = g_file_get_parent (file_list->data);
+          directory = (parent != NULL) ? g_file_get_location (parent) : NULL;
+          g_object_unref (parent);
+        }
+      else
+        {
+          /* use the directory of the executable file */
+          parent = g_file_get_parent (file->gfile);
+          directory = (parent != NULL) ? g_file_get_location (parent) : NULL;
+          g_object_unref (parent);
+        }
+
+      /* execute the command */
+      result = thunar_exec_on_screen (screen, directory, argv, NULL, G_SPAWN_SEARCH_PATH,
+                                      snotify, icon, error);
+
+      /* release the working directory */
+      g_free (directory);
+    }
+
+  /* clean up */
+  g_strfreev (argv);
+  g_free (location);
+
+  return result;
 }
 
 
@@ -1061,7 +1140,7 @@
  * @error : return location for errors or %NULL.
  *
  * Tries to rename @file to the new @name. If @file cannot be renamed,
- * %FALSE will be returned and @error will be accordingly. Else, if
+ * %FALSE will be returned and @error will be set accordingly. Else, if
  * the operation succeeds, %TRUE will be returned, and @file will have
  * a new URI and a new display name.
  *
@@ -1076,21 +1155,23 @@
                     const gchar *name,
                     GError     **error)
 {
-  GFile   *previous_file;
-  gboolean succeed;
-  gint     watch_count;;
+  GFile *previous_file;
+  GFile *renamed_file;
+  gint   watch_count;
 
-  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (g_utf8_validate (name, -1, NULL), FALSE);
-  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
   /* remember the previous file */
-  previous_file = g_object_ref (file->gfile);
+  previous_file = file->gfile;
   
   /* try to rename the file */
-  succeed = thunar_vfs_info_rename (file->info, name, error);
-  if (G_LIKELY (succeed))
+  /* TODO Make this asynchronous */
+  renamed_file = g_file_set_display_name (file->gfile, name, NULL, error);
+
+  /* check if we succeeded */
+  if (renamed_file != NULL)
     {
+      /* set the new file */
+      file->gfile = renamed_file;
+
       /* need to re-register the monitor handle for the new uri */
       watch_count = THUNAR_FILE_GET_WATCH_COUNT (file);
       if (G_LIKELY (watch_count > 0))
@@ -1113,6 +1194,9 @@
       /* drop the previous entry from the cache */
       g_hash_table_remove (file_cache, previous_file);
 
+      /* drop the reference on the previous file */
+      g_object_unref (previous_file);
+
       /* insert the new entry */
       g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
 
@@ -1123,12 +1207,13 @@
 
       /* emit the file changed signal */
       thunar_file_changed (file);
+      
+      return TRUE;
     }
-
-  /* drop the reference on the previous file */
-  g_object_unref (previous_file);
-
-  return succeed;
+  else
+    {
+      return FALSE;
+    }
 }
 
 
@@ -1234,8 +1319,10 @@
                * are on the same disk, and the source file is owned by the current user.
                */
               if (ofile == NULL 
-                  || (ofile->info->device != file->info->device) 
-                  || (ofile->info->uid != effective_user_id))
+                  || (!g_mount_is_same_drive (ofile->mount, file->mount))
+                  || (ofile->info != NULL 
+                      && g_file_info_get_attribute_uint32 (ofile->info, 
+                                                           G_FILE_ATTRIBUTE_UNIX_UID) != effective_user_id))
                 {
                   /* default to copy and get outa here */
                   suggested_action = GDK_ACTION_COPY;
@@ -1291,8 +1378,10 @@
 {
   const gchar *attribute;
 
-  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0);
+
+  if (file->info == NULL)
+    return 0;
   
   switch (date_type)
     {
@@ -1309,7 +1398,7 @@
       _thunar_assert_not_reached ();
     }
 
-  return g_file_info_get_attribute_uint64 (file->ginfo, attribute);
+  return g_file_info_get_attribute_uint64 (file->info, attribute);
 }
 
 
@@ -1349,9 +1438,9 @@
 gchar*
 thunar_file_get_mode_string (const ThunarFile *file)
 {
-  ThunarVfsFileType kind;
-  ThunarFileMode    mode;
-  gchar            *text;
+  ThunarFileMode mode;
+  GFileType      kind;
+  gchar         *text;
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
@@ -1362,17 +1451,23 @@
   /* file type */
   switch (kind)
     {
+#if 0 /* TODO */
     case THUNAR_VFS_FILE_TYPE_PORT:       text[0] = 'P'; break;
     case THUNAR_VFS_FILE_TYPE_DOOR:       text[0] = 'D'; break;
     case THUNAR_VFS_FILE_TYPE_SOCKET:     text[0] = 's'; break;
-    case THUNAR_VFS_FILE_TYPE_SYMLINK:    text[0] = 'l'; break;
-    case THUNAR_VFS_FILE_TYPE_REGULAR:    text[0] = '-'; break;
+#endif
+    case G_FILE_TYPE_SYMBOLIC_LINK:       text[0] = 'l'; break;
+    case G_FILE_TYPE_REGULAR:             text[0] = '-'; break;
+#if 0 /* TODO */
     case THUNAR_VFS_FILE_TYPE_BLOCKDEV:   text[0] = 'b'; break;
-    case THUNAR_VFS_FILE_TYPE_DIRECTORY:  text[0] = 'd'; break;
+#endif 
+    case G_FILE_TYPE_DIRECTORY:           text[0] = 'd'; break;
+#if 0 /* TODO */
     case THUNAR_VFS_FILE_TYPE_CHARDEV:    text[0] = 'c'; break;
     case THUNAR_VFS_FILE_TYPE_FIFO:       text[0] = 'f'; break;
-    case THUNAR_VFS_FILE_TYPE_UNKNOWN:    text[0] = ' '; break;
-    default:                              _thunar_assert_not_reached ();
+#endif
+    case G_FILE_TYPE_UNKNOWN:
+    default:                              text[0] = ' '; break;
     }
 
   /* permission flags */
@@ -1465,7 +1560,7 @@
  *
  * Return value: the #ThunarGroup for @file or %NULL.
  **/
-ThunarGroup*
+ThunarGroup *
 thunar_file_get_group (const ThunarFile *file)
 {
   guint32 gid;
@@ -1473,7 +1568,7 @@
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
   /* TODO what are we going to do on non-UNIX systems? */
-  gid = g_file_info_get_attribute_uint32 (file->ginfo,
+  gid = g_file_info_get_attribute_uint32 (file->info,
                                           G_FILE_ATTRIBUTE_UNIX_GID);
 
   return thunar_user_manager_get_group_by_id (user_manager, gid);
@@ -1498,10 +1593,11 @@
 thunar_file_get_user (const ThunarFile *file)
 {
   guint32 uid;
+
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
   /* TODO what are we going to do on non-UNIX systems? */
-  uid = g_file_info_get_attribute_uint32 (file->ginfo,
+  uid = g_file_info_get_attribute_uint32 (file->info,
                                           G_FILE_ATTRIBUTE_UNIX_UID);
 
   return thunar_user_manager_get_user_by_id (user_manager, uid);
@@ -1521,8 +1617,11 @@
 thunar_file_get_content_type (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), NULL);
-  return g_file_info_get_content_type (file->ginfo);
+
+  if (file->info == NULL)
+    return NULL;
+
+  return g_file_info_get_content_type (file->info);
 }
 
 
@@ -1540,8 +1639,11 @@
 thunar_file_get_symlink_target (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), NULL);
-  return g_file_info_get_symlink_target (file->ginfo);
+
+  if (file->info == NULL)
+    return NULL;
+
+  return g_file_info_get_symlink_target (file->info);
 }
 
 
@@ -1558,8 +1660,7 @@
 thunar_file_get_basename (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), NULL);
-  return g_file_info_get_name (file->ginfo);
+  return file->basename;
 }
 
 
@@ -1576,8 +1677,11 @@
 thunar_file_is_symlink (const ThunarFile *file) 
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_is_symlink (file->ginfo);
+
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_file_info_get_is_symlink (file->info);
 }
 
 
@@ -1595,8 +1699,11 @@
 thunar_file_get_size (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), 0);
-  return g_file_info_get_size (file->ginfo);
+
+  if (file->info == NULL)
+    return 0;
+
+  return g_file_info_get_size (file->info);
 }
 
 
@@ -1633,8 +1740,11 @@
 thunar_file_get_kind (const ThunarFile *file) 
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), G_FILE_TYPE_UNKNOWN);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), G_FILE_TYPE_UNKNOWN);
-  return g_file_info_get_file_type (file->ginfo);
+
+  if (file->info == NULL)
+    return G_FILE_TYPE_UNKNOWN;
+
+  return g_file_info_get_file_type (file->info);
 }
 
 
@@ -1651,8 +1761,11 @@
 thunar_file_get_mode (const ThunarFile *file) 
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), 0);
-  return g_file_info_get_attribute_uint32 (file->ginfo, G_FILE_ATTRIBUTE_UNIX_MODE);
+
+  if (file->info == NULL)
+    return 0;
+
+  return g_file_info_get_attribute_uint32 (file->info, G_FILE_ATTRIBUTE_UNIX_MODE);
 }
 
 
@@ -1700,7 +1813,10 @@
 thunar_file_is_directory (const ThunarFile *file) 
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
+
+  if (file->info == NULL)
+    return FALSE;
+
   return thunar_file_get_kind (file) == G_FILE_TYPE_DIRECTORY;
 }
 
@@ -1768,17 +1884,25 @@
  *
  * Determines whether the owner of the current process is allowed
  * to execute the @file (or enter the directory refered to by
- * @file).
+ * @file). On UNIX it also returns %TRUE if @file refers to a 
+ * desktop entry.
  *
  * Return value: %TRUE if @file can be executed.
  **/
 gboolean
 thunar_file_is_executable (const ThunarFile *file)
 {
+  gboolean can_execute;
+
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_attribute_boolean (file->ginfo, 
-                                            G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
+
+  if (file->info == NULL)
+    return FALSE;
+  
+  can_execute = g_file_info_get_attribute_boolean (file->info, 
+                                                   G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
+
+  return can_execute || thunar_file_is_desktop_file (file);
 }
 
 
@@ -1796,8 +1920,11 @@
 thunar_file_is_readable (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_attribute_boolean (file->ginfo, 
+
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_file_info_get_attribute_boolean (file->info, 
                                             G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
 }
 
@@ -1816,8 +1943,11 @@
 thunar_file_is_writable (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_attribute_boolean (file->ginfo, 
+  
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_file_info_get_attribute_boolean (file->info, 
                                             G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
 }
 
@@ -1835,8 +1965,11 @@
 thunar_file_is_hidden (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_is_hidden (file->ginfo);
+  
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_file_info_get_is_hidden (file->info);
 }
 
 
@@ -1914,9 +2047,11 @@
 thunar_file_is_desktop_file (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
 
-  return g_content_type_equals (g_file_info_get_content_type (file->ginfo), "application/x-desktop")
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_content_type_equals (g_file_info_get_content_type (file->info), "application/x-desktop")
          && !g_str_has_suffix (thunar_file_get_basename (file), ".directory");
 }
 
@@ -1935,8 +2070,7 @@
 thunar_file_get_display_name (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_display_name (file->ginfo);
+  return file->display_name;
 }
 
 
@@ -1964,9 +2098,9 @@
   time_t       time;
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), NULL);
+  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->info), NULL);
 
-  date = g_file_info_get_attribute_string (file->ginfo, "trash::deletion-date");
+  date = g_file_info_get_attribute_string (file->info, "trash::deletion-date");
   if (G_UNLIKELY (date == NULL))
     return NULL;
 
@@ -1994,8 +2128,8 @@
 thunar_file_get_original_path (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), NULL);
-  return g_file_info_get_attribute_string (file->ginfo, "trash::orig-file");
+  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->info), NULL);
+  return g_file_info_get_attribute_string (file->info, "trash::orig-file");
 }
 
 
@@ -2020,7 +2154,17 @@
    *   b) the super-user id
    * and the file is not in the trash.
    */
-  return ((effective_user_id == 0 || effective_user_id == file->info->uid) && !thunar_file_is_trashed (file));
+  if (file->info == NULL)
+    {
+      return (effective_user_id == 0 && !thunar_file_is_trashed (file));
+    }
+  else
+    {
+      return ((effective_user_id == 0 
+               || effective_user_id == g_file_info_get_attribute_uint32 (file->info,
+                                                                         G_FILE_ATTRIBUTE_UNIX_UID))
+              && !thunar_file_is_trashed (file));
+    }
 }
 
 
@@ -2039,23 +2183,13 @@
 gboolean
 thunar_file_is_renameable (const ThunarFile *file)
 {
-  gboolean renameable = FALSE;
-
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
+  
+  if (file->info == NULL)
+    return FALSE;
 
-  /* we cannot the node node or trashed files */
-  if (!thunar_file_is_root (file) && !thunar_file_is_trashed (file))
-    {
-      /* we just do a guess here, by checking whether the folder is writable */
-      file = thunar_file_get_parent (file, NULL);
-      if (G_LIKELY (file != NULL))
-        {
-          renameable = thunar_file_is_writable (file);
-          g_object_unref (G_OBJECT (file));
-        }
-    }
-
-  return renameable;
+  return g_file_info_get_attribute_boolean (file->info,
+                                            G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME);
 }
 
 
@@ -2064,8 +2198,11 @@
 thunar_file_can_be_trashed (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
-  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
-  return g_file_info_get_attribute_boolean (file->ginfo, 
+
+  if (file->info == NULL)
+    return FALSE;
+
+  return g_file_info_get_attribute_boolean (file->info, 
                                             G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH);
 }
 
@@ -2118,12 +2255,14 @@
         emblems = g_list_append (emblems, *emblem_names);
     }
 
-  if (g_file_info_get_is_symlink (file->ginfo))
+  if (thunar_file_is_symlink (file))
     emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_SYMBOLIC_LINK);
 
   /* determine the user ID of the file owner */
   /* TODO what are we going to do here on non-UNIX systems? */
-  uid = g_file_info_get_attribute_uint32 (file->ginfo, G_FILE_ATTRIBUTE_UNIX_UID);
+  uid = file->info != NULL 
+        ? g_file_info_get_attribute_uint32 (file->info, G_FILE_ATTRIBUTE_UNIX_UID) 
+        : 0;
 
   /* we add "cant-read" if either (a) the file is not readable or (b) a directory, that lacks the
    * x-bit, see http://bugzilla.xfce.org/show_bug.cgi?id=1408 for the details about this change.
@@ -2207,7 +2346,9 @@
  * @custom_icon : the new custom icon for the @file.
  * @error       : return location for errors or %NULL.
  *
- * Wrapper for _thunar_vfs_info_set_custom_icon().
+ * Tries to change the custom icon of the .desktop file referred
+ * to by @file. If that fails, %FALSE is returned and the
+ * @error is set accordingly.
  *
  * Return value: %TRUE if the icon of @file was changed, %FALSE otherwise.
  **/
@@ -2216,17 +2357,33 @@
                              const gchar *custom_icon,
                              GError     **error)
 {
+  GKeyFile *key_file;
+
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
   _thunar_return_val_if_fail (custom_icon != NULL, FALSE);
 
-  /* try to set the new custom_icon for the file */
-  if (!thunar_vfs_info_set_custom_icon (file->info, custom_icon, error))
+  key_file = g_file_query_key_file (file->gfile, NULL, error);
+
+  if (key_file == NULL)
     return FALSE;
 
-  /* tell everybody that we have changed */
-  thunar_file_changed (file);
-  return TRUE;
+  g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                         G_KEY_FILE_DESKTOP_KEY_ICON, custom_icon);
+
+  if (g_file_write_key_file (file->gfile, key_file, NULL, error))
+    {
+      /* tell everybody that we have changed */
+      thunar_file_changed (file);
+
+      g_key_file_free (key_file);
+      return TRUE;
+    }
+  else
+    {
+      g_key_file_free (key_file);
+      return FALSE;
+    }
 }
 
 
@@ -2252,7 +2409,27 @@
 }
 
 
+
 /**
+ * thunar_file_get_custom_icon:
+ * @file : a #ThunarFile instance.
+ *
+ * Queries the custom icon from @file if any, else %NULL is returned. 
+ * The custom icon can be either a themed icon name or an absolute path
+ * to an icon file in the local file system.
+ *
+ * Return value: the custom icon for @file or %NULL.
+ **/
+gchar *
+thunar_file_get_custom_icon (const ThunarFile *file)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
+  return g_strdup (file->custom_icon_name);
+}
+
+
+
+/**
  * thunar_file_get_icon_name:
  * @file       : a #ThunarFile instance.
  * @icon_state : the state of the @file<!---->s icon we are interested in.
@@ -2264,7 +2441,7 @@
  *
  * Return value: the icon name for @file in @icon_theme.
  **/
-gchar*
+gchar *
 thunar_file_get_icon_name (const ThunarFile   *file,
                            ThunarFileIconState icon_state,
                            GtkIconTheme       *icon_theme)
@@ -2277,8 +2454,11 @@
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
   _thunar_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
 
-  icon = g_file_info_get_icon (file->ginfo);
+  if (file->info == NULL)
+    return NULL;
 
+  icon = g_file_info_get_icon (file->info);
+
   if (icon != NULL && G_IS_THEMED_ICON (icon))
     {
       g_object_get (icon, "names", &themed_icon_names, NULL);
@@ -2486,38 +2666,19 @@
 void
 thunar_file_reload (ThunarFile *file)
 {
-  ThunarVfsInfo *info;
-
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
 
-  /* re-query the file info */
-  info = thunar_vfs_info_new_for_path (file->info->path, NULL);
-  if (G_UNLIKELY (info == NULL))
+  if (!g_file_query_exists (file->gfile, NULL))
     {
       /* the file is no longer present */
       thunar_file_destroy (file);
     }
   else
     {
-      /* apply the new info... */
-      thunar_vfs_info_unref (file->info);
-      file->info = info;
-
-      if (file->ginfo != NULL)
-        {
-          g_object_unref (file->ginfo);
-          file->ginfo = NULL;
-        }
-
-      if (file->filesystem_info != NULL)
-        {
-          g_object_unref (file->filesystem_info);
-          file->filesystem_info = NULL;
-        }
-
       thunar_file_load (file, NULL, NULL);
 
-      if (file->ginfo == NULL)
+      /* destroy the file if we cannot query any file information */
+      if (file->info == NULL)
         {
           thunar_file_destroy (file);
           return;
@@ -2791,42 +2952,6 @@
 
 
 /**
- * thunar_file_cache_lookup_path:
- * @path : a #ThunarVfsPath.
- *
- * Looks up the #ThunarFile for @path in the internal file
- * cache and returns the file present for @path in the
- * cache or %NULL if no #ThunarFile is cached for @path.
- *
- * Note that no reference is taken for the caller.
- *
- * This method should not be used but in very rare cases.
- * Consider using thunar_file_get() instead.
- *
- * Return value: the #ThunarFile for @path in the internal
- *               cache, or %NULL.
- **/
-ThunarFile *
-thunar_file_cache_lookup_path (const ThunarVfsPath *path)
-{
-  ThunarFile *file;
-  GFile      *gfile;
-  gchar      *uri;
-
-  _thunar_return_val_if_fail (path != NULL, NULL);
-
-  uri = thunar_vfs_path_dup_uri (path);
-  gfile = g_file_new_for_uri (uri);
-  file = thunar_file_cache_lookup (gfile);
-  g_object_unref (gfile);
-  g_free (uri);
-
-  return file;
-}
-
-
-
-/**
  * thunar_file_list_get_applications:
  * @file_list : a #GList of #ThunarFile<!---->s.
  *
@@ -2856,12 +2981,12 @@
   /* determine the set of applications that can open all files */
   for (lp = file_list; lp != NULL; lp = lp->next)
     {
-      current_type = g_file_info_get_content_type (THUNAR_FILE (lp->data)->ginfo);
+      current_type = thunar_file_get_content_type (lp->data);
 
       /* no need to check anything if this file has the same mime type as the previous file */
       if (lp->prev != NULL)
         {
-          previous_type = g_file_info_get_content_type (THUNAR_FILE (lp->prev->data)->ginfo);
+          previous_type = thunar_file_get_content_type (lp->prev->data);
           if (G_LIKELY (g_content_type_equals (previous_type, current_type)))
             continue;
         }
@@ -2930,32 +3055,3 @@
 
   return list;
 }
-
-
-
-/**
- * thunar_file_list_to_path_list:
- * @file_list : a #GList of #ThunarFile<!---->s.
- *
- * Transforms the @file_list to a #GList of #ThunarVfsPath<!---->s for
- * the #ThunarFile<!---->s contained within @file_list.
- *
- * The caller is responsible to free the returned list using
- * thunar_vfs_path_list_free() when no longer needed.
- *
- * Return value: the list of #ThunarVfsPath<!---->s for @file_list.
- **/
-GList*
-thunar_file_list_to_path_list (GList *file_list)
-{
-  GList *path_list = NULL;
-  GList *lp;
-
-  for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev)
-    path_list = g_list_prepend (path_list, thunar_vfs_path_ref (THUNAR_FILE (lp->data)->info->path));
-
-  return path_list;
-}
-
-
-

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -21,14 +21,17 @@
 #ifndef __THUNAR_FILE_H__
 #define __THUNAR_FILE_H__
 
+#include <glib.h>
+
+#include <thunar-vfs/thunar-vfs.h>
+
+#include <thunarx/thunarx.h>
+
 #include <thunar/thunar-enum-types.h>
 #include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-metafile.h>
 #include <thunar/thunar-user.h>
-#include <thunarx/thunarx.h>
 
-#include <glib.h>
-
 G_BEGIN_DECLS;
 
 typedef struct _ThunarFileClass ThunarFileClass;
@@ -111,11 +114,14 @@
   GObject        __parent__;
 
   /*< private >*/
-  ThunarVfsInfo *info;
-  GFileInfo     *ginfo;
-  GFileInfo     *filesystem_info;
   GFileMonitor  *monitor;
+  GFileInfo     *info;
+  GFileInfo     *filesystem_info;
+  GMount        *mount;
   GFile         *gfile;
+  gchar         *custom_icon_name;
+  gchar         *display_name;
+  gchar         *basename;
   guint          flags;
 };
 
@@ -123,9 +129,6 @@
 
 ThunarFile       *thunar_file_get                  (GFile                  *file,
                                                     GError                **error);
-ThunarFile       *thunar_file_get_for_info         (ThunarVfsInfo          *info);
-ThunarFile       *thunar_file_get_for_path         (ThunarVfsPath          *path,
-                                                    GError                **error);
 ThunarFile       *thunar_file_get_for_uri          (const gchar            *uri,
                                                     GError                **error);
 
@@ -206,9 +209,10 @@
 void              thunar_file_set_emblem_names     (ThunarFile              *file,
                                                     GList                   *emblem_names);
 
+gchar            *thunar_file_get_custom_icon      (const ThunarFile        *file);
 gboolean          thunar_file_set_custom_icon      (ThunarFile              *file,
                                                     const gchar             *custom_icon,
-                                                    GError                 **error) G_GNUC_WARN_UNUSED_RESULT;
+                                                    GError                 **error);
 
 gchar            *thunar_file_get_icon_name        (const ThunarFile        *file,
                                                     ThunarFileIconState     icon_state,
@@ -234,14 +238,11 @@
                                                     const ThunarFile       *file_b,
                                                     gboolean                case_sensitive);
 
-
 ThunarFile       *thunar_file_cache_lookup         (const GFile            *file);
-ThunarFile       *thunar_file_cache_lookup_path    (const ThunarVfsPath    *path);
 
 
 GList            *thunar_file_list_get_applications  (GList *file_list);
 GList            *thunar_file_list_to_g_file_list    (GList *file_list);
-GList            *thunar_file_list_to_path_list      (GList *file_list);
 
 gboolean         thunar_file_is_desktop              (const ThunarFile *file);
 
@@ -270,33 +271,18 @@
  * thunar_file_get_info:
  * @file : a #ThunarFile instance.
  *
- * Returns the #ThunarVfsInfo for @file.
+ * Returns the #GFileInfo for @file.
  *
  * Note, that there's no reference taken for the caller on the
- * returned #ThunarVfsInfo, so if you need the object for a longer
+ * returned #GFileInfo, so if you need the object for a longer
  * perioud, you'll need to take a reference yourself using the
- * thunar_vfs_info_ref() method.
+ * g_object_ref() method.
  *
- * Return value: the #ThunarVfsInfo for @file.
+ * Return value: the #GFileInfo for @file.
  **/
 #define thunar_file_get_info(file) (THUNAR_FILE ((file))->info)
 
 /**
- * thunar_file_get_path:
- * @file  : a #ThunarFile instance.
- *
- * Returns the #ThunarVfsPath, that refers to the location of the @file.
- *
- * Note, that there's no reference taken for the caller on the
- * returned #ThunarVfsPath, so if you need the object for a longer
- * period, you'll need to take a reference yourself using the
- * thunar_vfs_path_ref() function.
- *
- * Return value: the path to the @file.
- **/
-#define thunar_file_get_path(file) (THUNAR_FILE ((file))->info->path)
-
-/**
  * thunar_file_get_file:
  * @file : a #ThunarFile instance.
  *
@@ -310,22 +296,6 @@
 #define thunar_file_get_file(file) (THUNAR_FILE ((file))->gfile)
 
 /**
- * thunar_file_get_mime_info:
- * @file : a #ThunarFile instance.
- *
- * Returns the MIME type information for the given @file object. This
- * function is garantied to always return a valid #ThunarVfsMimeInfo.
- *
- * Note, that there's no reference taken for the caller on the
- * returned #ThunarVfsMimeInfo, so if you need the object for a
- * longer period, you'll need to take a reference yourself using
- * the thunar_vfs_mime_info_ref() function.
- *
- * Return value: the MIME type.
- **/
-#define thunar_file_get_mime_info(file) (THUNAR_FILE ((file))->info->mime_info)
-
-/**
  * thunar_file_dup_uri:
  * @file : a #ThunarFile instance.
  *
@@ -337,21 +307,6 @@
 #define thunar_file_dup_uri(file) (g_file_get_uri (THUNAR_FILE ((file))->gfile))
 
 /**
- * thunar_file_get_custom_icon:
- * @file : a #ThunarFile instance.
- *
- * Queries the custom icon from @file if any,
- * else %NULL is returned. The custom icon
- * can be either a themed icon name or an
- * absolute path to an icon file in the local
- * file system.
- *
- * Return value: the custom icon for @file
- *               or %NULL.
- **/
-#define thunar_file_get_custom_icon(file) (g_strdup (thunar_vfs_info_get_custom_icon (THUNAR_FILE ((file))->info)))
-
-/**
  * thunar_file_changed:
  * @file : a #ThunarFile instance.
  *

Modified: thunar/branches/migration-to-gio/thunar/thunar-folder.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-folder.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-folder.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -100,7 +100,7 @@
 {
   GtkObject __parent__;
 
-  ThunarJob            *job;
+  ThunarJob         *job;
 
   ThunarFile        *corresponding_file;
   GList             *new_files;
@@ -275,8 +275,8 @@
   if (G_UNLIKELY (folder->job != NULL))
     {
       g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-      exo_job_cancel (EXO_JOB (folder->job));
       g_object_unref (folder->job);
+      folder->job = NULL;
     }
 
   /* disconnect from the corresponding file */
@@ -357,7 +357,6 @@
 {
   _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (folder->job == THUNAR_JOB (job));
 
   /* tell the consumer about the problem */
   g_signal_emit (G_OBJECT (folder), folder_signals[ERROR], 0, error);
@@ -373,7 +372,6 @@
   _thunar_return_val_if_fail (THUNAR_IS_FOLDER (folder), FALSE);
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (folder->monitor == NULL, FALSE);
-  _thunar_return_val_if_fail (folder->job == THUNAR_JOB (job), FALSE);
 
   /* merge the list with the existing list of new files */
   folder->new_files = g_list_concat (folder->new_files, files);
@@ -396,7 +394,6 @@
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file));
   _thunar_return_if_fail (folder->monitor == NULL);
-  _thunar_return_if_fail (folder->job == THUNAR_JOB (job));
 
   /* check if we need to merge new files with existing files */
   if (G_UNLIKELY (folder->files != NULL))
@@ -469,7 +466,7 @@
 
   /* we did it, the folder is loaded */
   g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-  g_object_unref (G_OBJECT (folder->job));
+  g_object_unref (folder->job);
   folder->job = NULL;
 
   /* add us to the file alteration monitor */
@@ -729,8 +726,8 @@
     {
       /* disconnect from the job */
       g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-      exo_job_cancel (EXO_JOB (folder->job));
       g_object_unref (folder->job);
+      folder->job = NULL;
     }
 
   /* disconnect from the file alteration monitor */

Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -123,7 +123,96 @@
 
 
 
+GKeyFile *
+g_file_query_key_file (GFile              *file,
+                       GCancellable       *cancellable,
+                       GError            **error)
+{
+  GKeyFile *key_file;
+  gchar    *contents = NULL;
+  gsize     length;
+
+  _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
+  _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  /* try to load the entire file into memory */
+  if (!g_file_load_contents (file, cancellable, &contents, &length, NULL, error))
+    return NULL;
+
+  /* allocate a new key file */
+  key_file = g_key_file_new ();
+
+  /* try to parse the key file from the contents of the file */
+  if (!g_key_file_load_from_data (key_file, contents, length, 
+                                  G_KEY_FILE_KEEP_COMMENTS 
+                                  | G_KEY_FILE_KEEP_TRANSLATIONS,
+                                  error))
+    {
+      g_free (contents);
+      g_key_file_free (key_file);
+      return NULL;
+    }
+  else
+    {
+      g_free (contents);
+      return key_file;
+    }
+}
+
+
+
+gboolean
+g_file_write_key_file (GFile        *file,
+                       GKeyFile     *key_file,
+                       GCancellable *cancellable,
+                       GError      **error)
+{
+  gchar *contents;
+  gsize  length;
+
+  _thunar_return_val_if_fail (G_IS_FILE (file), FALSE);
+  _thunar_return_val_if_fail (key_file != NULL, FALSE);
+  _thunar_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* write the key file into the contents buffer */
+  contents = g_key_file_to_data (key_file, &length, NULL);
+
+  /* try to replace the file contents with the key file data */
+  if (!g_file_replace_contents (file, contents, length, NULL, FALSE, 
+                                G_FILE_CREATE_REPLACE_DESTINATION, NULL,
+                                cancellable, error))
+    {
+      g_free (contents);
+      return FALSE;
+    }
+  else
+    {
+      g_free (contents);
+      return TRUE;
+    }
+}
+
+
+
 gchar *
+g_file_get_location (GFile *file)
+{
+  gchar *location;
+
+  _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
+  
+  location = g_file_get_path (file);
+  if (location == NULL)
+    location = g_file_get_uri (file);
+
+  return location;
+}
+
+
+
+gchar *
 g_file_size_humanize (guint64 size)
 {
   gchar *buffer;
@@ -369,3 +458,36 @@
 
   return has_media;
 }
+
+
+
+gboolean
+g_mount_is_same_drive (GMount *mount,
+                       GMount *other)
+{
+  gboolean same_drive = FALSE;
+  GDrive  *mount_drive;
+  GDrive  *other_drive;
+
+  _thunar_return_val_if_fail (mount == NULL || G_IS_MOUNT (mount), FALSE);
+  _thunar_return_val_if_fail (other == NULL || G_IS_MOUNT (other), FALSE);
+
+  if (mount == NULL || other == NULL)
+    return FALSE;
+
+  mount_drive = g_mount_get_drive (mount);
+  other_drive = g_mount_get_drive (other);
+
+  if (mount_drive != NULL && other_drive != NULL)
+    {
+      same_drive = (mount_drive == other_drive);
+    }
+
+  if (mount_drive != NULL)
+    g_object_unref (mount_drive);
+  
+  if (other_drive != NULL)
+    g_object_unref (other_drive);
+
+  return same_drive;
+}

Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -24,18 +24,28 @@
 
 G_BEGIN_DECLS
 
-GFile   *g_file_new_for_home              (void);
-GFile   *g_file_new_for_root              (void);
-GFile   *g_file_new_for_trash             (void);
-GFile   *g_file_new_for_desktop           (void);
-GFile   *g_file_new_for_user_special_dir  (GUserDirectory dir);
+GFile    *g_file_new_for_home              (void);
+GFile    *g_file_new_for_root              (void);
+GFile    *g_file_new_for_trash             (void);
+GFile    *g_file_new_for_desktop           (void);
+GFile    *g_file_new_for_user_special_dir  (GUserDirectory      dir);
 
-gboolean g_file_is_root                   (GFile         *file);
-gboolean g_file_is_trashed                (GFile         *file);
-gboolean g_file_is_desktop                (GFile         *file);
+gboolean  g_file_is_root                   (GFile              *file);
+gboolean  g_file_is_trashed                (GFile              *file);
+gboolean  g_file_is_desktop                (GFile              *file);
 
-gchar   *g_file_size_humanize             (guint64        size);
+GKeyFile *g_file_query_key_file            (GFile              *file,
+                                            GCancellable       *cancellable,
+                                            GError            **error);
+gboolean  g_file_write_key_file            (GFile              *file,
+                                            GKeyFile           *key_file,
+                                            GCancellable       *cancellable,
+                                            GError            **error);
 
+gchar    *g_file_get_location              (GFile              *file);
+
+gchar    *g_file_size_humanize             (guint64             size);
+
 /**
  * G_TYPE_FILE_LIST:
  *
@@ -44,21 +54,24 @@
  **/
 #define G_TYPE_FILE_LIST (g_file_list_get_type ())
 
-GType    g_file_list_get_type             (void);
+GType     g_file_list_get_type             (void);
 
-GList   *g_file_list_new_from_string      (const gchar   *string);
-gchar   *g_file_list_to_string            (GList         *list);
-GList   *g_file_list_append               (GList         *list,
-                                           GFile         *file);
-GList   *g_file_list_prepend              (GList         *list,
-                                           GFile         *file);
-GList   *g_file_list_copy                 (GList         *list);
-void     g_file_list_free                 (GList         *list);
+GList    *g_file_list_new_from_string      (const gchar        *string);
+gchar    *g_file_list_to_string            (GList              *list);
+GList    *g_file_list_append               (GList              *list,
+                                            GFile              *file);
+GList    *g_file_list_prepend              (GList              *list,
+                                            GFile              *file);
+GList    *g_file_list_copy                 (GList              *list);
+void      g_file_list_free                 (GList              *list);
 
-gboolean g_volume_is_removable            (GVolume       *volume);
-gboolean g_volume_is_mounted              (GVolume       *volume);
-gboolean g_volume_is_present              (GVolume       *volume);
+gboolean  g_volume_is_removable            (GVolume            *volume);
+gboolean  g_volume_is_mounted              (GVolume            *volume);
+gboolean  g_volume_is_present              (GVolume            *volume);
 
+gboolean  g_mount_is_same_drive            (GMount             *mount,
+                                            GMount             *other);
+
 G_END_DECLS
 
 #endif /* !__THUNAR_GLIB_EXTENSIONS_H__ */

Modified: thunar/branches/migration-to-gio/thunar/thunar-icon-factory.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-icon-factory.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-icon-factory.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -924,7 +925,7 @@
   ThunarVfsInfo       *info;
   ThunarVfsPath       *path;
   ThunarIconKey        key;
-  GdkPixbuf           *icon;
+  GdkPixbuf           *icon = NULL;
   guint64              time;
   gchar               *icon_name;
   gchar               *thumb_path;
@@ -933,9 +934,9 @@
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
   _thunar_return_val_if_fail (icon_size > 0, NULL);
 
-  /* check if there's a custom icon for the file */
+  /* check if we have a custom icon for this file */
   icon_name = thunar_file_get_custom_icon (file);
-  if (G_UNLIKELY (icon_name != NULL))
+  if (icon_name != NULL)
     {
       /* try to load the icon */
       icon = thunar_icon_factory_lookup_icon (factory, icon_name, icon_size, FALSE);
@@ -955,33 +956,38 @@
         {
 again:
           /* determine the ThunarVfsInfo for the file */
-          info = thunar_file_get_info (file);
+          info = thunarx_file_info_get_vfs_info (THUNARX_FILE_INFO (file));
+          if (info != NULL)
+            {
+              /* try to load an existing thumbnail for the file */
+              thumb_path = thunar_vfs_thumb_factory_lookup_thumbnail (factory->thumbnail_factory, info);
 
-          /* try to load an existing thumbnail for the file */
-          thumb_path = thunar_vfs_thumb_factory_lookup_thumbnail (factory->thumbnail_factory, info);
+              /* check if we can generate a thumbnail in case there's none yet */
+              if (G_UNLIKELY (thumb_path == NULL && thunar_vfs_thumb_factory_can_thumbnail (factory->thumbnail_factory, info)))
+                {
+                  /* schedule the thumbnail loading for the file */
+                  thunar_thumbnail_generator_enqueue (factory->thumbnail_generator, file);
 
-          /* check if we can generate a thumbnail in case there's none yet */
-          if (G_UNLIKELY (thumb_path == NULL && thunar_vfs_thumb_factory_can_thumbnail (factory->thumbnail_factory, info)))
-            {
-              /* schedule the thumbnail loading for the file */
-              thunar_thumbnail_generator_enqueue (factory->thumbnail_generator, file);
+                  /* set the thumbnail state to "loading" */
+                  thumb_state = THUNAR_FILE_THUMB_STATE_LOADING;
+                }
 
-              /* set the thumbnail state to "loading" */
-              thumb_state = THUNAR_FILE_THUMB_STATE_LOADING;
-            }
+              if (G_LIKELY (thumb_path != NULL))
+                {
+                  thumb_state = THUNAR_FILE_THUMB_STATE_READY;
+                  g_object_set_qdata_full (G_OBJECT (file), thunar_file_thumb_path_quark, thumb_path, g_free);
+                }
+              else if (thumb_state != THUNAR_FILE_THUMB_STATE_LOADING)
+                {
+                  thumb_state = THUNAR_FILE_THUMB_STATE_NONE;
+                }
 
-          if (G_LIKELY (thumb_path != NULL))
-            {
-              thumb_state = THUNAR_FILE_THUMB_STATE_READY;
-              g_object_set_qdata_full (G_OBJECT (file), thunar_file_thumb_path_quark, thumb_path, g_free);
+              /* apply the new state */
+              thunar_file_set_thumb_state (file, thumb_state);
+
+              /* release the file info */
+              thunar_vfs_info_unref (info);
             }
-          else if (thumb_state != THUNAR_FILE_THUMB_STATE_LOADING)
-            {
-              thumb_state = THUNAR_FILE_THUMB_STATE_NONE;
-            }
-
-          /* apply the new state */
-          thunar_file_set_thumb_state (file, thumb_state);
         }
 
       /* check if we have a thumbnail path loaded */
@@ -995,40 +1001,45 @@
               if (G_LIKELY (icon != NULL))
                 {
                   /* determine the VFS info for the file */
-                  info = thunar_file_get_info (file);
-
-                  /* determine mtime and path for the thumbnail */
-                  path = g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_path_quark);
-                  time = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark));
-
-                  /* check if mtime and path was already associated with the thumbnail */
-                  if (G_UNLIKELY (path == NULL))
+                  info = thunarx_file_info_get_vfs_info (THUNARX_FILE_INFO (file));
+                  if (info != NULL)
                     {
-                      /* just save mtime and path for the thumbnail */
-                      g_object_set_qdata_full (G_OBJECT (icon), thunar_icon_thumb_path_quark,
-                                               thunar_vfs_path_ref (info->path),
-                                               (GDestroyNotify) thunar_vfs_path_unref);
-                      g_object_set_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark,
-                                          GUINT_TO_POINTER (info->mtime));
-                    }
-                  else if (G_UNLIKELY (time != info->mtime || !thunar_vfs_path_equal (path, info->path)))
-                    {
-                      /* the thumbnail is no longer valid, remove it from our internal cache */
-                      key.name = thumb_path;
-                      key.size = icon_size;
+                      /* determine mtime and path for the thumbnail */
+                      path = g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_path_quark);
+                      time = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark));
 
-                      /* try to remove based on the key */
-                      if (g_hash_table_remove (factory->icon_cache, &key))
+                      /* check if mtime and path was already associated with the thumbnail */
+                      if (G_UNLIKELY (path == NULL))
                         {
-                          /* we only restart the operation if we were successfull, else we could recurse infinitely */
-                          thumb_state = THUNAR_FILE_THUMB_STATE_UNKNOWN;
-                          g_object_unref (G_OBJECT (icon));
-                          goto again;
+                          /* just save mtime and path for the thumbnail */
+                          g_object_set_qdata_full (G_OBJECT (icon), thunar_icon_thumb_path_quark,
+                                                   thunar_vfs_path_ref (info->path),
+                                                   (GDestroyNotify) thunar_vfs_path_unref);
+                          g_object_set_qdata (G_OBJECT (icon), thunar_icon_thumb_time_quark,
+                                              GUINT_TO_POINTER (info->mtime));
                         }
+                      else if (G_UNLIKELY (time != info->mtime || !thunar_vfs_path_equal (path, info->path)))
+                        {
+                          /* the thumbnail is no longer valid, remove it from our internal cache */
+                          key.name = thumb_path;
+                          key.size = icon_size;
+
+                          /* try to remove based on the key */
+                          if (g_hash_table_remove (factory->icon_cache, &key))
+                            {
+                              /* we only restart the operation if we were successfull, else we could recurse infinitely */
+                              thumb_state = THUNAR_FILE_THUMB_STATE_UNKNOWN;
+                              g_object_unref (G_OBJECT (icon));
+                              goto again;
+                            }
+                        }
+
+                      /* release the info */
+                      thunar_vfs_info_unref (info);
+
+                      /* ok, we have a valid thumbnail */
+                      return icon;
                     }
-
-                  /* ok, we have a valid thumbnail */
-                  return icon;
                 }
             }
         }

Modified: thunar/branches/migration-to-gio/thunar/thunar-list-model.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-list-model.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-list-model.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -1468,9 +1468,20 @@
                const ThunarFile *b,
                gboolean          case_sensitive)
 {
-  if (a->info->gid < b->info->gid)
+  guint32 gid_a;
+  guint32 gid_b;
+
+  if (thunar_file_get_info (a) == NULL || thunar_file_get_info (b) == NULL)
+    return 0;
+
+  gid_a = g_file_info_get_attribute_uint32 (thunar_file_get_info (a),
+                                            G_FILE_ATTRIBUTE_UNIX_GID);
+  gid_b = g_file_info_get_attribute_uint32 (thunar_file_get_info (b),
+                                            G_FILE_ATTRIBUTE_UNIX_GID);
+
+  if (gid_a < gid_b)
     return -1;
-  else if (a->info->gid > b->info->gid)
+  else if (gid_a > gid_b)
     return 1;
   else
     return sort_by_name (a, b, case_sensitive);
@@ -1515,9 +1526,20 @@
                const ThunarFile *b,
                gboolean          case_sensitive)
 {
-  if (a->info->uid < b->info->uid)
+  guint32 uid_a;
+  guint32 uid_b;
+
+  if (thunar_file_get_info (a) == NULL || thunar_file_get_info (b) == NULL)
+    return 0;
+
+  uid_a = g_file_info_get_attribute_uint32 (thunar_file_get_info (a),
+                                            G_FILE_ATTRIBUTE_UNIX_UID);
+  uid_b = g_file_info_get_attribute_uint32 (thunar_file_get_info (b),
+                                            G_FILE_ATTRIBUTE_UNIX_UID);
+
+  if (uid_a < uid_b)
     return -1;
-  else if (a->info->uid > b->info->uid)
+  else if (uid_a > uid_b)
     return 1;
   else
     return sort_by_name (a, b, case_sensitive);

Modified: thunar/branches/migration-to-gio/thunar/thunar-location-button.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-location-button.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-location-button.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -508,8 +508,11 @@
 
   /* setup the DnD icon for the button */
   icon_name = thunar_file_get_custom_icon (file);
-  if (G_LIKELY (icon_name == NULL))
-    icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, icon_theme);
+  if (icon_name == NULL)
+    {
+      icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, 
+                                             icon_theme);
+    }
   gtk_drag_source_set_icon_name (GTK_BIN (location_button)->child, icon_name);
   g_free (icon_name);
 }

Modified: thunar/branches/migration-to-gio/thunar/thunar-location-dialog.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-location-dialog.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-location-dialog.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -28,7 +28,7 @@
 
 
 
-static void thunar_location_dialog_init (ThunarLocationDialog      *location_dialog);
+static void thunar_location_dialog_init (ThunarLocationDialog *location_dialog);
 
 
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-metafile.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-metafile.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-metafile.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -38,6 +38,10 @@
 #include <string.h>
 #endif
 
+#include <gio/gio.h>
+
+#include <exo/exo.h>
+
 #include <tdb/tdb.h>
 
 #include <thunar/thunar-metafile.h>

Modified: thunar/branches/migration-to-gio/thunar/thunar-metafile.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-metafile.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-metafile.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -21,7 +21,7 @@
 #ifndef __THUNAR_METAFILE_H__
 #define __THUNAR_METAFILE_H__
 
-#include <thunar-vfs/thunar-vfs.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS;
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -55,11 +55,11 @@
 static ThunarJobResponse thunar_progress_dialog_ask          (ThunarProgressDialog       *dialog,
                                                               const gchar                *message,
                                                               ThunarJobResponse           choices,
-                                                              ExoJob                     *job);
+                                                              ThunarJob                  *job);
 static ThunarJobResponse thunar_progress_dialog_ask_replace  (ThunarProgressDialog       *dialog,
                                                               ThunarFile                 *src_file,
                                                               ThunarFile                 *dst_file,
-                                                              ExoJob                     *job);
+                                                              ThunarJob                  *job);
 static void              thunar_progress_dialog_error        (ThunarProgressDialog       *dialog,
                                                               GError                     *error,
                                                               ExoJob                     *job);
@@ -83,7 +83,7 @@
 {
   GtkDialog  __parent__;
 
-  ExoJob    *job;
+  ThunarJob *job;
 
   GTimeVal   start_time;
   GTimeVal   last_update_time;
@@ -273,7 +273,7 @@
 thunar_progress_dialog_ask (ThunarProgressDialog *dialog,
                             const gchar          *message,
                             ThunarJobResponse     choices,
-                            ExoJob               *job)
+                            ThunarJob            *job)
 {
   _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_JOB_RESPONSE_CANCEL);
   _thunar_return_val_if_fail (g_utf8_validate (message, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL);
@@ -293,7 +293,7 @@
 thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog,
                                     ThunarFile           *src_file,
                                     ThunarFile           *dst_file,
-                                    ExoJob               *job)
+                                    ThunarJob            *job)
 {
   _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_JOB_RESPONSE_CANCEL);
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL);
@@ -318,7 +318,7 @@
   _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog));
   _thunar_return_if_fail (error != NULL && error->message != NULL);
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (dialog->job == job);
+  _thunar_return_if_fail (dialog->job == THUNAR_JOB (job));
 
   /* be sure to display the progress dialog prior to opening the error dialog */
   gtk_widget_show_now (GTK_WIDGET (dialog));
@@ -335,7 +335,7 @@
 {
   _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog));
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (dialog->job == job);
+  _thunar_return_if_fail (dialog->job == THUNAR_JOB (job));
 
   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
 }
@@ -350,7 +350,7 @@
   _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog));
   _thunar_return_if_fail (g_utf8_validate (message, -1, NULL));
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (dialog->job == job);
+  _thunar_return_if_fail (dialog->job == THUNAR_JOB (job));
 
   gtk_label_set_text (GTK_LABEL (dialog->progress_label), message);
 }
@@ -380,7 +380,7 @@
   _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog));
   _thunar_return_if_fail (percent >= 0.0 && percent <= 100.0);
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (dialog->job == job);
+  _thunar_return_if_fail (dialog->job == THUNAR_JOB (job));
 
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dialog->progress_bar), percent / 100.0);
 
@@ -442,7 +442,7 @@
     case GTK_RESPONSE_CLOSE:
     case GTK_RESPONSE_NO:
       if (G_LIKELY (THUNAR_PROGRESS_DIALOG (dialog)->job != NULL))
-        exo_job_cancel (THUNAR_PROGRESS_DIALOG (dialog)->job);
+        exo_job_cancel (EXO_JOB (THUNAR_PROGRESS_DIALOG (dialog)->job));
       break;
     }
 
@@ -469,15 +469,14 @@
 
 /**
  * thunar_progress_dialog_new_with_job:
- * @job : a #ExoJob    or %NULL.
+ * @job : a #ThunarJob or %NULL.
  *
- * Allocates a new #ThunarProgressDialog and associates it with
- * the @job.
+ * Allocates a new #ThunarProgressDialog and associates it with the @job.
  *
  * Return value: the newly allocated #ThunarProgressDialog.
  **/
 GtkWidget*
-thunar_progress_dialog_new_with_job (ExoJob    *job)
+thunar_progress_dialog_new_with_job (ThunarJob *job)
 {
   _thunar_return_val_if_fail (job == NULL || THUNAR_IS_JOB (job), NULL);
   return g_object_new (THUNAR_TYPE_PROGRESS_DIALOG, "job", job, NULL);
@@ -489,12 +488,12 @@
  * thunar_progress_dialog_get_job:
  * @dialog : a #ThunarProgressDialog.
  *
- * Returns the #ExoJob    associated with @dialog
+ * Returns the #ThunarJob associated with @dialog
  * or %NULL if no job is currently associated with @dialog.
  *
  * Return value: the job associated with @dialog or %NULL.
  **/
-ExoJob    *
+ThunarJob *
 thunar_progress_dialog_get_job (ThunarProgressDialog *dialog)
 {
   _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), NULL);
@@ -506,13 +505,13 @@
 /**
  * thunar_progress_dialog_set_job:
  * @dialog : a #ThunarProgressDialog.
- * @job    : a #ExoJob    or %NULL.
+ * @job    : a #ThunarJob or %NULL.
  *
  * Associates @job with @dialog.
  **/
 void
 thunar_progress_dialog_set_job (ThunarProgressDialog *dialog,
-                                ExoJob               *job)
+                                ThunarJob            *job)
 {
   _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog));
   _thunar_return_if_fail (job == NULL || THUNAR_IS_JOB (job));

Modified: thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -21,8 +21,10 @@
 #ifndef __THUNAR_PROGRESS_DIALOG_H__
 #define __THUNAR_PROGRESS_DIALOG_H__
 
-#include <thunar-vfs/thunar-vfs.h>
+#include <gtk/gtk.h>
 
+#include <thunar/thunar-job.h>
+
 G_BEGIN_DECLS;
 
 typedef struct _ThunarProgressDialogClass ThunarProgressDialogClass;
@@ -38,11 +40,11 @@
 GType         thunar_progress_dialog_get_type      (void) G_GNUC_CONST;
 
 GtkWidget    *thunar_progress_dialog_new           (void) G_GNUC_MALLOC;
-GtkWidget    *thunar_progress_dialog_new_with_job  (ExoJob               *job) G_GNUC_MALLOC;
+GtkWidget    *thunar_progress_dialog_new_with_job  (ThunarJob            *job) G_GNUC_MALLOC;
 
-ExoJob       *thunar_progress_dialog_get_job       (ThunarProgressDialog *dialog);
+ThunarJob    *thunar_progress_dialog_get_job       (ThunarProgressDialog *dialog);
 void          thunar_progress_dialog_set_job       (ThunarProgressDialog *dialog,
-                                                    ExoJob               *job);
+                                                    ThunarJob            *job);
 
 G_END_DECLS;
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-renamer-model.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-renamer-model.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-renamer-model.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -631,6 +631,7 @@
                                    ThunarFileMonitor  *file_monitor)
 {
   ThunarRenamerModelItem *item;
+  ThunarVfsInfo          *info;
   GtkTreePath            *path;
   GtkTreeIter             iter;
   GList                  *lp;
@@ -646,11 +647,12 @@
       {
         /* check if the file changed on disk */
         item = THUNAR_RENAMER_MODEL_ITEM (lp->data);
-        if (!thunar_vfs_info_matches (item->info, thunar_file_get_info (file)))
+        info = thunarx_file_info_get_vfs_info (THUNARX_FILE_INFO (file));
+        if (info == NULL || !thunar_vfs_info_matches (item->info, info))
           {
             /* connect to the new info */
             thunar_vfs_info_unref (item->info);
-            item->info = thunar_vfs_info_ref (thunar_file_get_info (file));
+            item->info = info;
 
             /* check if we're frozen */
             if (G_LIKELY (!renamer_model->frozen))
@@ -663,6 +665,8 @@
                 break;
               }
           }
+        else
+          thunar_vfs_info_unref (info);
 
         /* determine the iter for the item */
         GTK_TREE_ITER_INIT (iter, renamer_model->stamp, lp);
@@ -1005,7 +1009,7 @@
   ThunarRenamerModelItem *item;
 
   item = _thunar_slice_new0 (ThunarRenamerModelItem);
-  item->info = thunar_vfs_info_ref (thunar_file_get_info (file));
+  item->info = thunarx_file_info_get_vfs_info (THUNARX_FILE_INFO (file));
   item->file = g_object_ref (G_OBJECT (file));
   item->dirty = TRUE;
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -342,7 +343,7 @@
       /* allocate a thumbnail info for the file */
       info = _thunar_slice_new (ThunarThumbnailInfo);
       info->file = g_object_ref (G_OBJECT (file));
-      info->info = thunar_vfs_info_copy (thunar_file_get_info (file));
+      info->info = thunarx_file_info_get_vfs_info (THUNARX_FILE_INFO (file));
 
       /* schedule the request */
       generator->requests = g_list_append (generator->requests, info);

Modified: thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-thumbnail-generator.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -20,6 +20,8 @@
 #ifndef __THUNAR_THUMBNAIL_GENERATOR_H__
 #define __THUNAR_THUMBNAIL_GENERATOR_H__
 
+#include <thunar-vfs/thunar-vfs.h>
+
 #include <thunar/thunar-file.h>
 
 G_BEGIN_DECLS;

Modified: thunar/branches/migration-to-gio/thunar/thunar-tree-model.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-tree-model.h	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-tree-model.h	2009-05-11 01:37:08 UTC (rev 29935)
@@ -43,7 +43,7 @@
  * @THUNAR_TREE_MODEL_COLUMN_FILE   : the index of the file column.
  * @THUNAR_TREE_MODEL_COLUMN_NAME   : the index of the name column.
  * @THUNAR_TREE_MODEL_COLUMN_ATTR   : the index of the #PangoAttrList column.
- * @THUNAR_TREE_MODEL_COLUMN_VOLUME : the index of the #ThunarVfsVolume column.
+ * @THUNAR_TREE_MODEL_COLUMN_VOLUME : the index of the #GVolume column.
  *
  * Columns exported by the #ThunarTreeModel using the
  * #GtkTreeModel interface.

Modified: thunar/branches/migration-to-gio/thunar/thunar-window.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-window.c	2009-05-10 08:01:53 UTC (rev 29934)
+++ thunar/branches/migration-to-gio/thunar/thunar-window.c	2009-05-11 01:37:08 UTC (rev 29935)
@@ -2233,7 +2233,6 @@
                                          ThunarWindow *window)
 {
   ThunarFile *new_directory = NULL;
-  GMount     *mount;
   GFile      *path;
   GFile      *tmp;
 
@@ -2242,24 +2241,40 @@
   _thunar_return_if_fail (window->current_directory == current_directory);
 
   /* determine the path of the current directory */
-  path = thunar_file_get_file (current_directory);
+  path = g_object_ref (thunar_file_get_file (current_directory));
 
-  while (new_directory == NULL && path != NULL)
+  /* try to find a parent directory that still exists */
+  while (new_directory == NULL)
     {
-      /* TODO make this asynchronous if possible */
-      mount = g_file_find_enclosing_mount (path, NULL, NULL);
-
-      if (mount != NULL)
+      /* check whether the current directory exists */
+      if (g_file_query_exists (path, NULL))
         {
+          /* it does, try to load the file */
           new_directory = thunar_file_get (path, NULL);
-          g_object_unref (mount);
+
+          /* fall back to $HOME if loading the file failed */
+          if (new_directory == NULL)
+            break;
         }
+      else
+        {
+          /* determine the parent of the directory */
+          tmp = g_file_get_parent (path);
+          
+          /* if there's no parent this means that we've found no parent
+           * that still exists at all. Fall back to $HOME then */
+          if (tmp == NULL)
+            break;
 
-      tmp = g_file_get_parent (path);
-      g_object_unref (path);
-      path = tmp;
+          /* free the old directory */
+          g_object_unref (path);
+
+          /* check the parent next */
+          path = tmp;
+        }
     }
 
+  /* make sure we don't leak */
   if (path != NULL)
     g_object_unref (path);
 




More information about the Xfce4-commits mailing list