diff --git a/ChangeLog b/ChangeLog
index 8db7e5f82f166f838094dbddb8f51f97fb3fd3fc..d734fbe0b671366a0e6f206bf9b622e76c403bf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-03-08	Benedikt Meurer <benny@xfce.org>
+
+	* thunar/thunar-view.{c,h}: Add new methods get_visible_range() and
+	  scroll_to_file().
+	* thunar/thunar-standard-view.c: Implement get_visible_range() and
+	  scroll_to_file(). Drop the scroll_offsets, will be handled in
+	  ThunarWindow.
+	* thunar/thunar-window.{c,h}: Remember the first visible file whenever
+	  leaving a directory and scroll to it when entering the directory
+	  again.
+	* thunar/thunar-application.{c,h}: Return the created window from the
+	  thunar_application_open_window() method.
+	* thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c:
+	  Add DisplayFolderAndSelect() to the org.xfce.FileManager interface.
+	  File managers that cannot scroll and select to a given file can
+	  silently ignore the filename parameter and handle it like an
+	  invocation of DisplayFolder(). Bug #1553.
+
 2006-03-08	Benedikt Meurer <benny@xfce.org>
 
 	* thunar/thunar-shortcuts-view.c: Fix shortcut rename.
diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c
index 8c7a2722a40070d0cb354408ecf5b3d3b6e812e8..82936f5b745193b56e6c52a1f5cddce1eb6a46a1 100644
--- a/thunar/thunar-application.c
+++ b/thunar/thunar-application.c
@@ -50,41 +50,41 @@ enum
 
 
 
-static void     thunar_application_class_init             (ThunarApplicationClass *klass);
-static void     thunar_application_init                   (ThunarApplication      *application);
-static void     thunar_application_finalize               (GObject                *object);
-static void     thunar_application_get_property           (GObject                *object,
-                                                           guint                   prop_id,
-                                                           GValue                 *value,
-                                                           GParamSpec             *pspec);
-static void     thunar_application_set_property           (GObject                *object,
-                                                           guint                   prop_id,
-                                                           const GValue           *value,
-                                                           GParamSpec             *pspec);
-static void     thunar_application_collect_and_launch     (ThunarApplication      *application,
-                                                           GtkWidget              *widget,
-                                                           const gchar            *icon_name,
-                                                           const gchar            *title,
-                                                           Launcher                launcher,
-                                                           GList                  *source_path_list,
-                                                           ThunarVfsPath          *target_path,
-                                                           GClosure               *new_files_closure);
-static void     thunar_application_launch                 (ThunarApplication      *application,
-                                                           GtkWidget              *widget,
-                                                           const gchar            *icon_name,
-                                                           const gchar            *title,
-                                                           Launcher                launcher,
-                                                           GList                  *source_path_list,
-                                                           GList                  *target_path_list,
-                                                           GClosure               *new_files_closure);
-static void     thunar_application_open_window_with_role  (ThunarApplication      *application,
-                                                           const gchar            *role,
-                                                           ThunarFile             *directory,
-                                                           GdkScreen              *screen);
-static void     thunar_application_window_destroyed       (GtkWidget              *window,
-                                                           ThunarApplication      *application);
-static gboolean thunar_application_show_dialogs           (gpointer                user_data);
-static void     thunar_application_show_dialogs_destroy   (gpointer                user_data);
+static void       thunar_application_class_init             (ThunarApplicationClass *klass);
+static void       thunar_application_init                   (ThunarApplication      *application);
+static void       thunar_application_finalize               (GObject                *object);
+static void       thunar_application_get_property           (GObject                *object,
+                                                             guint                   prop_id,
+                                                             GValue                 *value,
+                                                             GParamSpec             *pspec);
+static void       thunar_application_set_property           (GObject                *object,
+                                                             guint                   prop_id,
+                                                             const GValue           *value,
+                                                             GParamSpec             *pspec);
+static void       thunar_application_collect_and_launch     (ThunarApplication      *application,
+                                                             GtkWidget              *widget,
+                                                             const gchar            *icon_name,
+                                                             const gchar            *title,
+                                                             Launcher                launcher,
+                                                             GList                  *source_path_list,
+                                                             ThunarVfsPath          *target_path,
+                                                             GClosure               *new_files_closure);
+static void       thunar_application_launch                 (ThunarApplication      *application,
+                                                             GtkWidget              *widget,
+                                                             const gchar            *icon_name,
+                                                             const gchar            *title,
+                                                             Launcher                launcher,
+                                                             GList                  *source_path_list,
+                                                             GList                  *target_path_list,
+                                                             GClosure               *new_files_closure);
+static GtkWidget *thunar_application_open_window_with_role  (ThunarApplication      *application,
+                                                             const gchar            *role,
+                                                             ThunarFile             *directory,
+                                                             GdkScreen              *screen);
+static void       thunar_application_window_destroyed       (GtkWidget              *window,
+                                                             ThunarApplication      *application);
+static gboolean   thunar_application_show_dialogs           (gpointer                user_data);
+static void       thunar_application_show_dialogs_destroy   (gpointer                user_data);
 
 
 
@@ -353,7 +353,7 @@ thunar_application_launch (ThunarApplication *application,
 
 
 
-static void
+static GtkWidget*
 thunar_application_open_window_with_role (ThunarApplication *application,
                                           const gchar       *role,
                                           ThunarFile        *directory,
@@ -378,6 +378,8 @@ thunar_application_open_window_with_role (ThunarApplication *application,
 
   /* change the directory */
   thunar_window_set_current_directory (THUNAR_WINDOW (window), directory);
+
+  return window;
 }
 
 
@@ -569,29 +571,34 @@ thunar_application_take_window (ThunarApplication *application,
 
 /**
  * thunar_application_open_window:
- * @application : a #ThunarApplication.
- * @directory   : the directory to open.
- * @screen      : the #GdkScreen on which to open the window or %NULL
- *                to open on the default screen.
+ * @application    : a #ThunarApplication.
+ * @directory      : the directory to open.
+ * @screen         : the #GdkScreen on which to open the window or %NULL
+ *                   to open on the default screen.
  *
  * Opens a new #ThunarWindow for @application, displaying the
  * given @directory.
+ *
+ * Return value: the newly allocated #ThunarWindow.
  **/
-void
+GtkWidget*
 thunar_application_open_window (ThunarApplication *application,
                                 ThunarFile        *directory,
                                 GdkScreen         *screen)
 {
-  gchar *role;
+  GtkWidget *window;
+  gchar     *role;
 
-  g_return_if_fail (THUNAR_IS_APPLICATION (application));
-  g_return_if_fail (THUNAR_IS_FILE (directory));
-  g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
+  g_return_val_if_fail (THUNAR_IS_APPLICATION (application), NULL);
+  g_return_val_if_fail (THUNAR_IS_FILE (directory), NULL);
+  g_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), NULL);
 
   /* generate a unique role for the new window (for session management) */
   role = g_strdup_printf ("Thunar-%u-%u", (guint) time (NULL), (guint) g_random_int ());
-  thunar_application_open_window_with_role (application, role, directory, screen);
+  window = thunar_application_open_window_with_role (application, role, directory, screen);
   g_free (role);
+
+  return window;
 }
 
 
diff --git a/thunar/thunar-application.h b/thunar/thunar-application.h
index 5e29215cfda75ced771de72a241959481d68814e..df97d29500a9d4f20b75ce27e278a199738e3616 100644
--- a/thunar/thunar-application.h
+++ b/thunar/thunar-application.h
@@ -50,7 +50,7 @@ gboolean           thunar_application_has_windows       (ThunarApplication *appl
 void               thunar_application_take_window       (ThunarApplication *application,
                                                          GtkWindow         *window);
 
-void               thunar_application_open_window       (ThunarApplication *application,
+GtkWidget         *thunar_application_open_window       (ThunarApplication *application,
                                                          ThunarFile        *directory,
                                                          GdkScreen         *screen);
 
diff --git a/thunar/thunar-dbus-service-infos.xml b/thunar/thunar-dbus-service-infos.xml
index 4959fc1ff69a6ae8431ebeb9a41da33f3cae2e41..5062ef31581504fe818e7e04e45436d6e7cb6daa 100644
--- a/thunar/thunar-dbus-service-infos.xml
+++ b/thunar/thunar-dbus-service-infos.xml
@@ -43,6 +43,29 @@
     </method>
 
 
+    <!--
+      DisplayFolderAndSelect (uri : STRING, filename : STRING, display : STRING) : VOID
+
+      uri        : either a file:-URI or an absolute path.
+      filename   : the name of the file in the folder which should
+                   be selected by the file manager after loading the
+                   folder. The file manager will also scroll the view
+                   to ensure that the file is visible. The filename
+                   must be a name relative to the folder URI.
+      display    : the screen on which to display the folder or ""
+                   to use the default screen of the file manager.
+
+      Note to implementors: Not all file managers may be able to
+      implement this method properly for whatever reasons. If you
+      cannot implement it properly, handle this method like an
+      invocation of DisplayFolder() and ignore the filename.
+    -->
+    <method name="DisplayFolderAndSelect">
+      <arg direction="in" name="uri" type="s" />
+      <arg direction="in" name="filename" type="s" />
+      <arg direction="in" name="display" type="s" />
+    </method>
+
     <!--
       DisplayFileProperties (uri : STRING, display : STRING) : VOID
 
diff --git a/thunar/thunar-dbus-service.c b/thunar/thunar-dbus-service.c
index 46616d596c4622a77a3d1ffbc0134334551e559a..ae267a09298469d84b47f17d70462c27355f7b33 100644
--- a/thunar/thunar-dbus-service.c
+++ b/thunar/thunar-dbus-service.c
@@ -21,6 +21,13 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
 #include <dbus/dbus-glib-bindings.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus.h>
@@ -49,6 +56,11 @@ static gboolean thunar_dbus_service_display_folder              (ThunarDBusServi
                                                                  const gchar            *uri,
                                                                  const gchar            *display,
                                                                  GError                **error);
+static gboolean thunar_dbus_service_display_folder_and_select   (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *uri,
+                                                                 const gchar            *filename,
+                                                                 const gchar            *display,
+                                                                 GError                **error);
 static gboolean thunar_dbus_service_display_file_properties     (ThunarDBusService      *dbus_service,
                                                                  const gchar            *uri,
                                                                  const gchar            *display,
@@ -244,6 +256,64 @@ thunar_dbus_service_display_folder (ThunarDBusService *dbus_service,
 
 
 
+static gboolean
+thunar_dbus_service_display_folder_and_select (ThunarDBusService *dbus_service,
+                                               const gchar       *uri,
+                                               const gchar       *filename,
+                                               const gchar       *display,
+                                               GError           **error)
+{
+  ThunarApplication *application;
+  ThunarVfsPath     *path;
+  ThunarFile        *file;
+  ThunarFile        *folder;
+  GdkScreen         *screen;
+  GtkWidget         *window;
+
+  /* verify that filename is valid */
+  if (G_UNLIKELY (filename == NULL || *filename == '\0' || strchr (filename, '/') != NULL))
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid filename \"%s\""), filename);
+      return FALSE;
+    }
+
+  /* parse uri and display parameters */
+  if (!thunar_dbus_service_parse_uri_and_display (dbus_service, uri, display, &folder, &screen, error))
+    return FALSE;
+
+  /* popup a new window for the folder */
+  application = thunar_application_get ();
+  window = thunar_application_open_window (application, folder, screen);
+  g_object_unref (G_OBJECT (application));
+
+  /* determine the path for the filename relative to the folder */
+  path = thunar_vfs_path_relative (thunar_file_get_path (folder), filename);
+  if (G_LIKELY (path != NULL))
+    {
+      /* try to determine the file for the path */
+      file = thunar_file_get_for_path (path, NULL);
+      if (G_LIKELY (file != NULL))
+        {
+          /* tell the window to scroll to the given file and select it */
+          thunar_window_scroll_to_file (THUNAR_WINDOW (window), file, TRUE, TRUE, 0.5f, 0.5f);
+
+          /* release the file reference */
+          g_object_unref (G_OBJECT (file));
+        }
+
+      /* release the path */
+      thunar_vfs_path_unref (path);
+    }
+
+  /* cleanup */
+  g_object_unref (G_OBJECT (screen));
+  g_object_unref (G_OBJECT (folder));
+
+  return TRUE;
+}
+
+
+
 static gboolean
 thunar_dbus_service_display_file_properties (ThunarDBusService *dbus_service,
                                              const gchar       *uri,
diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index 9ba3e83d37e7025541cfa81efe37a74e133df0a4..287453cedd0502fb385e7a5cfde94d48cc107856 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -125,6 +125,15 @@ static void                 thunar_standard_view_set_zoom_level             (Thu
                                                                              ThunarZoomLevel           zoom_level);
 static void                 thunar_standard_view_reset_zoom_level           (ThunarView               *view);
 static void                 thunar_standard_view_reload                     (ThunarView               *view);
+static gboolean             thunar_standard_view_get_visible_range          (ThunarView               *view,
+                                                                             ThunarFile              **start_file,
+                                                                             ThunarFile              **end_file);
+static void                 thunar_standard_view_scroll_to_file             (ThunarView               *view,
+                                                                             ThunarFile               *file,
+                                                                             gboolean                  select,
+                                                                             gboolean                  use_align,
+                                                                             gfloat                    row_align,
+                                                                             gfloat                    col_align);
 static gboolean             thunar_standard_view_delete_selected_files      (ThunarStandardView       *standard_view);
 static GdkDragAction        thunar_standard_view_get_dest_actions           (ThunarStandardView       *standard_view,
                                                                              GdkDragContext           *context,
@@ -280,8 +289,12 @@ struct _ThunarStandardViewPrivate
    */
   GClosure               *new_files_closure;
 
-  /* scroll offsets (-> GtkTreePath indices) per VFS path */
-  GHashTable             *scroll_offsets;
+  /* scroll-to-file support */
+  ThunarFile             *scroll_to_file;
+  guint                   scroll_to_select : 1;
+  guint                   scroll_to_use_align : 1;
+  gfloat                  scroll_to_row_align;
+  gfloat                  scroll_to_col_align;
 };
 
 
@@ -508,6 +521,8 @@ thunar_standard_view_view_init (ThunarViewIface *iface)
   iface->set_zoom_level = thunar_standard_view_set_zoom_level;
   iface->reset_zoom_level = thunar_standard_view_reset_zoom_level;
   iface->reload = thunar_standard_view_reload;
+  iface->get_visible_range = thunar_standard_view_get_visible_range;
+  iface->scroll_to_file = thunar_standard_view_scroll_to_file;
 }
 
 
@@ -519,10 +534,6 @@ thunar_standard_view_init (ThunarStandardView *standard_view)
   standard_view->priv->drag_scroll_timer_id = -1;
   standard_view->priv->drag_timer_id = -1;
 
-  /* setup the scroll paths offset table */
-  standard_view->priv->scroll_offsets = g_hash_table_new_full (thunar_vfs_path_hash, thunar_vfs_path_equal,
-                                                               (GDestroyNotify) thunar_vfs_path_unref, NULL);
-
   /* grab a reference on the preferences */
   standard_view->preferences = thunar_preferences_get ();
 
@@ -700,6 +711,10 @@ thunar_standard_view_finalize (GObject *object)
   g_assert (standard_view->ui_manager == NULL);
   g_assert (standard_view->clipboard == NULL);
 
+  /* release the scroll_to_file reference (if any) */
+  if (G_UNLIKELY (standard_view->priv->scroll_to_file != NULL))
+    g_object_unref (G_OBJECT (standard_view->priv->scroll_to_file));
+
   /* release our reference on the provider factory */
   g_object_unref (G_OBJECT (standard_view->priv->provider_factory));
 
@@ -736,9 +751,6 @@ thunar_standard_view_finalize (GObject *object)
   /* release our list of currently selected files */
   thunar_file_list_free (standard_view->selected_files);
 
-  /* destroy the scroll offset table */
-  g_hash_table_destroy (standard_view->priv->scroll_offsets);
-
   /* free the statusbar text (if any) */
   g_free (standard_view->statusbar_text);
 
@@ -1091,34 +1103,10 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator,
 {
   ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (navigator);
   ThunarFolder       *folder;
-  GtkTreePath        *path;
-  ThunarFile         *file;
-  gint                offset;
 
   g_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
   g_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
   
-  /* determine the (previous) current directory */
-  file = thunar_navigator_get_current_directory (navigator);
-  if (G_LIKELY (file != NULL))
-    {
-      /* determine the first visible tree path */
-      if ((*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_visible_range) (standard_view, &path, NULL))
-        {
-          /* determine the scroll offset from the tree path */
-          offset = gtk_tree_path_get_indices (path)[0] + 1;
-          gtk_tree_path_free (path);
-        }
-      else
-        {
-          /* just use the first available path */
-          offset = 0;
-        }
-
-      /* remember the scroll offset for the directory */
-      g_hash_table_replace (standard_view->priv->scroll_offsets, thunar_vfs_path_ref (thunar_file_get_path (file)), GINT_TO_POINTER (offset));
-    }
-
   /* disconnect any previous "loading" binding */
   if (G_LIKELY (standard_view->loading_binding != NULL))
     exo_binding_unbind (standard_view->loading_binding);
@@ -1130,6 +1118,10 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator,
       return;
     }
 
+  /* scroll to top-left when changing folder */
+  gtk_adjustment_set_value (gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (standard_view)), 0.0);
+  gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (standard_view)), 0.0);
+
   /* We drop the model from the view as a simple optimization to speed up
    * the process of disconnecting the model data from the view.
    */
@@ -1169,9 +1161,7 @@ static void
 thunar_standard_view_set_loading (ThunarStandardView *standard_view,
                                   gboolean            loading)
 {
-  GtkTreePath *path;
-  ThunarFile  *file;
-  gint         offset;
+  ThunarFile *file;
 
   loading = !!loading;
 
@@ -1182,28 +1172,29 @@ thunar_standard_view_set_loading (ThunarStandardView *standard_view,
   /* apply the new state */
   standard_view->loading = loading;
 
-  /* check if this state change was due to a "loading complete" event */
-  if (G_LIKELY (!loading))
+  /* check if we're done loading and have a scheduled scroll_to_file */
+  if (G_UNLIKELY (!loading && standard_view->priv->scroll_to_file != NULL))
     {
-      /* determine the current directory */
-      file = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view));
-      if (G_LIKELY (file != NULL))
-        {
-          /* determine the scroll offset for this folder */
-          offset = GPOINTER_TO_INT (g_hash_table_lookup (standard_view->priv->scroll_offsets, thunar_file_get_path (file)));
-          if (G_LIKELY (offset > 0))
-            {
-              /* scroll to the path for the offset */
-              path = gtk_tree_path_new_from_indices (offset - 1, -1);
-              (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path, TRUE, 0.0f, 0.0f);
-              gtk_tree_path_free (path);
-            }
-        }
+      /* remember and reset the scroll_to_file reference */
+      file = standard_view->priv->scroll_to_file;
+      standard_view->priv->scroll_to_file = NULL;
+
+      /* and try again */
+      thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file,
+                                  standard_view->priv->scroll_to_select,
+                                  standard_view->priv->scroll_to_use_align,
+                                  standard_view->priv->scroll_to_row_align,
+                                  standard_view->priv->scroll_to_col_align);
+
+      /* cleanup */
+      g_object_unref (G_OBJECT (file));
     }
 
   /* notify listeners */
