Index: gtk/gtkrange.c
===================================================================
--- gtk/gtkrange.c	(revision 19932)
+++ gtk/gtkrange.c	(arbetskopia)
@@ -1161,6 +1161,18 @@
     return range->inverted;
 }
 
+/**
+ * can_be_smooth:
+ *
+ * Returns %TRUE if the @range can be smooth scrolled.
+ **/
+static gboolean
+can_be_smooth (GtkRange *range)
+{
+  return range->round_digits < 0 &&
+    range->update_policy == GTK_UPDATE_CONTINUOUS;
+}
+
 static void
 gtk_range_destroy (GtkObject *object)
 {
@@ -2090,57 +2102,57 @@
   return FALSE;
 }
 
-/**
- * _gtk_range_get_wheel_delta:
- * @range: a #GtkRange
- * @direction: A #GdkScrollDirection
- * 
- * Returns a good step value for the mouse wheel.
- * 
- * Return value: A good step value for the mouse wheel. 
- * 
- * Since: 2.4
- **/
-gdouble
-_gtk_range_get_wheel_delta (GtkRange           *range,
-			    GdkScrollDirection  direction)
-{
-  GtkAdjustment *adj = range->adjustment;
-  gdouble delta;
-
-  if (GTK_IS_SCROLLBAR (range))
-    delta = pow (adj->page_size, 2.0 / 3.0);
-  else
-    delta = adj->step_increment * 2;
-  
-  if (direction == GDK_SCROLL_UP ||
-      direction == GDK_SCROLL_LEFT)
-    delta = - delta;
-  
-  if (range->inverted)
-    delta = - delta;
-
-  return delta;
-}
-      
 static gboolean
 gtk_range_scroll_event (GtkWidget      *widget,
 			GdkEventScroll *event)
 {
   GtkRange *range = GTK_RANGE (widget);
+  GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
+  GdkScrollDirection direction = event->direction;
 
-  if (GTK_WIDGET_REALIZED (range))
+  if (!GTK_WIDGET_REALIZED (range))
+    return TRUE;
+
+  if (direction == GDK_SCROLL_UP || direction == GDK_SCROLL_LEFT)
+    direction = GDK_SCROLL_UP;
+  else
+    direction = GDK_SCROLL_DOWN;
+
+  if (should_invert (range))
     {
-      GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
-      gdouble delta;
+      if (direction == GDK_SCROLL_UP)
+        direction = GDK_SCROLL_DOWN;
+      else
+        direction = GDK_SCROLL_UP;
+    }
+
+  if (can_be_smooth (range) && GTK_IS_SCROLLBAR (range))
+    {
+      if (direction == GDK_SCROLL_UP)
+        gtk_adjustment_wheel_up (adj);
+      else
+        gtk_adjustment_wheel_down (adj);
+
+      range->need_recalc = TRUE;
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+    }
+  else
+    {
+      gdouble increment;
       gboolean handled;
 
-      delta = _gtk_range_get_wheel_delta (range, event->direction);
+      if (GTK_IS_SCROLLBAR (widget))
+        increment = pow (adj->page_size, 2.0/3.0);
+      else
+        increment = 2 * adj->step_increment;
 
+      if (direction == GDK_SCROLL_UP)
+        increment = -increment;
+
       g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                     GTK_SCROLL_JUMP, adj->value + delta,
+                     GTK_SCROLL_JUMP, adj->value + increment,
                      &handled);
-      
+
       /* Policy DELAYED makes sense with scroll events,
        * but DISCONTINUOUS doesn't, so we update immediately
        * for DISCONTINUOUS
@@ -2148,7 +2160,7 @@
       if (range->update_policy == GTK_UPDATE_DISCONTINUOUS)
         gtk_range_update_value (range);
     }
-
+  
   return TRUE;
 }
 
@@ -2252,16 +2264,20 @@
 			      gpointer       data)
 {
   GtkRange *range = GTK_RANGE (data);
-  /* create a copy of the layout */
-  GtkRangeLayout layout = *range->layout;
+  GtkRangeLayout old_layout = *range->layout;
 
   range->need_recalc = TRUE;
-  gtk_range_calc_layout (range, range->adjustment->value);
-  
-  /* now check whether the layout changed  */
-  if (layout_changed (range->layout, &layout))
-    gtk_widget_queue_draw (GTK_WIDGET (range));
+  gtk_range_calc_layout (range, adjustment->value);
 
+  if (layout_changed (&old_layout, range->layout))
+    {
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+      
+      /* This is so we don't lag the widget being scrolled. */
+      if (GTK_WIDGET_REALIZED (range))
+        gdk_window_process_updates (GTK_WIDGET (range)->window, FALSE);
+    }
+
   /* Note that we don't round off to range->round_digits here.
    * that's because it's really broken to change a value
    * in response to a change signal on that value; round_digits
@@ -2326,73 +2342,97 @@
 static void
 step_back (GtkRange *range)
 {
-  gdouble newval;
-  gboolean handled;
-  
-  newval = range->adjustment->value - range->adjustment->step_increment;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                 GTK_SCROLL_STEP_BACKWARD, newval, &handled);
+  GtkAdjustment *adj = range->adjustment;
+
+  if (can_be_smooth (range))
+    {
+      gtk_adjustment_step_up (adj);
+      range->need_recalc = TRUE;
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+    }
+  else
+    {
+      gdouble newval;
+      gdouble handled;
+
+      newval = adj->value - adj->step_increment;
+      g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                     GTK_SCROLL_STEP_BACKWARD, newval, &handled);
+    }
 }
 
 static void
 step_forward (GtkRange *range)
 {
-  gdouble newval;
-  gboolean handled;
+  GtkAdjustment *adj = range->adjustment;
 
-  newval = range->adjustment->value + range->adjustment->step_increment;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                 GTK_SCROLL_STEP_FORWARD, newval, &handled);
+  if (can_be_smooth (range))
+    {
+      gtk_adjustment_step_down (adj);
+      range->need_recalc = TRUE;
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+    }
+  else
+    {
+      gdouble newval;
+      gboolean handled;
+
+      newval = adj->value + adj->step_increment;
+      g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                     GTK_SCROLL_STEP_FORWARD, newval, &handled);
+    }
 }
 
-
 static void
 page_back (GtkRange *range)
 {
-  gdouble newval;
-  gboolean handled;
+  GtkAdjustment *adj = range->adjustment;
 
-  newval = range->adjustment->value - range->adjustment->page_increment;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                 GTK_SCROLL_PAGE_BACKWARD, newval, &handled);
+  if (can_be_smooth (range))
+    {
+      gtk_adjustment_page_up (adj);
+      range->need_recalc = TRUE;
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+    }
+  else
+    {
+      gdouble newval;
+      gdouble handled;
+
+      newval = adj->value - adj->page_increment;
+      g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                     GTK_SCROLL_PAGE_BACKWARD, newval, &handled);
+    }
 }
 
 static void
 page_forward (GtkRange *range)
 {
-  gdouble newval;
-  gboolean handled;
+  GtkAdjustment *adj = range->adjustment;
 
-  newval = range->adjustment->value + range->adjustment->page_increment;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                 GTK_SCROLL_PAGE_FORWARD, newval, &handled);
-}
+  if (can_be_smooth (range))
+    {
+      gtk_adjustment_page_down (adj);
+      range->need_recalc = TRUE;
+      gtk_widget_queue_draw (GTK_WIDGET (range));
+    }
+  else
+    {
+      gdouble newval;
+      gdouble handled;
 
-static void
-scroll_begin (GtkRange *range)
-{
-  gboolean handled;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0,
-                 GTK_SCROLL_START, range->adjustment->lower,
-                 &handled);
+      newval = adj->value + adj->page_increment;
+      g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                     GTK_SCROLL_PAGE_FORWARD, newval, &handled);
+    }
 }
 
-static void
-scroll_end (GtkRange *range)
-{
-  gdouble newval;
-  gboolean handled;
-
-  newval = range->adjustment->upper - range->adjustment->page_size;
-  g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_END, newval,
-                 &handled);
-}
-
 static gboolean
 gtk_range_scroll (GtkRange     *range,
                   GtkScrollType scroll)
 {
   gdouble old_value = range->adjustment->value;
+  gboolean handled;
 
   switch (scroll)
     {
@@ -2469,11 +2509,30 @@
       break;
 
     case GTK_SCROLL_START:
-      scroll_begin (range);
+      if (can_be_smooth (range))
+        {
+          gtk_adjustment_home (range->adjustment);
+          range->need_recalc = TRUE;
+          gtk_widget_queue_draw (GTK_WIDGET (range));
+        }
+      else
+        g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                       GTK_SCROLL_JUMP, range->adjustment->lower, &handled);
       break;
 
     case GTK_SCROLL_END:
-      scroll_end (range);
+      if (can_be_smooth (range))
+        {
+          gtk_adjustment_end (range->adjustment);
+          range->need_recalc = TRUE;
+          gtk_widget_queue_draw (GTK_WIDGET (range));
+        }
+      else
+        g_signal_emit (range, signals[CHANGE_VALUE], 0,
+                       GTK_SCROLL_JUMP,
+                       range->adjustment->upper - range->adjustment->page_size,
+                       &handled);
+      
       break;
 
     case GTK_SCROLL_JUMP:
Index: gtk/gtkrange.h
===================================================================
--- gtk/gtkrange.h	(revision 19932)
+++ gtk/gtkrange.h	(arbetskopia)
@@ -170,10 +170,6 @@
                                                             gdouble        fill_level);
 gdouble            gtk_range_get_fill_level                (GtkRange      *range);
 
-gdouble            _gtk_range_get_wheel_delta              (GtkRange      *range,
-                                                            GdkScrollDirection direction);
-
-
 G_END_DECLS
 
 
Index: gtk/gtkadjustment.c
===================================================================
--- gtk/gtkadjustment.c	(revision 19932)
+++ gtk/gtkadjustment.c	(arbetskopia)
@@ -25,6 +25,7 @@
  */
 
 #include <config.h>
+#include <math.h>
 #include "gtkadjustment.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
@@ -49,6 +50,13 @@
   LAST_SIGNAL
 };
 
