[patch] scrolling behavior



   This patch fixes a bug in scrolling behavior. In general, to
reproduce the bug, scroll to the bottom of a large scrolled area, then
cause the scrolled area to resize to a smaller area. Two examples have
been reported: first, in the file selector, when clicking on a
directory that has fewer subdirectories, and also in the layers
dialog, when the number of layers is reduced.

   This patch changes the scrolling behavior, and thus might possibly
break some things. In particular, doing a size_allocate on a viewport
can change the value of an adjustment, which is something the previous
scrolling code was very careful to avoid. I _think_ the new behavior
is correct, but it's impossible to be sure without some field testing.

Raph

===================================================================
RCS file: gtkviewport.c,v
retrieving revision 1.1
diff -u -r1.1 gtkviewport.c
--- gtkviewport.c	1997/11/11 06:03:07	1.1
+++ gtkviewport.c	1997/11/11 06:41:09
@@ -448,6 +448,7 @@
   GtkViewport *viewport;
   GtkBin *bin;
   GtkAllocation child_allocation;
+  gint hval, vval;
 
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_VIEWPORT (widget));
@@ -486,19 +487,26 @@
   viewport->vadjustment->page_increment = viewport->vadjustment->page_size / 2;
   viewport->vadjustment->step_increment = 10;
 
+  hval = viewport->hadjustment->value;
+  vval = viewport->vadjustment->value;
+
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     {
       viewport->hadjustment->lower = 0;
-      viewport->hadjustment->upper = MAX (child_allocation.width + 
-					  (viewport->hadjustment->value - 
-					   viewport->hadjustment->lower), 
-					  bin->child->requisition.width);
+      viewport->hadjustment->upper = MAX (bin->child->requisition.width,
+					  child_allocation.width);
+
+      hval = CLAMP (hval, 0,
+		    viewport->hadjustment->upper -
+		    viewport->hadjustment->page_size);
 
       viewport->vadjustment->lower = 0;
-      viewport->vadjustment->upper = MAX (child_allocation.height + 
-					  (viewport->vadjustment->value - 
-					   viewport->vadjustment->lower),
-					  bin->child->requisition.height);
+      viewport->vadjustment->upper = MAX (bin->child->requisition.height,
+					  child_allocation.height);
+
+      vval = CLAMP (vval, 0,
+		    viewport->vadjustment->upper -
+		    viewport->vadjustment->page_size);
     }
 
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
@@ -523,6 +531,16 @@
 
   gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "changed");
   gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "changed");
+  if (viewport->hadjustment->value != hval)
+    {
+      viewport->hadjustment->value = hval;
+      gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "value_changed");
+    }
+  if (viewport->vadjustment->value != vval)
+    {
+      viewport->vadjustment->value = vval;
+      gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "value_changed");
+    }
 }
 
 static gint



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]