fix(app): normalize trackpad scroll deltas on macOS (#694)
This commit is contained in:
parent
bd7124c873
commit
ff22c8ac3b
1 changed files with 36 additions and 6 deletions
|
|
@ -5,6 +5,30 @@ use crate::theme::colors;
|
|||
|
||||
const LAZY_OVERSCAN: i64 = 3;
|
||||
|
||||
pub(crate) fn normalize_wheel_delta(delta: f64, scale_factor: f64) -> f32 {
|
||||
if delta == 0.0 {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const FREYA_LINE_SPEED: f64 = 53.0;
|
||||
const FREYA_PIXEL_SPEED: f64 = 2.0;
|
||||
const LINE_DELTA_TOLERANCE: f64 = 1e-6;
|
||||
const LINE_SCROLL: f64 = 53.0;
|
||||
const PIXEL_SCROLL: f64 = 1.0;
|
||||
|
||||
let lines = (delta / FREYA_LINE_SPEED).round();
|
||||
if lines != 0.0 && (delta - lines * FREYA_LINE_SPEED).abs() <= LINE_DELTA_TOLERANCE {
|
||||
return (lines * LINE_SCROLL) as f32;
|
||||
}
|
||||
|
||||
let scale_factor = if scale_factor > 0.0 {
|
||||
scale_factor
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
(delta / (FREYA_PIXEL_SPEED * scale_factor) * PIXEL_SCROLL) as f32
|
||||
}
|
||||
|
||||
pub(crate) fn scroll_pos_from_wheel(wheel: f32, inner: f32, viewport: f32, current: f32) -> i32 {
|
||||
if viewport >= inner {
|
||||
return 0;
|
||||
|
|
@ -226,6 +250,8 @@ impl ScrollArea {
|
|||
let internal = use_scroll_controller(ScrollConfig::default);
|
||||
let mut controller = self.controller.unwrap_or(internal);
|
||||
|
||||
let scale_factor = Platform::get().scale_factor;
|
||||
|
||||
let mut viewport_h = use_state(|| 0f32);
|
||||
let mut viewport_w = use_state(|| 0f32);
|
||||
let mut viewport_top = use_state(|| 0f32);
|
||||
|
|
@ -310,17 +336,21 @@ impl ScrollArea {
|
|||
|
||||
let on_wheel = move |e: Event<WheelEventData>| {
|
||||
let shift = *shift_held.read();
|
||||
let scale = *scale_factor.peek();
|
||||
|
||||
let delta_x = normalize_wheel_delta(e.delta_x, scale);
|
||||
let delta_y = normalize_wheel_delta(e.delta_y, scale);
|
||||
|
||||
let h_delta = if horizontal {
|
||||
if shift && e.delta_x == 0.0 {
|
||||
e.delta_y
|
||||
if shift && delta_x == 0.0 {
|
||||
delta_y
|
||||
} else {
|
||||
e.delta_x
|
||||
delta_x
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let v_delta = if horizontal && shift { 0.0 } else { e.delta_y };
|
||||
let v_delta = if horizontal && shift { 0.0 } else { delta_y };
|
||||
|
||||
let do_h = h_delta != 0.0 && can_scroll_h;
|
||||
let do_v = v_delta != 0.0 && can_scroll_v;
|
||||
|
|
@ -337,14 +367,14 @@ impl ScrollArea {
|
|||
|
||||
if do_h {
|
||||
let cur_x = corrected_scroll(content_w, vp_w, *scroll_x.read());
|
||||
let new_x = scroll_pos_from_wheel(h_delta as f32, content_w, vp_w, cur_x);
|
||||
let new_x = scroll_pos_from_wheel(h_delta, content_w, vp_w, cur_x);
|
||||
scroll_x.set(new_x as f32);
|
||||
}
|
||||
|
||||
if do_v {
|
||||
let (_, cur_y) = controller.into();
|
||||
let current = corrected_scroll(ct_h, vp_h, cur_y as f32);
|
||||
let new_y = scroll_pos_from_wheel(v_delta as f32, ct_h, vp_h, current);
|
||||
let new_y = scroll_pos_from_wheel(v_delta, ct_h, vp_h, current);
|
||||
if new_y != cur_y {
|
||||
controller.scroll_to_y(new_y);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue