From 5911cd891f92c90aa0af7e18264d0935634b4834 Mon Sep 17 00:00:00 2001 From: Euclid Ye Date: Fri, 18 Jul 2025 01:43:30 +0800 Subject: [PATCH] servoshell: Fix scroll speed for Desktop (#37982) According to discussion https://github.com/servo/servo/pull/34063#discussion_r2187147615, this PR 1. adds `PIXEL_DELTA_FACTOR` to increase scroll speed for `MouseScrollDelta::PixelDelta`, which is used by macOS and high-precision mouse. 2. adds `LINE_WIDTH` to increase x-axis scroll speed for `MouseScrollDelta::LineDelta`, which is used by Linux and Windows. 3. Increase mouse scroll speed in general to match other browsers 4. Reduce keyboard scroll offset to scroll exactly "one line", to match other browsers. Testing: Example in #35037 can now scroll in x-axis as fast as y-axis, similar to other browsers. Fixes: part of #38072. --------- Signed-off-by: Euclid Ye Signed-off-by: Euclid Ye --- ports/servoshell/desktop/app_state.rs | 10 +++++----- ports/servoshell/desktop/headed_window.rs | 20 +++++++++++++------- ports/servoshell/desktop/window_trait.rs | 7 ++++++- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ports/servoshell/desktop/app_state.rs b/ports/servoshell/desktop/app_state.rs index cabc02a9f5e..b965dadfa30 100644 --- a/ports/servoshell/desktop/app_state.rs +++ b/ports/servoshell/desktop/app_state.rs @@ -29,7 +29,7 @@ use super::app::PumpResult; use super::dialog::Dialog; use super::gamepad::GamepadSupport; use super::keyutils::CMD_OR_CONTROL; -use super::window_trait::{LINE_HEIGHT, WindowPortsMethods}; +use super::window_trait::{LINE_HEIGHT, LINE_WIDTH, WindowPortsMethods}; use crate::output_image::save_output_image_if_necessary; use crate::prefs::ServoShellPreferences; @@ -425,19 +425,19 @@ impl RunningAppState { webview.notify_scroll_event(ScrollLocation::End, origin); }) .shortcut(Modifiers::empty(), Key::ArrowUp, || { - let location = ScrollLocation::Delta(Vector2D::new(0.0, -3.0 * LINE_HEIGHT)); + let location = ScrollLocation::Delta(Vector2D::new(0.0, -1.0 * LINE_HEIGHT)); webview.notify_scroll_event(location, origin); }) .shortcut(Modifiers::empty(), Key::ArrowDown, || { - let location = ScrollLocation::Delta(Vector2D::new(0.0, 3.0 * LINE_HEIGHT)); + let location = ScrollLocation::Delta(Vector2D::new(0.0, 1.0 * LINE_HEIGHT)); webview.notify_scroll_event(location, origin); }) .shortcut(Modifiers::empty(), Key::ArrowLeft, || { - let location = ScrollLocation::Delta(Vector2D::new(-LINE_HEIGHT, 0.0)); + let location = ScrollLocation::Delta(Vector2D::new(-LINE_WIDTH, 0.0)); webview.notify_scroll_event(location, origin); }) .shortcut(Modifiers::empty(), Key::ArrowRight, || { - let location = ScrollLocation::Delta(Vector2D::new(LINE_HEIGHT, 0.0)); + let location = ScrollLocation::Delta(Vector2D::new(LINE_WIDTH, 0.0)); webview.notify_scroll_event(location, origin); }); } diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs index ac55a9eea84..5e3dc8d9bf1 100644 --- a/ports/servoshell/desktop/headed_window.rs +++ b/ports/servoshell/desktop/headed_window.rs @@ -48,7 +48,7 @@ use { use super::app_state::RunningAppState; use super::geometry::{winit_position_to_euclid_point, winit_size_to_euclid_size}; use super::keyutils::{CMD_OR_ALT, keyboard_event_from_winit}; -use super::window_trait::{LINE_HEIGHT, WindowPortsMethods}; +use super::window_trait::{LINE_HEIGHT, LINE_WIDTH, PIXEL_DELTA_FACTOR, WindowPortsMethods}; use crate::desktop::accelerated_gl_media::setup_gl_accelerated_media; use crate::desktop::keyutils::CMD_OR_CONTROL; use crate::prefs::ServoShellPreferences; @@ -621,13 +621,19 @@ impl WindowPortsMethods for Window { }, WindowEvent::MouseWheel { delta, .. } => { let (mut dx, mut dy, mode) = match delta { - MouseScrollDelta::LineDelta(dx, dy) => { - (dx as f64, (dy * LINE_HEIGHT) as f64, WheelMode::DeltaLine) - }, + MouseScrollDelta::LineDelta(dx, dy) => ( + (dx * LINE_WIDTH) as f64, + (dy * LINE_HEIGHT) as f64, + WheelMode::DeltaLine, + ), MouseScrollDelta::PixelDelta(position) => { - let scale_factor = self.device_hidpi_scale_factor().inverse().get() as f64; - let position = position.to_logical(scale_factor); - (position.x, position.y, WheelMode::DeltaPixel) + let position: LogicalPosition = + position.to_logical(self.device_hidpi_scale_factor().get() as f64); + ( + position.x * PIXEL_DELTA_FACTOR, + position.y * PIXEL_DELTA_FACTOR, + WheelMode::DeltaPixel, + ) }, }; diff --git a/ports/servoshell/desktop/window_trait.rs b/ports/servoshell/desktop/window_trait.rs index 62e81b1ee73..14684ec084b 100644 --- a/ports/servoshell/desktop/window_trait.rs +++ b/ports/servoshell/desktop/window_trait.rs @@ -15,7 +15,12 @@ use servo::{Cursor, RenderingContext, ScreenGeometry, WebView}; use super::app_state::RunningAppState; // This should vary by zoom level and maybe actual text size (focused or under cursor) -pub const LINE_HEIGHT: f32 = 38.0; +pub const LINE_HEIGHT: f32 = 76.0; +pub const LINE_WIDTH: f32 = 76.0; +// MouseScrollDelta::PixelDelta is default for MacOS, which is high precision and very slow +// in winit. Therefore we use a factor of 4.0 to make it more usable. +// See https://github.com/servo/servo/pull/34063#discussion_r2197729507 +pub const PIXEL_DELTA_FACTOR: f64 = 4.0; pub trait WindowPortsMethods { fn id(&self) -> winit::window::WindowId;