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
[email protected]
http://foo-projects.org/mailman/listinfo/thunar-dev