diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gdk/gdk.symbols gtk+-2.6.7.patched/gdk/gdk.symbols
--- gtk+-2.6.7/gdk/gdk.symbols	2005-04-10 01:54:05.000000000 +0200
+++ gtk+-2.6.7.patched/gdk/gdk.symbols	2005-04-15 20:53:57.000000000 +0200
@@ -633,6 +633,7 @@
 gdk_window_get_toplevel
 gdk_window_get_toplevels
 gdk_window_get_update_area
+gdk_window_get_update_serial
 gdk_window_get_user_data
 gdk_window_get_window_type
 gdk_window_invalidate_maybe_recurse
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gdk/gdkwindow.c gtk+-2.6.7.patched/gdk/gdkwindow.c
--- gtk+-2.6.7/gdk/gdkwindow.c	2005-03-16 04:25:06.000000000 +0100
+++ gtk+-2.6.7.patched/gdk/gdkwindow.c	2005-04-15 20:39:21.000000000 +0200
@@ -2096,6 +2096,7 @@
 static GSList *update_windows = NULL;
 static guint update_idle = 0;
 static gboolean debug_updates = FALSE;
+static gint update_serial = 1;
 
 static gboolean
 gdk_window_update_idle (gpointer data)
@@ -2142,6 +2143,8 @@
 	  GdkRegion *window_region;
           gint width, height;
 
+	  ++update_serial;
+
           if (debug_updates)
             {
               /* Make sure we see the red invalid area before redrawing. */
@@ -2214,6 +2217,7 @@
 void
 gdk_window_process_all_updates (void)
 {
+  gboolean retval = FALSE;
   GSList *old_update_windows = update_windows;
   GSList *tmp_list = update_windows;
 
@@ -2223,6 +2227,9 @@
   update_windows = NULL;
   update_idle = 0;
 
+  if (old_update_windows)
+    retval = TRUE;
+  
   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
   
   while (tmp_list)
@@ -2447,6 +2454,12 @@
   gdk_region_destroy (visible_region);
 }
 
+gint
+gdk_window_get_update_serial (void)
+{
+  return update_serial;
+}
+
 static gboolean
 true_predicate (GdkWindow *window,
 		gpointer   user_data)
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gdk/gdkwindow.h gtk+-2.6.7.patched/gdk/gdkwindow.h
--- gtk+-2.6.7/gdk/gdkwindow.h	2004-07-11 15:26:57.000000000 +0200
+++ gtk+-2.6.7.patched/gdk/gdkwindow.h	2005-04-15 20:39:21.000000000 +0200
@@ -545,6 +545,7 @@
 void       gdk_window_freeze_updates      (GdkWindow    *window);
 void       gdk_window_thaw_updates        (GdkWindow    *window);
 
+gint       gdk_window_get_update_serial   (void);
 void       gdk_window_process_all_updates (void);
 void       gdk_window_process_updates     (GdkWindow    *window,
 					   gboolean      update_children);
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gtk/gtkadjustment.c gtk+-2.6.7.patched/gtk/gtkadjustment.c
--- gtk+-2.6.7/gtk/gtkadjustment.c	2005-03-20 07:25:27.000000000 +0100
+++ gtk+-2.6.7.patched/gtk/gtkadjustment.c	2005-04-15 21:02:58.000000000 +0200
@@ -25,6 +25,7 @@
  */
 
 #include <config.h>
+#include <math.h>
 #include "gtkadjustment.h"
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
@@ -48,9 +49,19 @@
 };
 
 
-static void gtk_adjustment_class_init (GtkAdjustmentClass *klass);
-static void gtk_adjustment_init       (GtkAdjustment      *adjustment);
+typedef struct _GtkAdjustmentPrivate GtkAdjustmentPrivate;
+struct _GtkAdjustmentPrivate
+{
+  GTimer *timer;
+  gdouble start_value;
+  gdouble goal_value;
+  guint idle_id;
+};
 
+static void                  gtk_adjustment_private_finalize   (GtkAdjustmentPrivate *private);
+static void                  gtk_adjustment_class_init         (GtkAdjustmentClass   *klass);
+static void                  gtk_adjustment_init               (GtkAdjustment        *adjustment);
+static GtkAdjustmentPrivate *gtk_adjustment_get_private        (GtkAdjustment        *adjustment);
 static void gtk_adjustment_get_property (GObject      *object,
                                          guint         prop_id,
                                          GValue       *value,
@@ -210,7 +221,6 @@
 							0.0, 
 							G_PARAM_READWRITE));
   
-
   adjustment_signals[CHANGED] =
     g_signal_new ("changed",
 		  G_OBJECT_CLASS_TYPE (class),
@@ -240,6 +250,44 @@
   adjustment->page_size = 0.0;
 }
 
