LiNuCe wrote: > Hello, > > Here is a small advice on improving navigation in Thunar. > > The problem (and how to reproduce it) > > I go to /usr/doc where there are hundred of folders, I scroll down > enough to be sure the folder I'm going to open is down enough to > be out of the Thunar view if I scroll to the top of it : > > http://linuce.free.fr/screenshots/thunar-dev/thunar-browsing.0.png > > Now, I select bsd-games-2.13/ and I open this folder : > > http://linuce.free.fr/screenshots/thunar-dev/thunar-browsing.1.png > > Then, I go back to its parent folder, /usr/doc, either with the > Back icon of the toolbar, or with the Parent icon of the toolbar > (or with the Alt+Up keyboard shortcut) : > > http://linuce.free.fr/screenshots/thunar-dev/thunar-browsing.2.png > > As you can see on this screenshot, the Thunar view does not show > the bsd-games-2.13/ folder from where I come from. > > Expected results > > An expected result would be the Thunar view to select the > bsd-games-2.13/ folder when going back from bsd-games-2.13/ > to /usr/doc (or at least to scroll the view in order to show it) : > > http://linuce.free.fr/screenshots/thunar-dev/thunar-browsing.3.png
Please try the attached patch (requires latest libexo, r20117). It should do the trick. It's a bit different to the way it's done in Nautilus tho. In Nautilus the scroll offset is associated with the forward/back-history, which is IMHO not very useful in the context of Thunar. Benedikt
Index: thunar/thunar-icon-view.c =================================================================== --- thunar/thunar-icon-view.c (revision 20106) +++ thunar/thunar-icon-view.c (working copy) @@ -59,10 +59,16 @@ GtkTreePath *path, gboolean start_editing); static void thunar_icon_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); static GtkTreePath *thunar_icon_view_get_path_at_pos (ThunarStandardView *standard_view, gint x, gint y); +static gboolean thunar_icon_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); static void thunar_icon_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path); static GtkAction *thunar_icon_view_gesture_action (ThunarIconView *icon_view); @@ -200,6 +206,7 @@ thunarstandard_view_class->set_cursor = thunar_icon_view_set_cursor; thunarstandard_view_class->scroll_to_path = thunar_icon_view_scroll_to_path; thunarstandard_view_class->get_path_at_pos = thunar_icon_view_get_path_at_pos; + thunarstandard_view_class->get_visible_range = thunar_icon_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_icon_view_highlight_path; thunarstandard_view_class->zoom_level_property_name = "last-icon-view-zoom-level"; @@ -423,10 +430,13 @@ static void thunar_icon_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path) + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align) { g_return_if_fail (THUNAR_IS_ICON_VIEW (standard_view)); - exo_icon_view_scroll_to_path (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), path, FALSE, 0.0f, 0.0f); + exo_icon_view_scroll_to_path (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), path, use_align, row_align, col_align); } @@ -442,6 +452,17 @@ +static gboolean +thunar_icon_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path) +{ + g_return_val_if_fail (THUNAR_IS_ICON_VIEW (standard_view), FALSE); + return exo_icon_view_get_visible_range (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), start_path, end_path); +} + + + static void thunar_icon_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path) Index: thunar/thunar-standard-view.c =================================================================== --- thunar/thunar-standard-view.c (revision 20114) +++ thunar/thunar-standard-view.c (working copy) @@ -113,6 +113,8 @@ static void thunar_standard_view_set_current_directory (ThunarNavigator *navigator, ThunarFile *current_directory); static gboolean thunar_standard_view_get_loading (ThunarView *view); +static void thunar_standard_view_set_loading (ThunarStandardView *standard_view, + gboolean loading); static const gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); static gboolean thunar_standard_view_get_show_hidden (ThunarView *view); static void thunar_standard_view_set_show_hidden (ThunarView *view, @@ -276,6 +278,9 @@ * new files are created by a ThunarVfsJob associated with this view */ GClosure *new_files_closure; + + /* scroll offsets (-> GtkTreePath indices) per VFS path */ + GHashTable *scroll_offsets; }; @@ -513,6 +518,10 @@ 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 (); @@ -726,6 +735,9 @@ /* 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); @@ -785,7 +797,6 @@ GParamSpec *pspec) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (object); - gboolean loading; switch (prop_id) { @@ -794,14 +805,9 @@ break; case PROP_LOADING: - loading = g_value_get_boolean (value); - if (G_LIKELY (loading != standard_view->loading)) - { - standard_view->loading = loading; - g_object_notify (object, "loading"); - g_object_notify (object, "statusbar-text"); - } + thunar_standard_view_set_loading (standard_view, g_value_get_boolean (value)); break; + break; case PROP_SELECTED_FILES: thunar_component_set_selected_files (THUNAR_COMPONENT (object), g_value_get_boxed (value)); @@ -973,7 +979,7 @@ } /* scroll to the first path (previously determined) */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, first_path); + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, first_path, FALSE, 0.0f, 0.0f); /* release the tree paths */ g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL); @@ -1084,10 +1090,34 @@ { 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); @@ -1134,6 +1164,49 @@ +static void +thunar_standard_view_set_loading (ThunarStandardView *standard_view, + gboolean loading) +{ + GtkTreePath *path; + ThunarFile *file; + gint offset; + + loading = !!loading; + + /* check if we're already in that state */ + if (G_UNLIKELY (standard_view->loading == loading)) + return; + + /* apply the new state */ + standard_view->loading = loading; + + /* check if this state change was due to a "loading complete" event */ + if (G_LIKELY (!loading)) + { + /* 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); + } + } + } + + /* notify listeners */ + g_object_notify (G_OBJECT (standard_view), "loading"); + g_object_notify (G_OBJECT (standard_view), "statusbar-text"); +} + + + static const gchar* thunar_standard_view_get_statusbar_text (ThunarView *view) { @@ -2123,7 +2196,7 @@ if (G_LIKELY (path_list != NULL)) { /* place the cursor on the file and scroll the new position */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path_list->data); + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path_list->data, FALSE, 0.0f, 0.0f); /* update the selection, so we get updated actions, statusbar, * etc. with the new file name and probably new mime type. Index: thunar/thunar-standard-view.h =================================================================== --- thunar/thunar-standard-view.h (revision 20106) +++ thunar/thunar-standard-view.h (working copy) @@ -78,7 +78,10 @@ * scroll the view to the given path. */ void (*scroll_to_path) (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); /* Returns the path at the given position or NULL if no item/row * is located at that coordinates. The path is freed by the caller. @@ -87,6 +90,11 @@ gint x, gint y); + /* Returns the visible range */ + gboolean (*get_visible_range) (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); + /* Sets the item/row that is highlighted for feedback. NULL is * passed for path to disable the highlighting. */ Index: thunar/thunar-details-view.c =================================================================== --- thunar/thunar-details-view.c (revision 20106) +++ thunar/thunar-details-view.c (working copy) @@ -40,10 +40,16 @@ GtkTreePath *path, gboolean start_editing); static void thunar_details_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); static GtkTreePath *thunar_details_view_get_path_at_pos (ThunarStandardView *standard_view, gint x, gint y); +static gboolean thunar_details_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); static void thunar_details_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path); static void thunar_details_view_notify_model (GtkTreeView *tree_view, @@ -128,6 +134,7 @@ thunarstandard_view_class->set_cursor = thunar_details_view_set_cursor; thunarstandard_view_class->scroll_to_path = thunar_details_view_scroll_to_path; thunarstandard_view_class->get_path_at_pos = thunar_details_view_get_path_at_pos; + thunarstandard_view_class->get_visible_range = thunar_details_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_details_view_highlight_path; thunarstandard_view_class->zoom_level_property_name = "last-details-view-zoom-level"; } @@ -349,7 +356,10 @@ static void thunar_details_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path) + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align) { GtkTreeViewColumn *column; @@ -357,7 +367,7 @@ /* tell the tree view to scroll to the given row */ column = gtk_tree_view_get_column (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), 0); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), path, column, FALSE, 0.0f, 0.0f); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), path, column, use_align, row_align, col_align); } @@ -379,6 +389,22 @@ +static gboolean +thunar_details_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path) +{ + g_return_val_if_fail (THUNAR_IS_DETAILS_VIEW (standard_view), FALSE); + +#if GTK_CHECK_VERSION(2,8,0) + return gtk_tree_view_get_visible_range (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), start_path, end_path); +#else + return FALSE; +#endif +} + + + static void thunar_details_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path)
_______________________________________________ Thunar-dev mailing list Thunar-dev@xfce.org http://foo-projects.org/mailman/listinfo/thunar-dev