LiNuCe wrote:
>>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.
> 
> Ok, I'm not enough used to use SVN for now so I'm going to test it
> when the next exo snapshot > r20117 will be available on the Xfce
> snapshot download area (I use these snapshot to daily build Thunar &
> exo). Thanks !

Attached is a patch for libexo to the latest version.

Benedikt
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20116)
+++ ChangeLog	(revision 20120)
@@ -1,5 +1,10 @@
 2006-02-27	Benedikt Meurer <[EMAIL PROTECTED]>
 
+	* exo/exo-icon-view.c: Handle scrolling to a path before the view
+	  is realized/layouted.
+
+2006-02-27	Benedikt Meurer <[EMAIL PROTECTED]>
+
 	* exo/exo-icon-view.c, exo/exo-tree-view.c: Also drop the prelit
 	  timeout defines.
 	* exo/exo-icon-view.c(exo_icon_view_button_press_event): Do not alter
Index: exo/exo-icon-view.c
===================================================================
--- exo/exo-icon-view.c	(revision 20116)
+++ exo/exo-icon-view.c	(revision 20120)
@@ -483,15 +483,22 @@
   GtkTreeRowReference *dest_item;
   ExoIconViewDropPosition dest_pos;
 
-  guint source_set : 1;
-  guint dest_set : 1;
-  guint reorderable : 1;
-  guint single_click : 1;
-  guint empty_view_drop :1;
+  /* delayed scrolling */
+  GtkTreeRowReference          *scroll_to_path;
+  gfloat                        scroll_to_row_align;
+  gfloat                        scroll_to_col_align;
+  guint                         scroll_to_use_align : 1;
 
-  guint ctrl_pressed : 1;
-  guint shift_pressed : 1;
+  /* misc flags */
+  guint                         source_set : 1;
+  guint                         dest_set : 1;
+  guint                         reorderable : 1;
+  guint                         single_click : 1;
+  guint                         empty_view_drop :1;
 
+  guint                         ctrl_pressed : 1;
+  guint                         shift_pressed : 1;
+
   /* Interactive search support */
   guint                         enable_search : 1;
   guint                         search_imcontext_changed : 1;
@@ -1149,6 +1156,13 @@
   /* reset the drag dest item */
   exo_icon_view_set_drag_dest_item (icon_view, NULL, EXO_ICON_VIEW_NO_DROP);
 
+  /* drop the scroll to path (if any) */
+  if (G_UNLIKELY (icon_view->priv->scroll_to_path != NULL))
+    {
+      gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
+      icon_view->priv->scroll_to_path = NULL;
+    }
+
   /* reset the model (also stops any active editing) */
   exo_icon_view_set_model (icon_view, NULL);
 
@@ -1478,6 +1492,7 @@
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
   ExoIconView   *icon_view = EXO_ICON_VIEW (widget);
+  GtkTreePath   *path;
 
   /* apply the new size allocation */
   widget->allocation = *allocation;
@@ -1503,7 +1518,6 @@
   hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
   if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
     gtk_adjustment_set_value (hadjustment, MAX (0, hadjustment->upper - hadjustment->page_size));
-  gtk_adjustment_changed (hadjustment);
 
   /* update the vertical scroll adjustment accordingly */
   vadjustment = icon_view->priv->vadjustment;
@@ -1514,7 +1528,31 @@
   vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
   if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
     gtk_adjustment_set_value (vadjustment, MAX (0, vadjustment->upper - vadjustment->page_size));
-  gtk_adjustment_changed (vadjustment);
+
+  /* scroll to the previously remember path (will emit "changed" for the adjustments) */
+  if (GTK_WIDGET_REALIZED (widget) && icon_view->priv->scroll_to_path != NULL
+      && gtk_tree_row_reference_valid (icon_view->priv->scroll_to_path))
+    {
+      /* grab the path from the reference and invalidate the reference */
+      path = gtk_tree_row_reference_get_path (icon_view->priv->scroll_to_path);
+      gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
+      icon_view->priv->scroll_to_path = NULL;
+
+      /* try to scroll again */
+      exo_icon_view_scroll_to_path (icon_view, path,
+                                    icon_view->priv->scroll_to_use_align,
+                                    icon_view->priv->scroll_to_row_align,
+                                    icon_view->priv->scroll_to_col_align);
+
+      /* release the path */
+      gtk_tree_path_free (path);
+    }
+  else
+    {
+      /* we need to emit "changed" ourselves */
+      gtk_adjustment_changed (hadjustment);
+      gtk_adjustment_changed (vadjustment);
+    }
 }
 
 
@@ -4813,6 +4851,15 @@
         gdk_window_set_cursor (icon_view->priv->bin_window, NULL);
     }
 