+static GtkAdjustmentPrivate *
+gtk_adjustment_get_private (GtkAdjustment *adjustment)
+{
+  GtkAdjustmentPrivate *private;
+  static GQuark private_quark = 0;
+
+  if (!private_quark)
+    private_quark = g_quark_from_static_string ("gtk-adjustment-private");
+
+  private = g_object_get_qdata (G_OBJECT (adjustment), private_quark);
+
+  if (!private)
+    {
+      private = g_new0 (GtkAdjustmentPrivate, 1);
+
+      private->timer = g_timer_new ();
+      private->start_value = 0.0;
+      private->goal_value = 0.0;
+      private->idle_id = 0;
+      
+      g_object_set_qdata_full (G_OBJECT (adjustment), private_quark,
+			       private,
+                               (GDestroyNotify) gtk_adjustment_private_finalize);
+    }
+
+  return private;
+}
+
+static void
+gtk_adjustment_private_finalize (GtkAdjustmentPrivate *private)
+{
+  if (private->idle_id)
+    g_source_remove (private->idle_id);
+
+  g_timer_destroy (private->timer);
+  g_free (private);
+}
+
 static void
 gtk_adjustment_get_property (GObject *object, guint prop_id, GValue *value, 
 	                     GParamSpec *pspec)
@@ -384,12 +432,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");
 }
 
@@ -422,5 +484,173 @@
     gtk_adjustment_value_changed (adjustment);
 }
 
+#define UPDATE_TIME 0.1
+
+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);
+
+  GDK_THREADS_ENTER();
+  
+  new_value = priv->start_value +
+    (elapsed / UPDATE_TIME) * (priv->goal_value - priv->start_value);
+
+  /* make sure new_value is betweeen start_value and goal_value */
+  if (!((new_value >= priv->start_value && new_value <= priv->goal_value) ||
+	(new_value <= priv->start_value && new_value >= priv->goal_value)))
+    {
+      new_value = priv->goal_value;
+    }
+
+  if (new_value > adj->upper - adj->page_size)
+    new_value = adj->upper - adj->page_size;
+  
+  if (new_value < adj->lower)
+    new_value = adj->lower;
+
+  if (new_value != adj->value)
+    {
+      gint update_serial_before  = gdk_window_get_update_serial();
+      
+      adj->value = new_value;
+
+      gtk_adjustment_value_changed_unchecked (adj);
+
+      /* if anything was drawn during the signal emission, synchronize
+       * with the X server to avoid swamping it with updates
+       */
+      gdk_window_process_all_updates ();
+      if (update_serial_before != gdk_window_get_update_serial())
+	gdk_flush ();
+    }
+  
+  if (adj->value == priv->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;
+}
+
+static void
+gtk_adjustment_change_value (GtkAdjustment *adjustment,
+			     gdouble        delta)
+{
+  GtkAdjustmentPrivate *priv;
+
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+  
+  priv = gtk_adjustment_get_private (adjustment);
+
+  if (delta > -1 && delta < 1)
+    return;
+
+  priv->start_value = adjustment->value;
+  g_timer_reset (priv->timer);
+  
+  if (!priv->idle_id)
+    {
+      priv->idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW + 3, adjustment_update_idle, adjustment, NULL);
+      priv->goal_value = adjustment->value + delta;
+    }
+  else
+    priv->goal_value = priv->goal_value + delta;
+}
+
+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_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_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_idle_add_full (GDK_PRIORITY_REDRAW + 3, adjustment_update_idle, adjustment, NULL);
+}
+
 #define __GTK_ADJUSTMENT_C__
 #include "gtkaliasdef.c"
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gtk/gtkadjustment.h gtk+-2.6.7.patched/gtk/gtkadjustment.h
--- gtk+-2.6.7/gtk/gtkadjustment.h	2002-10-10 00:25:17.000000000 +0200
+++ gtk+-2.6.7.patched/gtk/gtkadjustment.h	2005-04-15 20:39:21.000000000 +0200
@@ -75,21 +75,32 @@
 };
 
 