+typedef struct
+{
+  GTimer *timer;
+  gdouble start_value;
+  gdouble goal_value;
+  guint idle_id;
+} GtkAdjustmentPrivate;
 
 static void gtk_adjustment_get_property                (GObject      *object,
                                                         guint         prop_id,
@@ -217,6 +225,43 @@
 }
 
 static void
+gtk_adjustment_private_finalize (GtkAdjustmentPrivate *priv)
+{
+  if (priv->idle_id)
+    g_source_remove (priv->idle_id);
+  g_timer_destroy (priv->timer);
+  g_free (priv);
+}
+
+static GtkAdjustmentPrivate *
+gtk_adjustment_get_private (GtkAdjustment *adjustment)
+{
+  GtkAdjustmentPrivate *priv;
+  static GQuark priv_quark = 0;
+
+  if (!priv_quark)
+    priv_quark = g_quark_from_string ("gtk-adjustment-private");
+
+  priv = g_object_get_qdata (G_OBJECT (adjustment), priv_quark);
+
+  if (!priv)
+    {
+      priv = g_new0 (GtkAdjustmentPrivate, 1);
+
+      priv->timer = g_timer_new ();
+      priv->start_value = 0.0;
+      priv->goal_value = 0.0;
+      priv->idle_id = 0;
+
+      g_object_set_qdata_full (G_OBJECT (adjustment), priv_quark, priv,
+                               (GDestroyNotify)
+                               gtk_adjustment_private_finalize);
+    }
+  
+  return priv;
+}
+
+static void
 gtk_adjustment_get_property (GObject    *object,
                              guint       prop_id,
                              GValue     *value,
@@ -372,12 +417,26 @@
   g_signal_emit (adjustment, adjustment_signals[CHANGED], 0);
 }
 