+  g_object_freeze_notify (G_OBJECT (standard_view));
   g_object_notify (G_OBJECT (standard_view), "loading");
   g_object_notify (G_OBJECT (standard_view), "statusbar-text");
+  g_object_thaw_notify (G_OBJECT (standard_view));
 }
 
 
@@ -1312,6 +1303,105 @@ thunar_standard_view_reload (ThunarView *view)
 
 
 
+static gboolean
+thunar_standard_view_get_visible_range (ThunarView  *view,
+                                        ThunarFile **start_file,
+                                        ThunarFile **end_file)
+{
+  ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view);
+  GtkTreePath        *start_path;
+  GtkTreePath        *end_path;
+  GtkTreeIter         iter;
+
+  /* determine the visible range as tree paths */
+  if ((*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_visible_range) (standard_view, &start_path, &end_path))
+    {
+      /* determine the file for the start path */
+      if (G_LIKELY (start_file != NULL))
+        {
+          gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, start_path);
+          *start_file = thunar_list_model_get_file (standard_view->model, &iter);
+        }
+
+      /* determine the file for the end path */
+      if (G_LIKELY (end_file != NULL))
+        {
+          gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, end_path);
+          *end_file = thunar_list_model_get_file (standard_view->model, &iter);
+        }
+
+      /* release the tree paths */
+      gtk_tree_path_free (start_path);
+      gtk_tree_path_free (end_path);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static void
+thunar_standard_view_scroll_to_file (ThunarView *view,
+                                     ThunarFile *file,
+                                     gboolean    select,
+                                     gboolean    use_align,
+                                     gfloat      row_align,
+                                     gfloat      col_align)
+{
+  ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view);
+  GList               files;
+  GList              *paths;
+
+  /* release the previous scroll_to_file reference (if any) */
+  if (G_UNLIKELY (standard_view->priv->scroll_to_file != NULL))
+    {
+      g_object_unref (G_OBJECT (standard_view->priv->scroll_to_file));
+      standard_view->priv->scroll_to_file = NULL;
+    }
+
+  /* check if we're still loading */
+  if (thunar_view_get_loading (view))
+    {
+      /* remember a reference for the new file and settings */
+      standard_view->priv->scroll_to_file = g_object_ref (G_OBJECT (file));
+      standard_view->priv->scroll_to_select = select;
+      standard_view->priv->scroll_to_use_align = use_align;
+      standard_view->priv->scroll_to_row_align = row_align;
+      standard_view->priv->scroll_to_col_align = col_align;
+    }
+  else
+    {
+      /* fake a file list */
+      files.data = file;
+      files.next = NULL;
+      files.prev = NULL;
+
+      /* determine the path for the file */
+      paths = thunar_list_model_get_paths_for_files (standard_view->model, &files);
+      if (G_LIKELY (paths != NULL))
+        {
+          /* scroll to the path */
+          (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, paths->data, use_align, row_align, col_align);
+
+          /* check if we should also alter the selection */
+          if (G_UNLIKELY (select))
+            {
+              /* select only the file in question */
+              (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->unselect_all) (standard_view);
+              (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->select_path) (standard_view, paths->data);
+            }
+
+          /* cleanup */
+          g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
+          g_list_free (paths);
+        }
+    }
+}
+
+
+
 static gboolean
 thunar_standard_view_delete_selected_files (ThunarStandardView *standard_view)
 {
diff --git a/thunar/thunar-view.c b/thunar/thunar-view.c
index b5e79a98c428a702c732ae6abd50e67fd75f99b1..df7bfb9c48dd880b0ed8810129bef7c2c960cd56 100644
--- a/thunar/thunar-view.c
+++ b/thunar/thunar-view.c
@@ -268,3 +268,58 @@ thunar_view_reload (ThunarView *view)
 
 
 
+/**
+ * thunar_view_get_visible_range:
+ * @view       : a #ThunarView instance.
+ * @start_file : return location for start of region, or %NULL.
+ * @end_file   : return location for end of region, or %NULL.
+ *
+ * Sets @start_file and @end_file to be the first and last visible
+ * #ThunarFile.
+ *
+ * The files should be freed with g_object_unref() when no
+ * longer needed.
+ *
+ * Return value: %TRUE if valid files were placed in @start_file
+ *               and @end_file.
+ **/
+gboolean
+thunar_view_get_visible_range (ThunarView  *view,
+                               ThunarFile **start_file,
+                               ThunarFile **end_file)
+{
+  g_return_val_if_fail (THUNAR_IS_VIEW (view), FALSE);
+  return (*THUNAR_VIEW_GET_IFACE (view)->get_visible_range) (view, start_file, end_file);
+}
+
+
+
+/**
+ * thunar_view_scroll_to_file:
+ * @view      : a #ThunarView instance.
+ * @file      : the #ThunarFile to scroll to.
+ * @select    : %TRUE to also select the @file in the @view.
+ * @use_align : whether to use alignment arguments.
+ * @row_align : the vertical alignment.
+ * @col_align : the horizontal alignment.
+ *
+ * Tells @view to scroll to the @file. If @view is currently
+ * loading, it'll remember to scroll to @file later when
+ * the contents are loaded.
+ **/
+void
+thunar_view_scroll_to_file (ThunarView *view,
+                            ThunarFile *file,
+                            gboolean    select,
+                            gboolean    use_align,
+                            gfloat      row_align,
+                            gfloat      col_align)
+{
+  g_return_if_fail (THUNAR_IS_VIEW (view));
+  g_return_if_fail (THUNAR_IS_FILE (file));
+  g_return_if_fail (row_align >= 0.0f && row_align <= 1.0f);
+  g_return_if_fail (col_align >= 0.0f && col_align <= 1.0f);
+  (*THUNAR_VIEW_GET_IFACE (view)->scroll_to_file) (view, file, select, use_align, row_align, col_align);
+}
+
+
diff --git a/thunar/thunar-view.h b/thunar/thunar-view.h
index 8783752b1c1a3ddba425a78cf54d7a149f1c4701..63b7232f3f6617b96dab2a2dc81435a05e77e04c 100644
--- a/thunar/thunar-view.h
+++ b/thunar/thunar-view.h
@@ -52,6 +52,17 @@ struct _ThunarViewIface
   void            (*reset_zoom_level)   (ThunarView     *view);
 
   void            (*reload)             (ThunarView     *view);
+
+  gboolean        (*get_visible_range)  (ThunarView     *view,
+                                         ThunarFile    **start_file,
+                                         ThunarFile    **end_file);
+
+  void            (*scroll_to_file)     (ThunarView     *view,
+                                         ThunarFile     *file,
+                                         gboolean        select,
+                                         gboolean        use_align,
+                                         gfloat          row_align,
+                                         gfloat          col_align);
 };
 
 GType           thunar_view_get_type            (void) G_GNUC_CONST;