+  /* be sure to drop any previous scroll_to_path reference,
+   * as it points to the old (no longer valid) model.
+   */
+  if (G_UNLIKELY (icon_view->priv->scroll_to_path != NULL))
+    {
+      gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
+      icon_view->priv->scroll_to_path = NULL;
+    }
+
   /* activate the new model */
   icon_view->priv->model = model;
 
@@ -5468,9 +5515,12 @@
       info = NULL;
     }
 
+  /* place the cursor on the item */
   exo_icon_view_set_cursor_item (icon_view, item, cell_pos);
-  exo_icon_view_scroll_to_item (icon_view, item);
 
+  /* scroll to the item (maybe delayed) */
+  exo_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0f, 0.0f);
+
   if (start_editing)
     exo_icon_view_start_editing (icon_view, item, info, NULL);
 }
@@ -5515,43 +5565,59 @@
   g_return_if_fail (row_align >= 0.0 && row_align <= 1.0);
   g_return_if_fail (col_align >= 0.0 && col_align <= 1.0);
   
-  item = g_list_nth_data (icon_view->priv->items, gtk_tree_path_get_indices(path)[0]);
-  if (G_UNLIKELY (item == NULL))
-    return;
+  /* Delay scrolling if either not realized or pending layout() */
+  if (!GTK_WIDGET_REALIZED (icon_view) || icon_view->priv->layout_idle_id >= 0)
+    {
+      /* release the previous scroll_to_path reference */
+      if (G_UNLIKELY (icon_view->priv->scroll_to_path != NULL))
+        gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
 
-  if (use_align)
+      /* remember a reference for the new path and settings */
+      icon_view->priv->scroll_to_path = gtk_tree_row_reference_new_proxy (G_OBJECT (icon_view), icon_view->priv->model, path);
+      icon_view->priv->scroll_to_use_align = use_align;
+      icon_view->priv->scroll_to_row_align = row_align;
+      icon_view->priv->scroll_to_col_align = col_align;
+    }
+  else
     {
-      gint x, y;
-      gint focus_width;
-      gfloat offset, value;
+      item = g_list_nth_data (icon_view->priv->items, gtk_tree_path_get_indices(path)[0]);
+      if (G_UNLIKELY (item == NULL))
+        return;
 
-      gtk_widget_style_get (GTK_WIDGET (icon_view),
-                            "focus-line-width", &focus_width,
-                            NULL);
-      
-      gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
-      
-      offset =  y + item->area.y - focus_width - 
-        row_align * (GTK_WIDGET (icon_view)->allocation.height - item->area.height);
-      value = CLAMP (icon_view->priv->vadjustment->value + offset, 
-                     icon_view->priv->vadjustment->lower,
-                     icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
-      gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
+      if (use_align)
+        {
+          gint x, y;
+          gint focus_width;
+          gfloat offset, value;
 
-      offset = x + item->area.x - focus_width - 
-        col_align * (GTK_WIDGET (icon_view)->allocation.width - item->area.width);
-      value = CLAMP (icon_view->priv->hadjustment->value + offset, 
-                     icon_view->priv->hadjustment->lower,
-                     icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
-      gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
+          gtk_widget_style_get (GTK_WIDGET (icon_view),
+                                "focus-line-width", &focus_width,
+                                NULL);
+          
+          gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
+          
+          offset =  y + item->area.y - focus_width - 
+            row_align * (GTK_WIDGET (icon_view)->allocation.height - item->area.height);
+          value = CLAMP (icon_view->priv->vadjustment->value + offset, 
+                         icon_view->priv->vadjustment->lower,
+                         icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
+          gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
 
-      gtk_adjustment_changed (icon_view->priv->hadjustment);
-      gtk_adjustment_changed (icon_view->priv->vadjustment);
+          offset = x + item->area.x - focus_width - 
+            col_align * (GTK_WIDGET (icon_view)->allocation.width - item->area.width);
+          value = CLAMP (icon_view->priv->hadjustment->value + offset, 
+                         icon_view->priv->hadjustment->lower,
+                         icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
+          gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
+
+          gtk_adjustment_changed (icon_view->priv->hadjustment);
+          gtk_adjustment_changed (icon_view->priv->vadjustment);
+        }
+      else
+        {
+          exo_icon_view_scroll_to_item (icon_view, item);    
+        }
     }
-  else
-    {
-      exo_icon_view_scroll_to_item (icon_view, item);    
-    }
 }
 
 
_______________________________________________
Thunar-dev mailing list
Thunar-dev@xfce.org
http://foo-projects.org/mailman/listinfo/thunar-dev

Reply via email to