+static void
+gtk_adjustment_value_changed_unchecked (GtkAdjustment *adjustment)
+{
+  g_signal_emit (adjustment, adjustment_signals[VALUE_CHANGED], 0);
+}
+
 void
 gtk_adjustment_value_changed (GtkAdjustment *adjustment)
 {
+  GtkAdjustmentPrivate *priv;
+  
   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
 
-  g_signal_emit (adjustment, adjustment_signals[VALUE_CHANGED], 0);
+  priv = gtk_adjustment_get_private (adjustment);
+  if (priv->idle_id)
+    {
+      g_source_remove (priv->idle_id);
+      priv->idle_id = 0;
+    }
+  gtk_adjustment_value_changed_unchecked (adjustment);
   g_object_notify (G_OBJECT (adjustment), "value");
 }
 
@@ -410,5 +469,171 @@
     gtk_adjustment_value_changed (adjustment);
 }
 
+static gboolean
+adjustment_update_idle (gpointer data)
+{
+  GtkAdjustment *adj = data;
+  GtkAdjustmentPrivate *priv = gtk_adjustment_get_private (adj);
+
+  gdouble new_value;
+  gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
+  gdouble update_time = 0.1;
+  
+  gdouble start_value = priv->start_value;
+  gdouble goal_value = priv->goal_value;
+  gdouble move_delta = goal_value - start_value;
+
+  GDK_THREADS_ENTER();
+
+  new_value = start_value + (elapsed / update_time) * move_delta;
+
+  /* Make sure new_value is between start_value and goal_value */
+  new_value = CLAMP (new_value,
+                     MIN (start_value, goal_value),
+                     MAX (start_value, goal_value));
+  new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
+
+  if (new_value != adj->value)
+    {
+      adj->value = new_value;
+      gtk_adjustment_value_changed_unchecked (adj);
+}
+
+  /* Scroll done? */
+  if (adj->value == goal_value ||
+      adj->value == adj->lower ||
+      adj->value == adj->upper - adj->page_size)
+    {
+      priv->idle_id = 0;
+      GDK_THREADS_LEAVE ();
+      return FALSE;
+    }
+
+  GDK_THREADS_LEAVE ();
+  return TRUE;
+}
+
+/**
+ * gtk_adjustment_change_value:
+ *
+ * Change the adjustments value by @delta. The change is done smoothly
+ * by starting a timer that changes the adjustment in steps.
+ **/
+static void
+gtk_adjustment_change_value (GtkAdjustment *adjustment,
+                             gdouble        delta)
+{
+  GtkAdjustmentPrivate *priv;
+
+  if (delta > -1 && delta < 1)
+    return;
+
+  priv = gtk_adjustment_get_private (adjustment);
+  priv->start_value = adjustment->value;
+  g_timer_reset (priv->timer);
+
+  if (!priv->idle_id)
+    {
+      priv->goal_value = adjustment->value + delta;
+      priv->idle_id = g_timeout_add_full (GDK_PRIORITY_REDRAW + 3,
+                                          20,
+                                          adjustment_update_idle,
+                                          adjustment,
+                                          NULL);
+    }
+  else
+    priv->goal_value = priv->goal_value + delta;
+}
+
+void
+gtk_adjustment_wheel_up (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment,
+                               -pow (adjustment->page_size, 2.0/3.0));
+}
+
+void
+gtk_adjustment_wheel_down (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment,
+                               pow (adjustment->page_size, 2.0/3.0));
+}
+
+void
+gtk_adjustment_step_up (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment, -adjustment->step_increment);
+}
+
+void
+gtk_adjustment_step_down (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment, adjustment->step_increment);
+}
+
+void
+gtk_adjustment_page_up (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment, -adjustment->page_increment);
+}
+
+void
+gtk_adjustment_page_down (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_change_value (adjustment, adjustment->page_increment);
+}
+
+void
+gtk_adjustment_home (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_goto_value (adjustment, 0.0);
+}
+
+void
+gtk_adjustment_end (GtkAdjustment *adjustment)
+{
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  gtk_adjustment_goto_value (adjustment,
+                             adjustment->upper - adjustment->page_size);
+}
+
+void
+gtk_adjustment_goto_value (GtkAdjustment *adjustment,
+                           gdouble        value)  
+{
+  GtkAdjustmentPrivate *priv;
+
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+  priv = gtk_adjustment_get_private (adjustment);
+
+  priv->start_value = adjustment->value;
+  priv->goal_value = value;
+  g_timer_reset (priv->timer);
+
+  if (!priv->idle_id)
+    priv->idle_id = g_timeout_add_full (GDK_PRIORITY_REDRAW + 3,
+                                        15,
+                                        adjustment_update_idle,
+                                        adjustment,
+                                        NULL);
+}
+
+
 #define __GTK_ADJUSTMENT_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkadjustment.h
