diff -x '*.orig' -uNr gtk+-2.7.1/gdk/gdk.symbols gtk+-2.7.1.patched/gdk/gdk.symbols --- gtk+-2.7.1/gdk/gdk.symbols 2005-06-21 06:09:51.000000000 +0200 +++ gtk+-2.7.1.patched/gdk/gdk.symbols 2005-07-02 13:17:35.000000000 +0200 @@ -653,6 +653,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 -x '*.orig' -uNr gtk+-2.7.1/gdk/gdkwindow.c gtk+-2.7.1.patched/gdk/gdkwindow.c --- gtk+-2.7.1/gdk/gdkwindow.c 2005-06-16 07:18:33.000000000 +0200 +++ gtk+-2.7.1.patched/gdk/gdkwindow.c 2005-07-02 13:17:35.000000000 +0200 @@ -2131,6 +2131,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) @@ -2177,6 +2178,8 @@ GdkRegion *window_region; gint width, height; + ++update_serial; + if (debug_updates) { /* Make sure we see the red invalid area before redrawing. */ @@ -2250,6 +2253,7 @@ void gdk_window_process_all_updates (void) { + gboolean retval = FALSE; GSList *old_update_windows = update_windows; GSList *tmp_list = update_windows; @@ -2259,6 +2263,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) @@ -2495,6 +2502,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 -x '*.orig' -uNr gtk+-2.7.1/gdk/gdkwindow.h gtk+-2.7.1.patched/gdk/gdkwindow.h --- gtk+-2.7.1/gdk/gdkwindow.h 2005-06-21 06:09:51.000000000 +0200 +++ gtk+-2.7.1.patched/gdk/gdkwindow.h 2005-07-02 13:17:35.000000000 +0200 @@ -549,6 +549,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 -x '*.orig' -uNr gtk+-2.7.1/gtk/gtk.symbols gtk+-2.7.1.patched/gtk/gtk.symbols --- gtk+-2.7.1/gtk/gtk.symbols 2005-06-20 20:19:33.000000000 +0200 +++ gtk+-2.7.1.patched/gtk/gtk.symbols 2005-07-02 13:17:35.000000000 +0200 @@ -186,10 +186,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 diff -x '*.orig' -uNr gtk+-2.7.1/gtk/gtkadjustment.c gtk+-2.7.1.patched/gtk/gtkadjustment.c --- gtk+-2.7.1/gtk/gtkadjustment.c 2005-03-26 06:49:14.000000000 +0100 +++ gtk+-2.7.1.patched/gtk/gtkadjustment.c 2005-07-02 13:17:35.000000000 +0200 @@ -25,6 +25,7 @@ */ #include +#include #include "gtkadjustment.h" #include "gtkmarshalers.h" #include "gtkprivate.h" @@ -49,9 +50,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, @@ -211,7 +222,6 @@ 0.0, GTK_PARAM_READWRITE)); - adjustment_signals[CHANGED] = g_signal_new ("changed", G_OBJECT_CLASS_TYPE (class), @@ -241,6 +251,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) @@ -385,12 +433,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"); } @@ -423,5 +485,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 -x '*.orig' -uNr gtk+-2.7.1/gtk/gtkadjustment.h gtk+-2.7.1.patched/gtk/gtkadjustment.h --- gtk+-2.7.1/gtk/gtkadjustment.h 2005-06-21 07:35:43.000000000 +0200 +++ gtk+-2.7.1.patched/gtk/gtkadjustment.h 2005-07-02 13:17:35.000000000 +0200 @@ -71,21 +71,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); G_END_DECLS diff -x '*.orig' -uNr gtk+-2.7.1/gtk/gtkrange.h gtk+-2.7.1.patched/gtk/gtkrange.h --- gtk+-2.7.1/gtk/gtkrange.h 2005-06-21 07:35:43.000000000 +0200 +++ gtk+-2.7.1.patched/gtk/gtkrange.h 2005-07-02 13:19:35.000000000 +0200 @@ -150,10 +150,6 @@ gdouble value); gdouble gtk_range_get_value (GtkRange *range); -gdouble _gtk_range_get_wheel_delta (GtkRange *range, - GdkScrollDirection direction); - - G_END_DECLS diff -x '*.orig' -uNr gtk+-2.7.1/gtk/gtkscrolledwindow.c gtk+-2.7.1.patched/gtk/gtkscrolledwindow.c --- gtk+-2.7.1/gtk/gtkscrolledwindow.c 2005-05-08 05:37:43.000000000 +0200 +++ gtk+-2.7.1.patched/gtk/gtkscrolledwindow.c 2005-07-02 13:17:35.000000000 +0200 @@ -835,98 +835,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 @@ -1267,15 +1234,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; }