-GType	   gtk_adjustment_get_type		(void) G_GNUC_CONST;
-GtkObject* gtk_adjustment_new			(gdouble	  value,
-						 gdouble	  lower,
-						 gdouble	  upper,
-						 gdouble	  step_increment,
-						 gdouble	  page_increment,
-						 gdouble	  page_size);
-void	   gtk_adjustment_changed		(GtkAdjustment	 *adjustment);
-void	   gtk_adjustment_value_changed		(GtkAdjustment	 *adjustment);
-void	   gtk_adjustment_clamp_page		(GtkAdjustment	 *adjustment,
-						 gdouble	  lower,
-						 gdouble	  upper);
-gdouble	   gtk_adjustment_get_value		(GtkAdjustment   *adjustment);
-void	   gtk_adjustment_set_value		(GtkAdjustment	 *adjustment,
-						 gdouble	  value);
+GType	   gtk_adjustment_get_type	(void) G_GNUC_CONST;
+GtkObject* gtk_adjustment_new           (gdouble        value,
+					 gdouble        lower,
+					 gdouble        upper,
+					 gdouble        step_increment,
+					 gdouble        page_increment,
+					 gdouble        page_size);
+void       gtk_adjustment_changed       (GtkAdjustment *adjustment);
+void       gtk_adjustment_value_changed (GtkAdjustment *adjustment);
+void       gtk_adjustment_clamp_page    (GtkAdjustment *adjustment,
+					 gdouble        lower,
+					 gdouble        upper);
+gdouble    gtk_adjustment_get_value     (GtkAdjustment *adjustment);
+void       gtk_adjustment_set_value     (GtkAdjustment *adjustment,
+					 gdouble        value);
+
+void       gtk_adjustment_goto_value    (GtkAdjustment *adjustment,
+					 gdouble        value);
+void	   gtk_adjustment_home		(GtkAdjustment *adjustment);
+void       gtk_adjustment_end           (GtkAdjustment *adjustment);
+void       gtk_adjustment_step_up       (GtkAdjustment *adjustment);
+void       gtk_adjustment_step_down     (GtkAdjustment *adjustment);
+void       gtk_adjustment_wheel_up      (GtkAdjustment *adjustment);
+void       gtk_adjustment_wheel_down    (GtkAdjustment *adjustment);
+void       gtk_adjustment_page_up       (GtkAdjustment *adjustment);
+void       gtk_adjustment_page_down     (GtkAdjustment *adjustment);
 
 #ifdef __cplusplus
 }
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gtk/gtkrange.h gtk+-2.6.7.patched/gtk/gtkrange.h
--- gtk+-2.6.7/gtk/gtkrange.h	2004-08-27 04:54:12.000000000 +0200
+++ gtk+-2.6.7.patched/gtk/gtkrange.h	2005-04-15 20:39:21.000000000 +0200
@@ -152,9 +152,6 @@
                                             gdouble        value);
 gdouble        gtk_range_get_value         (GtkRange      *range);
 
-gdouble	      _gtk_range_get_wheel_delta   (GtkRange           *range,
-					    GdkScrollDirection  direction);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gtk/gtkscrolledwindow.c gtk+-2.6.7.patched/gtk/gtkscrolledwindow.c
--- gtk+-2.6.7/gtk/gtkscrolledwindow.c	2005-04-07 07:09:32.000000000 +0200
+++ gtk+-2.6.7.patched/gtk/gtkscrolledwindow.c	2005-04-15 20:39:21.000000000 +0200
@@ -796,98 +796,65 @@
 				  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 %d for GtkSpinButton::change-value", scroll);
       return;
     }
-
-  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);
-    }
 }
 
 static void
@@ -1228,15 +1195,18 @@
 
   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);
+      GtkAdjustment *adjustment = GTK_RANGE (range)->adjustment;
+      
+      if (event->direction == GDK_SCROLL_UP ||
+	  event->direction == GDK_SCROLL_LEFT)
+ 	{
+	  gtk_adjustment_wheel_up (adjustment);
+ 	}
+      else
+ 	{
+	  gtk_adjustment_wheel_down (adjustment);
+ 	}
       
-      gtk_adjustment_set_value (adj, new_value);
-
       return TRUE;
     }
 
diff -uNr -x '*~' -x '*orig' -x '*rej' gtk+-2.6.7/gtk/gtk.symbols gtk+-2.6.7.patched/gtk/gtk.symbols
--- gtk+-2.6.7/gtk/gtk.symbols	2005-03-20 07:25:27.000000000 +0100
+++ gtk+-2.6.7.patched/gtk/gtk.symbols	2005-04-15 23:26:24.000000000 +0200
@@ -185,10 +185,19 @@
 #if IN_FILE(__GTK_ADJUSTMENT_C__)
 gtk_adjustment_changed
 gtk_adjustment_clamp_page
+gtk_adjustment_end
 gtk_adjustment_get_type G_GNUC_CONST
 gtk_adjustment_get_value
+gtk_adjustment_goto_value
+gtk_adjustment_home
 gtk_adjustment_new
+gtk_adjustment_page_down
+gtk_adjustment_page_up
 gtk_adjustment_set_value
+gtk_adjustment_step_down
+gtk_adjustment_step_up
+gtk_adjustment_wheel_down
+gtk_adjustment_wheel_up
 gtk_adjustment_value_changed
 #endif
 #endif