===================================================================
--- gtk/gtkadjustment.h	(revision 19932)
+++ gtk/gtkadjustment.h	(arbetskopia)
@@ -86,6 +86,16 @@
 gdouble	   gtk_adjustment_get_value		(GtkAdjustment   *adjustment);
 void	   gtk_adjustment_set_value		(GtkAdjustment	 *adjustment,
 						 gdouble	  value);
+void       gtk_adjustment_wheel_up              (GtkAdjustment   *adjustment);
+void       gtk_adjustment_wheel_down            (GtkAdjustment   *adjustment);
+void       gtk_adjustment_step_up               (GtkAdjustment   *adjustment);
+void       gtk_adjustment_step_down             (GtkAdjustment   *adjustment);
+void       gtk_adjustment_page_up               (GtkAdjustment   *adjustment);
+void       gtk_adjustment_page_down             (GtkAdjustment   *adjustment);
+void       gtk_adjustment_home                  (GtkAdjustment   *adjustment);
+void       gtk_adjustment_end                   (GtkAdjustment   *adjustment);
+void       gtk_adjustment_goto_value            (GtkAdjustment *adjustment,
+                                                 gdouble        value);
 
 G_END_DECLS
 
Index: gtk/gtkscrolledwindow.c
===================================================================
--- gtk/gtkscrolledwindow.c	(revision 19932)
+++ gtk/gtkscrolledwindow.c	(arbetskopia)
@@ -1036,105 +1036,75 @@
 				  GtkScrollType      scroll,
 				  gboolean           horizontal)
 {
-  GtkAdjustment *adjustment = NULL;
-  
+  GtkAdjustment *hadj = NULL;
+  GtkAdjustment *vadj = NULL;
+
+  if (scrolled_window->hscrollbar)
+    hadj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
+  if (scrolled_window->vscrollbar)
+    vadj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
+
   switch (scroll)
     {
     case GTK_SCROLL_STEP_UP:
-      scroll = GTK_SCROLL_STEP_BACKWARD;
-      horizontal = FALSE;
+    case GTK_SCROLL_STEP_BACKWARD:
+      if (vadj)
+        gtk_adjustment_step_up (vadj);
       break;
+      
     case GTK_SCROLL_STEP_DOWN:
-      scroll = GTK_SCROLL_STEP_FORWARD;
-      horizontal = FALSE;
+    case GTK_SCROLL_STEP_FORWARD:
+      if (vadj)
+        gtk_adjustment_step_down (vadj);
       break;
+
     case GTK_SCROLL_STEP_LEFT:
-      scroll = GTK_SCROLL_STEP_BACKWARD;
-      horizontal = TRUE;
+      if (hadj)
+        gtk_adjustment_step_up (hadj);
       break;
+
     case GTK_SCROLL_STEP_RIGHT:
-      scroll = GTK_SCROLL_STEP_FORWARD;
-      horizontal = TRUE;
+      if (hadj)
+        gtk_adjustment_step_down (hadj);
       break;
+
     case GTK_SCROLL_PAGE_UP:
-      scroll = GTK_SCROLL_PAGE_BACKWARD;
-      horizontal = FALSE;
+    case GTK_SCROLL_PAGE_BACKWARD:
+      if (vadj)
+        gtk_adjustment_page_up (vadj);
       break;
+
     case GTK_SCROLL_PAGE_DOWN:
-      scroll = GTK_SCROLL_PAGE_FORWARD;
-      horizontal = FALSE;
+    case GTK_SCROLL_PAGE_FORWARD:
+      if (vadj)
+        gtk_adjustment_page_down (vadj);
       break;
+
     case GTK_SCROLL_PAGE_LEFT:
-      scroll = GTK_SCROLL_STEP_BACKWARD;
-      horizontal = TRUE;
+      if (hadj)
+        gtk_adjustment_page_up (hadj);
       break;
+
     case GTK_SCROLL_PAGE_RIGHT:
-      scroll = GTK_SCROLL_STEP_FORWARD;
-      horizontal = TRUE;
+      if (hadj)
+        gtk_adjustment_page_down (hadj);
       break;
-    case GTK_SCROLL_STEP_BACKWARD:
-    case GTK_SCROLL_STEP_FORWARD:
-    case GTK_SCROLL_PAGE_BACKWARD:
-    case GTK_SCROLL_PAGE_FORWARD:
+
     case GTK_SCROLL_START:
+      if (vadj)
+        gtk_adjustment_home (vadj);
+      break;
+
     case GTK_SCROLL_END:
+      if (vadj)
+        gtk_adjustment_end (vadj);
       break;
+
     default:
       g_warning ("Invalid scroll type %u for GtkScrolledWindow::scroll-child", scroll);
       return FALSE;
     }
 
-  if ((horizontal && (!scrolled_window->hscrollbar || !scrolled_window->hscrollbar_visible)) ||
-      (!horizontal && (!scrolled_window->vscrollbar || !scrolled_window->vscrollbar_visible)))
-    return FALSE;
-
-  if (horizontal)
-    {
-      if (scrolled_window->hscrollbar)
-	adjustment = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
-    }
-  else
-    {
-      if (scrolled_window->vscrollbar)
-	adjustment = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
-    }
-
-  if (adjustment)
-    {
-      gdouble value = adjustment->value;
-      
-      switch (scroll)
-	{
-	case GTK_SCROLL_STEP_FORWARD:
-	  value += adjustment->step_increment;
-	  break;
-	case GTK_SCROLL_STEP_BACKWARD:
-	  value -= adjustment->step_increment;
-	  break;
-	case GTK_SCROLL_PAGE_FORWARD:
-	  value += adjustment->page_increment;
-	  break;
-	case GTK_SCROLL_PAGE_BACKWARD:
-	  value -= adjustment->page_increment;
-	  break;
-	case GTK_SCROLL_START:
-	  value = adjustment->lower;
-	  break;
-	case GTK_SCROLL_END:
-	  value = adjustment->upper;
-	  break;
-	default:
-	  g_assert_not_reached ();
-	  break;
-	}
-
-      value = CLAMP (value, adjustment->lower, adjustment->upper - adjustment->page_size);
-      
-      gtk_adjustment_set_value (adjustment, value);
-
-      return TRUE;
-    }
-
   return FALSE;
 }
 
@@ -1513,14 +1483,17 @@
   if (range && GTK_WIDGET_VISIBLE (range))
     {
       GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
-      gdouble delta, new_value;
 
-      delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event->direction);
-
-      new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
+      if (event->direction == GDK_SCROLL_UP ||
+          event->direction == GDK_SCROLL_LEFT)
+        {
+          gtk_adjustment_wheel_up (adj);
+        }
+      else
+        {
+          gtk_adjustment_wheel_down (adj);
+        }
       
-      gtk_adjustment_set_value (adj, new_value);
-
       return TRUE;
     }
 