@@ -70,6 +81,17 @@ void            thunar_view_reset_zoom_level    (ThunarView     *view);
 
 void            thunar_view_reload              (ThunarView     *view);
 
+gboolean        thunar_view_get_visible_range   (ThunarView     *view,
+                                                 ThunarFile    **start_file,
+                                                 ThunarFile    **end_file);
+
+void            thunar_view_scroll_to_file      (ThunarView     *view,
+                                                 ThunarFile     *file,
+                                                 gboolean        select,
+                                                 gboolean        use_align,
+                                                 gfloat          row_align,
+                                                 gfloat          col_align);
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_VIEW_H__ */
diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c
index 9ee04bde4c85f821e5645a63296d87a271652022..590e9a22ff41851fbe7c95cdbdd6619d0ca69d19 100644
--- a/thunar/thunar-window.c
+++ b/thunar/thunar-window.c
@@ -212,6 +212,9 @@ struct _ThunarWindow
 
   /* support to remember window geometry */
   gint                    save_geometry_timer_id;
+
+  /* scroll_to_file support */
+  GHashTable             *scroll_to_files;
 };
 
 
@@ -447,6 +450,9 @@ thunar_window_init (ThunarWindow *window)
   /* grab a reference on the preferences */
   window->preferences = thunar_preferences_get ();
 
