From d4943ef2fbc5a402bb5f43f40c93700b7263f07b Mon Sep 17 00:00:00 2001 From: Benjamin Schaaf Date: Fri, 25 Sep 2020 00:32:00 +1000 Subject: Add scaling adjustment for touch dragging a scrolled window If a GtkScrollable uses a different scale than pixels the offset from a drag must be adjusted to match this scale. This fixes issues like this https://gitlab.gnome.org/GNOME/vte/-/issues/283 where the terminal widget uses rows instead of pixels as its scale for each GtkAdjustable thus causing a 1 pixel vertical drag to scroll 1 row. --- gtk/gtkscrolledwindow.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 95c910f50e..fa898f14c6 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -1007,7 +1007,9 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, GtkScrolledWindowPrivate *priv = scrolled_window->priv; GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; - gdouble dx, dy; + GtkScrollable *child; + GtkBorder border; + double dx, dy, scale, size; gtk_scrolled_window_invalidate_overshoot (scrolled_window); @@ -1020,10 +1022,25 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, GTK_EVENT_SEQUENCE_CLAIMED); } + child = GTK_SCROLLABLE (gtk_bin_get_child (GTK_BIN (scrolled_window))); + hadjustment = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)); if (hadjustment && may_hscroll (scrolled_window)) { - dx = priv->drag_start_x - offset_x; + if (child && gtk_widget_get_visible (child)) + { + size = gtk_widget_get_allocated_width (GTK_WIDGET (child)); + if (gtk_scrollable_get_border (child, &border)) + size -= border.left + border.right; + + scale = gtk_adjustment_get_page_size (hadjustment) / size; + } + else + { + scale = 1.0; + } + + dx = priv->drag_start_x - offset_x * scale; _gtk_scrolled_window_set_adjustment_value (scrolled_window, hadjustment, dx); } @@ -1031,7 +1048,20 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window, vadjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)); if (vadjustment && may_vscroll (scrolled_window)) { - dy = priv->drag_start_y - offset_y; + if (child && gtk_widget_get_visible (child)) + { + size = gtk_widget_get_allocated_height (GTK_WIDGET (child)); + if (gtk_scrollable_get_border (child, &border)) + size -= border.top + border.bottom; + + scale = gtk_adjustment_get_page_size (vadjustment) / size; + } + else + { + scale = 1.0; + } + + dy = priv->drag_start_y - offset_y * scale; _gtk_scrolled_window_set_adjustment_value (scrolled_window, vadjustment, dy); } -- cgit v1.2.1