Improve touchpad scrolling

By scaling fractional scaling by scrolling multiplier
before conversion to lines it is now possible to scroll
much more accurately with touchpads.

The `scrolling.multiplier` now also applies to touchpads.
This commit is contained in:
ray851107 2019-01-27 21:06:27 +00:00 committed by Christian Duerr
parent 5e0d740943
commit fe8577ccfb
2 changed files with 39 additions and 43 deletions

View File

@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Changed
- Smoother scrolling for touchpads (also affects scrolling with some mice that send fractional scrolling values)
- `scrolling.multiplier` now affects normal scrolling with touchpads
### Fixed ### Fixed
- Resolved off-by-one issue with erasing characters in the last column - Resolved off-by-one issue with erasing characters in the last column

View File

@ -605,19 +605,8 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
pub fn on_mouse_wheel(&mut self, delta: MouseScrollDelta, phase: TouchPhase, modifiers: ModifiersState) { pub fn on_mouse_wheel(&mut self, delta: MouseScrollDelta, phase: TouchPhase, modifiers: ModifiersState) {
match delta { match delta {
MouseScrollDelta::LineDelta(_columns, lines) => { MouseScrollDelta::LineDelta(_columns, lines) => {
let to_scroll = self.ctx.mouse().lines_scrolled + lines; let new_scroll_px = lines * self.ctx.size_info().cell_height;
let code = if to_scroll > 0.0 { self.scroll_terminal(modifiers, new_scroll_px as i32);
64
} else {
65
};
let scrolling_multiplier = self.scrolling_config.multiplier;
for _ in 0..(to_scroll.abs() as usize) {
self.scroll_terminal(code, modifiers, scrolling_multiplier)
}
self.ctx.mouse_mut().lines_scrolled = to_scroll % 1.0;
}, },
MouseScrollDelta::PixelDelta(lpos) => { MouseScrollDelta::PixelDelta(lpos) => {
match phase { match phase {
@ -626,21 +615,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
self.ctx.mouse_mut().scroll_px = 0; self.ctx.mouse_mut().scroll_px = 0;
}, },
TouchPhase::Moved => { TouchPhase::Moved => {
let (_x, y): (i32, i32) = lpos.into(); self.scroll_terminal(modifiers, lpos.y as i32);
self.ctx.mouse_mut().scroll_px += y;
let height = self.ctx.size_info().cell_height as i32;
while self.ctx.mouse().scroll_px.abs() >= height {
let code = if self.ctx.mouse().scroll_px > 0 {
self.ctx.mouse_mut().scroll_px -= height;
64
} else {
self.ctx.mouse_mut().scroll_px += height;
65
};
self.scroll_terminal(code, modifiers, 1)
}
}, },
_ => (), _ => (),
} }
@ -648,36 +623,52 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
} }
} }
fn scroll_terminal(&mut self, code: u8, modifiers: ModifiersState, scroll_multiplier: u8) { fn scroll_terminal(&mut self, modifiers: ModifiersState, new_scroll_px: i32) {
debug_assert!(code == 64 || code == 65); let mouse_modes =
TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
let mouse_modes = TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION; let height = self.ctx.size_info().cell_height as i32;
// Make sure the new and deprecated setting are both allowed // Make sure the new and deprecated setting are both allowed
let faux_scrolling_lines = self.mouse_config let faux_multiplier = self
.mouse_config
.faux_scrollback_lines .faux_scrollback_lines
.unwrap_or(self.scrolling_config.faux_multiplier as usize); .unwrap_or(self.scrolling_config.faux_multiplier as usize);
if self.ctx.terminal_mode().intersects(mouse_modes) { if self.ctx.terminal_mode().intersects(mouse_modes) {
self.mouse_report(code, ElementState::Pressed, modifiers); self.ctx.mouse_mut().scroll_px += new_scroll_px;
let code = if new_scroll_px > 0 { 64 } else { 65 };
let lines = (self.ctx.mouse().scroll_px / height).abs();
for _ in 0..lines {
self.mouse_report(code, ElementState::Pressed, modifiers);
}
} else if self.ctx.terminal_mode().contains(TermMode::ALT_SCREEN) } else if self.ctx.terminal_mode().contains(TermMode::ALT_SCREEN)
&& faux_scrolling_lines > 0 && !modifiers.shift && faux_multiplier > 0
&& !modifiers.shift
{ {
// Faux scrolling self.ctx.mouse_mut().scroll_px += new_scroll_px * faux_multiplier as i32;
let cmd = code + 1; // 64 + 1 = A, 65 + 1 = B
let mut content = Vec::with_capacity(faux_scrolling_lines as usize * 3); let cmd = if new_scroll_px > 0 { b'A' } else { b'B' };
for _ in 0..faux_scrolling_lines { let lines = (self.ctx.mouse().scroll_px / height).abs();
let mut content = Vec::with_capacity(lines as usize * 3);
for _ in 0..lines {
content.push(0x1b); content.push(0x1b);
content.push(b'O'); content.push(b'O');
content.push(cmd); content.push(cmd);
} }
self.ctx.write_to_pty(content); self.ctx.write_to_pty(content);
} else { } else {
for _ in 0..scroll_multiplier { let multiplier = i32::from(self.scrolling_config.multiplier);
// Transform the reported button codes 64 and 65 into 1 and -1 lines to scroll self.ctx.mouse_mut().scroll_px += new_scroll_px * multiplier;
self.ctx.scroll(Scroll::Lines(-(code as isize * 2 - 129)));
} let lines = self.ctx.mouse().scroll_px / height;
self.ctx.scroll(Scroll::Lines(lines as isize));
} }
self.ctx.mouse_mut().scroll_px %= height;
} }
pub fn on_focus_change(&mut self, is_focused: bool) { pub fn on_focus_change(&mut self, is_focused: bool) {