+  /* allocate the scroll_to_files mapping */
+  window->scroll_to_files = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_object_unref);
+
   /* allocate a closure for the menu_item_selected() callback */
   window->menu_item_selected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_selected), G_OBJECT (window));
   g_closure_ref (window->menu_item_selected_closure);
@@ -683,6 +689,9 @@ thunar_window_finalize (GObject *object)
   /* release the preferences reference */
   g_object_unref (G_OBJECT (window->preferences));
 
+  /* release the scroll_to_files hash table */
+  g_hash_table_destroy (window->scroll_to_files);
+
   (*G_OBJECT_CLASS (thunar_window_parent_class)->finalize) (object);
 }
 
@@ -979,11 +988,24 @@ thunar_window_action_open_new_window (GtkAction    *action,
                                       ThunarWindow *window)
 {
   ThunarApplication *application;
+  ThunarFile        *start_file;
+  GtkWidget         *new_window;
 
+  /* popup a new window */
   application = thunar_application_get ();
-  thunar_application_open_window (application, window->current_directory,
-                                  gtk_widget_get_screen (GTK_WIDGET (window)));
+  new_window = thunar_application_open_window (application, window->current_directory,
+                                               gtk_widget_get_screen (GTK_WIDGET (window)));
   g_object_unref (G_OBJECT (application));
+
+  /* determine the first visible file in the current window */
+  if (window->view != NULL && thunar_view_get_visible_range (THUNAR_VIEW (window->view), &start_file, NULL))
+    {
+      /* scroll the new window to the same file */
+      thunar_window_scroll_to_file (THUNAR_WINDOW (new_window), start_file, FALSE, TRUE, 0.0f, 0.0f);
+
+      /* release the file reference */
+      g_object_unref (G_OBJECT (start_file));
+    }
 }
 
 
@@ -1279,11 +1301,16 @@ thunar_window_action_view_changed (GtkRadioAction *action,
                                    GtkRadioAction *current,
                                    ThunarWindow   *window)
 {
-  GType type;
+  ThunarFile *file = NULL;
+  GType       type;
 
   /* drop the previous view (if any) */
   if (G_LIKELY (window->view != NULL))
     {
+      /* get first visible file in the previous view */
+      if (!thunar_view_get_visible_range (THUNAR_VIEW (window->view), &file, NULL))
+        file = NULL;
+
       /* destroy and disconnect the previous view */
       gtk_widget_destroy (window->view);
 
@@ -1322,6 +1349,10 @@ thunar_window_action_view_changed (GtkRadioAction *action,
       /* connect to the statusbar (if any) */
       if (G_LIKELY (window->statusbar != NULL))
         exo_binding_new (G_OBJECT (window->view), "statusbar-text", G_OBJECT (window->statusbar), "text");
+
+      /* scroll to the previously visible file in the old view */
+      if (G_UNLIKELY (file != NULL))
+        thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, FALSE, TRUE, 0.0f, 0.0f);
     }
   else
     {
@@ -1331,6 +1362,10 @@ thunar_window_action_view_changed (GtkRadioAction *action,
 
   /* remember the setting */
   g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (type), NULL);
+
+  /* release the file reference */
+  if (G_UNLIKELY (file != NULL))
+    g_object_unref (G_OBJECT (file));
 }
 
 
@@ -1837,6 +1872,8 @@ void
 thunar_window_set_current_directory (ThunarWindow *window,
                                      ThunarFile   *current_directory)
 {
+  ThunarFile *file;
+
   g_return_if_fail (THUNAR_IS_WINDOW (window));
   g_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
 
@@ -1847,6 +1884,13 @@ thunar_window_set_current_directory (ThunarWindow *window,
   /* disconnect from the previously active directory */
   if (G_LIKELY (window->current_directory != NULL))
     {
+      /* determine the fist visible file in the previous directory */
+      if (window->view != NULL && thunar_view_get_visible_range (THUNAR_VIEW (window->view), &file, NULL))
+        {
+          /* add the file to our internal mapping of directories to scroll files */
+          g_hash_table_replace (window->scroll_to_files, g_object_ref (G_OBJECT (window->current_directory)), file);
+        }
+
       g_signal_handlers_disconnect_by_func (G_OBJECT (window->current_directory), thunar_window_current_directory_changed, window);
       g_object_unref (G_OBJECT (window->current_directory));
     }
@@ -1876,6 +1920,15 @@ thunar_window_set_current_directory (ThunarWindow *window,
    * state already while the folder view is loading.
    */
   g_object_notify (G_OBJECT (window), "current-directory");
+
+  /* check if we have a valid current directory */
+  if (G_LIKELY (window->current_directory != NULL))
+    {
+      /* check if we have a scroll_to_file for the new directory and scroll to the file */
+      file = g_hash_table_lookup (window->scroll_to_files, window->current_directory);
+      if (G_LIKELY (file != NULL))
+        thunar_window_scroll_to_file (window, file, FALSE, TRUE, 0.0f, 0.0f);
+    }
 }
 
 
@@ -1927,3 +1980,33 @@ thunar_window_set_zoom_level (ThunarWindow   *window,
 }
 
 
+
+/**
+ * thunar_window_scroll_to_file:
+ * @window    : a #ThunarWindow instance.
+ * @file      : a #ThunarFile.
+ * @select    : if %TRUE the @file will also be selected.
+ * @use_align : %TRUE to use the alignment arguments.
+ * @row_align : the vertical alignment.
+ * @col_align : the horizontal alignment.
+ *
+ * Tells the @window to scroll to the @file
+ * in the current view.
+ **/
+void
+thunar_window_scroll_to_file (ThunarWindow *window,
+                              ThunarFile   *file,
+                              gboolean      select,
+                              gboolean      use_align,
+                              gfloat        row_align,
+                              gfloat        col_align)
+{
+  g_return_if_fail (THUNAR_IS_WINDOW (window));
+  g_return_if_fail (THUNAR_IS_FILE (file));
+
+  /* verify that we have a valid view */
+  if (G_LIKELY (window->view != NULL))
+    thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, select, use_align, row_align, col_align);
+}
+
+
diff --git a/thunar/thunar-window.h b/thunar/thunar-window.h
index 9355942b0929826d155286d095462864dd6505e6..04c61a05927b59c5f5d670fb78eb8dac1be54b25 100644
--- a/thunar/thunar-window.h
+++ b/thunar/thunar-window.h
@@ -47,6 +47,13 @@ ThunarZoomLevel thunar_window_get_zoom_level        (ThunarWindow   *window);
 void            thunar_window_set_zoom_level        (ThunarWindow   *window,
                                                      ThunarZoomLevel zoom_level);
 
+void            thunar_window_scroll_to_file        (ThunarWindow   *window,
+                                                     ThunarFile     *file,
+                                                     gboolean        select,
+                                                     gboolean        use_align,
+                                                     gfloat          row_align,
+                                                     gfloat          col_align);
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_WINDOW_H__ */