diff --git a/gtk/gtkkineticscrolling.c b/gtk/gtkkineticscrolling.c index b686525099..1b2bd55eb3 100644 --- a/gtk/gtkkineticscrolling.c +++ b/gtk/gtkkineticscrolling.c @@ -70,18 +70,20 @@ struct _GtkKineticScrolling double c2; double equilibrium_position; - double t; + gint64 t; double position; double velocity; }; static void gtk_kinetic_scrolling_init_overshoot (GtkKineticScrolling *data, + gint64 frame_time, double equilibrium_position, double initial_position, double initial_velocity); GtkKineticScrolling * -gtk_kinetic_scrolling_new (double lower, +gtk_kinetic_scrolling_new (gint64 frame_time, + double lower, double upper, double overshoot_width, double decel_friction, @@ -96,16 +98,18 @@ gtk_kinetic_scrolling_new (double lower, data->upper = upper; data->decel_friction = decel_friction; data->overshoot_friction = overshoot_friction; - if(initial_position < lower) + if (initial_position < lower) { gtk_kinetic_scrolling_init_overshoot (data, + frame_time, lower, initial_position, initial_velocity); } - else if(initial_position > upper) + else if (initial_position > upper) { gtk_kinetic_scrolling_init_overshoot (data, + frame_time, upper, initial_position, initial_velocity); @@ -115,9 +119,9 @@ gtk_kinetic_scrolling_new (double lower, data->phase = GTK_KINETIC_SCROLLING_PHASE_DECELERATING; data->c1 = initial_velocity / decel_friction + initial_position; data->c2 = -initial_velocity / decel_friction; - data->t = 0; data->position = initial_position; data->velocity = initial_velocity; + data->t = frame_time; } return data; @@ -160,6 +164,7 @@ gtk_kinetic_scrolling_free (GtkKineticScrolling *kinetic) static void gtk_kinetic_scrolling_init_overshoot (GtkKineticScrolling *data, + gint64 frame_time, double equilibrium_position, double initial_position, double initial_velocity) @@ -168,36 +173,36 @@ gtk_kinetic_scrolling_init_overshoot (GtkKineticScrolling *data, data->equilibrium_position = equilibrium_position; data->c1 = initial_position - equilibrium_position; data->c2 = initial_velocity + data->overshoot_friction / 2 * data->c1; - data->t = 0; + data->t = frame_time; } gboolean gtk_kinetic_scrolling_tick (GtkKineticScrolling *data, - double time_delta, + gint64 frame_time, double *position, double *velocity) { - switch(data->phase) + double t = (frame_time - data->t) / (double)G_USEC_PER_SEC; + + switch (data->phase) { case GTK_KINETIC_SCROLLING_PHASE_DECELERATING: { double exp_part; - data->t += time_delta; - - exp_part = exp (-data->decel_friction * data->t); + exp_part = exp (-data->decel_friction * t); data->position = data->c1 + data->c2 * exp_part; data->velocity = -data->decel_friction * data->c2 * exp_part; - if(data->position < data->lower) + if (data->position < data->lower) { - gtk_kinetic_scrolling_init_overshoot(data,data->lower,data->position,data->velocity); + gtk_kinetic_scrolling_init_overshoot (data, frame_time, data->lower, data->position, data->velocity); } else if (data->position > data->upper) { - gtk_kinetic_scrolling_init_overshoot(data, data->upper, data->position, data->velocity); + gtk_kinetic_scrolling_init_overshoot (data, frame_time, data->upper, data->position, data->velocity); } - else if (fabs(data->velocity) < 0.1) + else if (fabs (data->velocity) < 0.1) { gtk_kinetic_scrolling_stop (data); } @@ -208,21 +213,20 @@ gtk_kinetic_scrolling_tick (GtkKineticScrolling *data, { double exp_part, pos; - data->t += time_delta; - exp_part = exp(-data->overshoot_friction / 2 * data->t); - pos = exp_part * (data->c1 + data->c2 * data->t); + exp_part = exp (-data->overshoot_friction / 2 * t); + pos = exp_part * (data->c1 + data->c2 * t); if (pos < data->lower - 50 || pos > data->upper + 50) { pos = CLAMP (pos, data->lower - 50, data->upper + 50); - gtk_kinetic_scrolling_init_overshoot (data, data->equilibrium_position, pos, 0); + gtk_kinetic_scrolling_init_overshoot (data, frame_time, data->equilibrium_position, pos, 0); } else data->velocity = data->c2 * exp_part - data->overshoot_friction / 2 * pos; data->position = pos + data->equilibrium_position; - if(fabs (pos) < 0.1) + if (fabs (pos) < 0.1) { data->phase = GTK_KINETIC_SCROLLING_PHASE_FINISHED; data->position = data->equilibrium_position; diff --git a/gtk/gtkkineticscrollingprivate.h b/gtk/gtkkineticscrollingprivate.h index 39cee10058..9db7f7f78c 100644 --- a/gtk/gtkkineticscrollingprivate.h +++ b/gtk/gtkkineticscrollingprivate.h @@ -31,7 +31,8 @@ typedef enum { typedef struct _GtkKineticScrolling GtkKineticScrolling; -GtkKineticScrolling * gtk_kinetic_scrolling_new (double lower, +GtkKineticScrolling * gtk_kinetic_scrolling_new (gint64 frame_time, + double lower, double upper, double overshoot_width, double decel_friction, @@ -45,7 +46,7 @@ GtkKineticScrollingChange gtk_kinetic_scrolling_update_size (GtkKineticScrolling double upper); gboolean gtk_kinetic_scrolling_tick (GtkKineticScrolling *data, - double time_delta, + gint64 frame_time, double *position, double *velocity); diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 2e03973cd1..fc2a4620ff 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -3263,11 +3263,10 @@ scrolled_window_deceleration_cb (GtkWidget *widget, GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window); GtkAdjustment *hadjustment, *vadjustment; gint64 current_time; - double position, elapsed; + double position; gboolean retval = G_SOURCE_REMOVE; current_time = gdk_frame_clock_get_frame_time (frame_clock); - elapsed = (current_time - priv->last_deceleration_time) / (double)G_TIME_SPAN_SECOND; priv->last_deceleration_time = current_time; hadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar)); @@ -3276,7 +3275,7 @@ scrolled_window_deceleration_cb (GtkWidget *widget, gtk_scrolled_window_invalidate_overshoot (scrolled_window); if (priv->hscrolling && - gtk_kinetic_scrolling_tick (priv->hscrolling, elapsed, &position, NULL)) + gtk_kinetic_scrolling_tick (priv->hscrolling, current_time, &position, NULL)) { priv->unclamped_hadj_value = position; gtk_adjustment_set_value (hadjustment, position); @@ -3284,7 +3283,7 @@ scrolled_window_deceleration_cb (GtkWidget *widget, } if (priv->vscrolling && - gtk_kinetic_scrolling_tick (priv->vscrolling, elapsed, &position, NULL)) + gtk_kinetic_scrolling_tick (priv->vscrolling, current_time, &position, NULL)) { priv->unclamped_vadj_value = position; gtk_adjustment_set_value (vadjustment, position); @@ -3320,13 +3319,15 @@ kinetic_scroll_stop_notify (GtkScrolledWindow *scrolled_window) } static void -gtk_scrolled_window_accumulate_velocity (GtkKineticScrolling **scrolling, double elapsed, double *velocity) +gtk_scrolled_window_accumulate_velocity (GtkKineticScrolling **scrolling, + gint64 current_time, + double *velocity) { if (!*scrolling) return; double last_velocity; - gtk_kinetic_scrolling_tick (*scrolling, elapsed, NULL, &last_velocity); + gtk_kinetic_scrolling_tick (*scrolling, current_time, NULL, &last_velocity); if (((*velocity >= 0) == (last_velocity >= 0)) && (fabs (*velocity) >= fabs (last_velocity) * VELOCITY_ACCUMULATION_FLOOR)) { @@ -3344,7 +3345,6 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window); GdkFrameClock *frame_clock; gint64 current_time; - double elapsed; int overshoot_x, overshoot_y; g_return_if_fail (priv->deceleration_id == 0); @@ -3352,7 +3352,6 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (scrolled_window)); current_time = gdk_frame_clock_get_frame_time (frame_clock); - elapsed = (current_time - priv->last_deceleration_time) / (double)G_TIME_SPAN_SECOND; priv->last_deceleration_time = current_time; _gtk_scrolled_window_get_overshoot (scrolled_window, &overshoot_x, &overshoot_y); @@ -3362,7 +3361,7 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) double lower,upper; GtkAdjustment *hadjustment; - gtk_scrolled_window_accumulate_velocity (&priv->hscrolling, elapsed, &priv->x_velocity); + gtk_scrolled_window_accumulate_velocity (&priv->hscrolling, current_time, &priv->x_velocity); g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free); if (priv->x_velocity != 0 || overshoot_x != 0) @@ -3372,7 +3371,8 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) upper = gtk_adjustment_get_upper (hadjustment); upper -= gtk_adjustment_get_page_size (hadjustment); priv->hscrolling = - gtk_kinetic_scrolling_new (lower, + gtk_kinetic_scrolling_new (current_time, + lower, upper, MAX_OVERSHOOT_DISTANCE, DECELERATION_FRICTION, @@ -3389,7 +3389,7 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) double lower,upper; GtkAdjustment *vadjustment; - gtk_scrolled_window_accumulate_velocity (&priv->vscrolling, elapsed, &priv->y_velocity); + gtk_scrolled_window_accumulate_velocity (&priv->vscrolling, current_time, &priv->y_velocity); g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free); if (priv->y_velocity != 0 || overshoot_y != 0) @@ -3399,7 +3399,8 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window) upper = gtk_adjustment_get_upper(vadjustment); upper -= gtk_adjustment_get_page_size(vadjustment); priv->vscrolling = - gtk_kinetic_scrolling_new (lower, + gtk_kinetic_scrolling_new (current_time, + lower, upper, MAX_OVERSHOOT_DISTANCE, DECELERATION_FRICTION,