diff --git a/gtk/gtkkineticscrolling.c b/gtk/gtkkineticscrolling.c index eb9c13bdfd..87618acd7c 100644 --- a/gtk/gtkkineticscrolling.c +++ b/gtk/gtkkineticscrolling.c @@ -123,6 +123,35 @@ gtk_kinetic_scrolling_new (double lower, return data; } +GtkKineticScrollingChange +gtk_kinetic_scrolling_update_size (GtkKineticScrolling *data, + double lower, + double upper) +{ + GtkKineticScrollingChange change = GTK_KINETIC_SCROLLING_CHANGE_NONE; + + if (lower != data->lower) + { + if (data->position <= lower) + change |= GTK_KINETIC_SCROLLING_CHANGE_LOWER; + + data->lower = lower; + } + + if (upper != data->upper) + { + if (data->position >= data->upper) + change |= GTK_KINETIC_SCROLLING_CHANGE_UPPER; + + data->upper = upper; + } + + if (data->phase == GTK_KINETIC_SCROLLING_PHASE_OVERSHOOTING) + change |= GTK_KINETIC_SCROLLING_CHANGE_IN_OVERSHOOT; + + return change; +} + void gtk_kinetic_scrolling_free (GtkKineticScrolling *kinetic) { diff --git a/gtk/gtkkineticscrollingprivate.h b/gtk/gtkkineticscrollingprivate.h index b97fac360f..a531ace476 100644 --- a/gtk/gtkkineticscrollingprivate.h +++ b/gtk/gtkkineticscrollingprivate.h @@ -23,6 +23,13 @@ G_BEGIN_DECLS +typedef enum { + GTK_KINETIC_SCROLLING_CHANGE_NONE = 0, + GTK_KINETIC_SCROLLING_CHANGE_LOWER = 1 << 0, + GTK_KINETIC_SCROLLING_CHANGE_UPPER = 1 << 1, + GTK_KINETIC_SCROLLING_CHANGE_IN_OVERSHOOT = 1 << 2, +} GtkKineticScrollingChange; + typedef struct _GtkKineticScrolling GtkKineticScrolling; GtkKineticScrolling * gtk_kinetic_scrolling_new (double lower, @@ -34,6 +41,10 @@ GtkKineticScrolling * gtk_kinetic_scrolling_new (double lower double initial_velocity); void gtk_kinetic_scrolling_free (GtkKineticScrolling *kinetic); +GtkKineticScrollingChange gtk_kinetic_scrolling_update_size (GtkKineticScrolling *data, + double lower, + double upper); + gboolean gtk_kinetic_scrolling_tick (GtkKineticScrolling *data, double time_delta, double *position, diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index a56891b5e2..40e285c77b 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -3455,6 +3455,24 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment, if (priv->hscrollbar_visible != visible) gtk_widget_queue_resize (GTK_WIDGET (scrolled_window)); + + if (priv->hscrolling) + { + GtkKineticScrollingChange change; + double lower = gtk_adjustment_get_lower (adjustment); + double upper = gtk_adjustment_get_upper (adjustment); + upper -= gtk_adjustment_get_page_size (adjustment); + + change = gtk_kinetic_scrolling_update_size (priv->hscrolling, lower, upper); + + if ((change & GTK_KINETIC_SCROLLING_CHANGE_IN_OVERSHOOT) && + (change & (GTK_KINETIC_SCROLLING_CHANGE_UPPER | GTK_KINETIC_SCROLLING_CHANGE_LOWER))) + { + g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free); + priv->unclamped_hadj_value = gtk_adjustment_get_value (adjustment); + gtk_scrolled_window_invalidate_overshoot (scrolled_window); + } + } } } else if (adjustment == gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar))) @@ -3468,8 +3486,29 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment, if (priv->vscrollbar_visible != visible) gtk_widget_queue_resize (GTK_WIDGET (scrolled_window)); + + if (priv->vscrolling) + { + GtkKineticScrollingChange change; + double lower = gtk_adjustment_get_lower (adjustment); + double upper = gtk_adjustment_get_upper (adjustment); + upper -= gtk_adjustment_get_page_size (adjustment); + + change = gtk_kinetic_scrolling_update_size (priv->vscrolling, lower, upper); + + if ((change & GTK_KINETIC_SCROLLING_CHANGE_IN_OVERSHOOT) && + (change & (GTK_KINETIC_SCROLLING_CHANGE_UPPER | GTK_KINETIC_SCROLLING_CHANGE_LOWER))) + { + g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free); + priv->unclamped_vadj_value = gtk_adjustment_get_value (adjustment); + gtk_scrolled_window_invalidate_overshoot (scrolled_window); + } + } } } + + if (!priv->hscrolling && !priv->vscrolling) + gtk_scrolled_window_cancel_deceleration (scrolled_window); } static void