diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index f2b6748bfa66f78558f8d1a114913fa41ec8da7a..d345e303e46f42419691801199265150bb34ae2c 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -267,8 +267,9 @@ typedef enum /** * GdkScrollUnit: * @GDK_SCROLL_UNIT_WHEEL: The delta is in number of wheel clicks. - * @GDK_SCROLL_UNIT_SURFACE: The delta is in surface pixels to scroll directly - * on screen. + * @GDK_SCROLL_UNIT_SURFACE: A unit used for high-precision scroll devices. + * @GDK_SCROLL_UNIT_SURFACE_CONTINUOUS: Special case of + * %GDK_SCROLL_UNIT_SURFACE. * * Specifies the unit of scroll deltas. * @@ -277,22 +278,21 @@ typedef enum * direction... This is the same logic for negative values but in the north * direction. * - * If you get %GDK_SCROLL_UNIT_SURFACE, are managing a scrollable view and get a - * value of 123, you have to scroll 123 surface logical pixels right if it's - * @delta_x or down if it's @delta_y. This is the same logic for negative values - * but you have to scroll left instead of right if it's @delta_x and up instead - * of down if it's @delta_y. + * If you get %GDK_SCROLL_UNIT_SURFACE, deltas are represented in a continuous + * unit space. This unit concerns high-precision scroll devices like touchpads. + * On Wayland, it is raised when `wl_pointer.axis_source` is `finger`. * - * 1 surface logical pixel is equal to 1 real screen pixel multiplied by the - * final scale factor of your graphical interface (the product of the desktop - * scale factor and eventually a custom scale factor in your app). + * %GDK_SCROLL_UNIT_SURFACE_CONTINUOUS is the same as %GDK_SCROLL_UNIT_SURFACE + * but is raised on Wayland when `wl_pointer.axis_source` is `continuous`. An + * exemple of concerned scroll device is trackpoint. * * Since: 4.8 */ typedef enum { GDK_SCROLL_UNIT_WHEEL, - GDK_SCROLL_UNIT_SURFACE + GDK_SCROLL_UNIT_SURFACE, + GDK_SCROLL_UNIT_SURFACE_CONTINUOUS } GdkScrollUnit; /** diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index d4e12f0fae0c4662754ea4534a66cd90d96e660d..c40da15d1e116952be5d2828e6705da0b33b5e6f 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -1445,6 +1445,12 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat, { GdkEvent *event; GdkDevice *source; + GdkScrollUnit unit; + + if (seat->pointer_info.frame.source == WL_POINTER_AXIS_SOURCE_CONTINUOUS) + unit = GDK_SCROLL_UNIT_SURFACE_CONTINUOUS; + else + unit = GDK_SCROLL_UNIT_SURFACE; source = get_scroll_device (seat, seat->pointer_info.frame.source); event = gdk_scroll_event_new (seat->pointer_info.focus, @@ -1454,7 +1460,7 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat, device_get_modifiers (seat->logical_pointer), delta_x, delta_y, is_stop, - GDK_SCROLL_UNIT_SURFACE); + unit); _gdk_wayland_display_deliver_event (seat->display, event); } diff --git a/gtk/gtkeventcontrollerscroll.c b/gtk/gtkeventcontrollerscroll.c index 6d1e8734e9b0debbd7e741c8ee591cac4a452055..1b17c68de337db85911b33c80e9972205c4bbd2d 100644 --- a/gtk/gtkeventcontrollerscroll.c +++ b/gtk/gtkeventcontrollerscroll.c @@ -398,17 +398,7 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller, scroll->cur_dy += dy; dx = dy = 0; - if (scroll_unit == GDK_SCROLL_UNIT_SURFACE) - { - dx = (int) scroll->cur_dx / SURFACE_UNIT_DISCRETE_MAPPING; - scroll->cur_dx -= dx * SURFACE_UNIT_DISCRETE_MAPPING; - - dy = (int) scroll->cur_dy / SURFACE_UNIT_DISCRETE_MAPPING; - scroll->cur_dy -= dy * SURFACE_UNIT_DISCRETE_MAPPING; - - scroll_unit = GDK_SCROLL_UNIT_WHEEL; - } - else + if (scroll_unit == GDK_SCROLL_UNIT_WHEEL) { if (ABS (scroll->cur_dx) >= 1) { @@ -424,6 +414,16 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller, dy = steps; } } + else + { + dx = (int) scroll->cur_dx / SURFACE_UNIT_DISCRETE_MAPPING; + scroll->cur_dx -= dx * SURFACE_UNIT_DISCRETE_MAPPING; + + dy = (int) scroll->cur_dy / SURFACE_UNIT_DISCRETE_MAPPING; + scroll->cur_dy -= dy * SURFACE_UNIT_DISCRETE_MAPPING; + + scroll_unit = GDK_SCROLL_UNIT_WHEEL; + } } } else diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 90f0222ee6a5bcc05de96f7098cf5d7bbdf33f64..e7fbb31a28e96ac155d07f01c45082c632c175a6 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -183,8 +183,6 @@ /* Scrolled off indication */ #define UNDERSHOOT_SIZE 40 -#define MAGIC_SCROLL_FACTOR 2.5 - typedef struct _GtkScrolledWindowClass GtkScrolledWindowClass; struct _GtkScrolledWindow @@ -1187,28 +1185,36 @@ check_update_scrollbar_proximity (GtkScrolledWindow *sw, } static double -get_wheel_detent_scroll_step (GtkScrolledWindow *sw, - GtkOrientation orientation) +get_scroll_distance (GtkScrolledWindow *scrolled_window, + GtkEventControllerScroll *scroll, + double delta, + GtkAdjustment *adj) { - GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw); - GtkScrollbar *scrollbar; - GtkAdjustment *adj; + GdkScrollUnit scroll_unit; + GtkSettings *settings; + double scroll_factor; double page_size; - double scroll_step; + double wheel_scroll_step; - if (orientation == GTK_ORIENTATION_HORIZONTAL) - scrollbar = GTK_SCROLLBAR (priv->hscrollbar); - else - scrollbar = GTK_SCROLLBAR (priv->vscrollbar); + scroll_unit = gtk_event_controller_scroll_get_unit (scroll); + settings = gtk_widget_get_settings (GTK_WIDGET (scrolled_window)); - if (!scrollbar) - return 0; + if (scroll_unit == GDK_SCROLL_UNIT_WHEEL) + { + g_object_get (settings, "gtk-scroll-speed-mouse", &scroll_factor, NULL); - adj = gtk_scrollbar_get_adjustment (scrollbar); - page_size = gtk_adjustment_get_page_size (adj); - scroll_step = pow (page_size, 2.0 / 3.0); + page_size = gtk_adjustment_get_page_size (adj); + wheel_scroll_step = pow (page_size, 2.0 / 3.0); + scroll_factor *= wheel_scroll_step; + } + else if(scroll_unit == GDK_SCROLL_UNIT_SURFACE) + g_object_get (settings, "gtk-scroll-speed-touchpad", &scroll_factor, + NULL); + else if(scroll_unit == GDK_SCROLL_UNIT_SURFACE_CONTINUOUS) + g_object_get (settings, "gtk-scroll-speed-trackpoint", &scroll_factor, + NULL); - return scroll_step; + return delta * scroll_factor; } static gboolean @@ -1349,21 +1355,13 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window, may_hscroll (scrolled_window)) { GtkAdjustment *adj; + double distance; double new_value; - GdkScrollUnit scroll_unit; adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar)); - scroll_unit = gtk_event_controller_scroll_get_unit (scroll); + distance = get_scroll_distance (scrolled_window, scroll, delta_x, adj); - if (scroll_unit == GDK_SCROLL_UNIT_WHEEL) - { - delta_x *= get_wheel_detent_scroll_step (scrolled_window, - GTK_ORIENTATION_HORIZONTAL); - } - else if (scroll_unit == GDK_SCROLL_UNIT_SURFACE) - delta_x *= MAGIC_SCROLL_FACTOR; - - new_value = priv->unclamped_hadj_value + delta_x; + new_value = priv->unclamped_hadj_value + distance; _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj, new_value); } @@ -1372,21 +1370,13 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window, may_vscroll (scrolled_window)) { GtkAdjustment *adj; + double distance; double new_value; - GdkScrollUnit scroll_unit; adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar)); - scroll_unit = gtk_event_controller_scroll_get_unit (scroll); - - if (scroll_unit == GDK_SCROLL_UNIT_WHEEL) - { - delta_y *= get_wheel_detent_scroll_step (scrolled_window, - GTK_ORIENTATION_VERTICAL); - } - else if (scroll_unit == GDK_SCROLL_UNIT_SURFACE) - delta_y *= MAGIC_SCROLL_FACTOR; + distance = get_scroll_distance (scrolled_window, scroll, delta_y, adj); - new_value = priv->unclamped_vadj_value + delta_y; + new_value = priv->unclamped_vadj_value + distance; _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj, new_value); } @@ -1433,13 +1423,18 @@ scroll_controller_decelerate (GtkEventControllerScroll *scroll, double initial_vel_y, GtkScrolledWindow *scrolled_window) { - GdkScrollUnit scroll_unit; + GtkScrolledWindowPrivate *priv = + gtk_scrolled_window_get_instance_private (scrolled_window); + gboolean shifted; GdkModifierType state; - scroll_unit = gtk_event_controller_scroll_get_unit (scroll); - state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll)); + GtkAdjustment *hadj; + GtkAdjustment *vadj; + double initial_vel_distance_x; + double initial_vel_distance_y; + state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll)); shifted = (state & GDK_SHIFT_MASK) != 0; if (shifted) @@ -1451,23 +1446,18 @@ scroll_controller_decelerate (GtkEventControllerScroll *scroll, initial_vel_y = tmp; } - if (scroll_unit == GDK_SCROLL_UNIT_WHEEL) - { - initial_vel_x *= get_wheel_detent_scroll_step (scrolled_window, - GTK_ORIENTATION_HORIZONTAL); + hadj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar)); + vadj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar)); - initial_vel_y *= get_wheel_detent_scroll_step (scrolled_window, - GTK_ORIENTATION_VERTICAL); - } - else - { - initial_vel_x *= MAGIC_SCROLL_FACTOR; - initial_vel_y *= MAGIC_SCROLL_FACTOR; - } + initial_vel_distance_x = get_scroll_distance (scrolled_window, scroll, + initial_vel_x, hadj); + + initial_vel_distance_y = get_scroll_distance (scrolled_window, scroll, + initial_vel_y, vadj); gtk_scrolled_window_decelerate (scrolled_window, - initial_vel_x, - initial_vel_y); + initial_vel_distance_x, + initial_vel_distance_y); } static void diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index 2bd42f297293a28d3331ce30eaac6e9685e88483..db549f5a5d78054aab6e83324f391ae524f70ba9 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -199,6 +199,9 @@ enum { PROP_LONG_PRESS_TIME, PROP_KEYNAV_USE_CARET, PROP_OVERLAY_SCROLLING, + PROP_SCROLL_SPEED_MOUSE, + PROP_SCROLL_SPEED_TOUCHPAD, + PROP_SCROLL_SPEED_TRACKPOINT, NUM_PROPERTIES }; @@ -938,6 +941,33 @@ gtk_settings_class_init (GtkSettingsClass *class) TRUE, GTK_PARAM_READWRITE); + /** + * GtkSettings:gtk-scroll-speed-mouse: + * + * The speed at which the content should scroll with the mouse. + */ + pspecs[PROP_SCROLL_SPEED_MOUSE] = g_param_spec_double ("gtk-scroll-speed-mouse", NULL, NULL, + 0.0, 100.0, 1.0, + GTK_PARAM_READWRITE); + + /** + * GtkSettings:gtk-scroll-speed-touchpad: + * + * The speed at which the content should scroll with the touchpad. + */ + pspecs[PROP_SCROLL_SPEED_TOUCHPAD] = g_param_spec_double ("gtk-scroll-speed-touchpad", NULL, NULL, + 0.0, 100.0, 1.0, + GTK_PARAM_READWRITE); + + /** + * GtkSettings:gtk-scroll-speed-trackpoint: + * + * The speed at which the content should scroll with the trackpoint. + */ + pspecs[PROP_SCROLL_SPEED_TRACKPOINT] = g_param_spec_double ("gtk-scroll-speed-trackpoint", NULL, NULL, + 0.0, 100.0, 1.0, + GTK_PARAM_READWRITE); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, pspecs); } diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c index e33d058b05db407f0d7238ad793155a969357674..e278637c66addc1ed8d8273bb4e3718a03dce299 100644 --- a/gtk/inspector/recorder.c +++ b/gtk/inspector/recorder.c @@ -1568,6 +1568,8 @@ scroll_unit_name (GdkScrollUnit unit) return "Wheel"; else if (unit == GDK_SCROLL_UNIT_SURFACE) return "Surface"; + else if (unit == GDK_SCROLL_UNIT_SURFACE_CONTINUOUS) + return "Surface continuous"; else return "Incorrect value"; } diff --git a/testsuite/tools/settings.in b/testsuite/tools/settings.in index 3c5ce690168a59d301503eaadebff90aed2efc13..57c72fe56c7813fcb8ea1805be34bbac828fe9bc 100755 --- a/testsuite/tools/settings.in +++ b/testsuite/tools/settings.in @@ -10,7 +10,7 @@ echo "1..1" name=gtk-query-settings result=$TEST_RESULT_DIR/$name.out $GTK_QUERY_SETTINGS 2>/dev/null >$result -EXPECTED=50 +EXPECTED=53 SEEN=$(wc -l $result | cut -f1 -d' ') if [ $SEEN -eq $EXPECTED ]; then