fix: accumulate fractional wheel-line scroll deltas
This commit is contained in:
parent
1d3d8837df
commit
1e49511fcf
1 changed files with 63 additions and 4 deletions
|
|
@ -1553,16 +1553,22 @@ where
|
|||
} else {
|
||||
match delta {
|
||||
ScrollDelta::Lines { x: _, y } => {
|
||||
//TODO: this adjustment is just a guess!
|
||||
// High-resolution wheels deliver a notch as many
|
||||
// fractional deltas; accumulate them so nothing
|
||||
// below one whole line is lost (see
|
||||
// accumulate_wheel_lines).
|
||||
state.scroll_pixels = 0.0;
|
||||
let lines = (-y * 6.0) as i32;
|
||||
let (lines, remainder) =
|
||||
accumulate_wheel_lines(*y, state.scroll_lines);
|
||||
state.scroll_lines = remainder;
|
||||
if lines != 0 {
|
||||
terminal.scroll(TerminalScroll::Delta(-lines));
|
||||
terminal.scroll(TerminalScroll::Delta(lines));
|
||||
}
|
||||
shell.capture_event();
|
||||
}
|
||||
ScrollDelta::Pixels { x: _, y } => {
|
||||
//TODO: this adjustment is just a guess!
|
||||
state.scroll_lines = 0.0;
|
||||
state.scroll_pixels -= y * 6.0;
|
||||
let mut lines = 0;
|
||||
let metrics = terminal.with_buffer(|buffer| buffer.metrics());
|
||||
|
|
@ -1728,6 +1734,26 @@ fn update_active_regex_match(
|
|||
}
|
||||
}
|
||||
|
||||
/// Whole lines scrolled per unit of wheel `Lines` delta.
|
||||
//TODO: this adjustment is just a guess!
|
||||
const SCROLL_LINE_MULTIPLIER: f32 = 6.0;
|
||||
|
||||
/// Convert a wheel `Lines` delta into whole lines to scroll, accumulating the
|
||||
/// fractional remainder across events.
|
||||
///
|
||||
/// High-resolution wheels deliver a single physical notch as many fractional
|
||||
/// deltas (e.g. `y = 0.125`). Scaling by [`SCROLL_LINE_MULTIPLIER`] and
|
||||
/// truncating per event discards anything below one whole line, so most of
|
||||
/// those events would scroll nothing. Carrying the remainder forward means the
|
||||
/// fractions add up and a full notch scrolls the intended amount.
|
||||
///
|
||||
/// Returns `(whole_lines, new_accumulator)`.
|
||||
fn accumulate_wheel_lines(y: f32, accumulator: f32) -> (i32, f32) {
|
||||
let total = accumulator + y * SCROLL_LINE_MULTIPLIER;
|
||||
let lines = total.trunc() as i32;
|
||||
(lines, total - lines as f32)
|
||||
}
|
||||
|
||||
fn shade(color: cosmic_text::Color, is_focused: bool) -> cosmic_text::Color {
|
||||
if is_focused {
|
||||
color
|
||||
|
|
@ -1929,6 +1955,7 @@ pub struct State {
|
|||
dragging: Option<Dragging>,
|
||||
is_focused: bool,
|
||||
scroll_pixels: f32,
|
||||
scroll_lines: f32,
|
||||
scrollbar_rect: Cell<Rectangle<f32>>,
|
||||
autoscroll: DragAutoscroll,
|
||||
preedit: Option<input_method::Preedit>,
|
||||
|
|
@ -1943,6 +1970,7 @@ impl State {
|
|||
dragging: None,
|
||||
is_focused: false,
|
||||
scroll_pixels: 0.0,
|
||||
scroll_lines: 0.0,
|
||||
scrollbar_rect: Cell::new(Rectangle::default()),
|
||||
autoscroll: DragAutoscroll::new(AUTOSCROLL_INTERVAL),
|
||||
preedit: None,
|
||||
|
|
@ -2022,7 +2050,38 @@ fn ss3(code: &str, modifiers: u8) -> Option<Vec<u8>> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{EdgeScrollDirection, edge_scroll_adjustment};
|
||||
use super::{EdgeScrollDirection, accumulate_wheel_lines, edge_scroll_adjustment};
|
||||
|
||||
#[test]
|
||||
fn wheel_lines_single_fractional_event_keeps_remainder() {
|
||||
// A high-res wheel notch arrives as fractional deltas. A lone 0.125
|
||||
// event is less than one whole line, but must not be discarded.
|
||||
let (lines, remainder) = accumulate_wheel_lines(0.125, 0.0);
|
||||
assert_eq!(lines, 0);
|
||||
assert!((remainder - 0.75).abs() < f32::EPSILON);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_lines_accumulate_into_whole_lines() {
|
||||
// Eight 0.125 deltas make up one physical notch and must scroll the
|
||||
// full SCROLL_LINE_MULTIPLIER (6) lines, not be lost to truncation.
|
||||
let mut accumulator = 0.0;
|
||||
let mut total = 0;
|
||||
for _ in 0..8 {
|
||||
let (lines, remainder) = accumulate_wheel_lines(0.125, accumulator);
|
||||
accumulator = remainder;
|
||||
total += lines;
|
||||
}
|
||||
assert_eq!(total, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_lines_preserve_direction() {
|
||||
let (down, _) = accumulate_wheel_lines(0.25, 0.0);
|
||||
let (up, _) = accumulate_wheel_lines(-0.25, 0.0);
|
||||
assert_eq!(down, 1);
|
||||
assert_eq!(up, -1);
|
||||
}
|
||||
|
||||
const BUFFER_HEIGHT: f32 = 200.0;
|
||||
const CELL_HEIGHT: f32 = 20.0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue