summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2023-01-16 20:22:01 +0300
committerGitHub <noreply@github.com>2023-01-16 20:22:01 +0300
commited67aa3c081950a55a8dc7fa1bd9c626f6e7a187 (patch)
treef4b887e3112a7f04698572c30856446d29e3ec4a
parent5a3280e8e0184c94e7a3f0a89676090d0694408d (diff)
Add support for horizontal scrolling
This adds support for horizontal mouse scrolling in mouse mode and alternative scrolling modes. Fixes #2185.
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty/src/event.rs14
-rw-r--r--alacritty/src/input.rs64
3 files changed, 60 insertions, 19 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2c8ce41..40855955 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- Uppercase `-T` short form for `--title`
+- Support for horizontal scrolling in mouse mode and alternative scrolling modes
### Changed
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 2fb60b2a..9388b8a9 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -1033,7 +1033,7 @@ pub struct Mouse {
pub last_click_timestamp: Instant,
pub last_click_button: MouseButton,
pub click_state: ClickState,
- pub scroll_px: f64,
+ pub accumulated_scroll: AccumulatedScroll,
pub cell_side: Side,
pub lines_scrolled: f32,
pub block_hint_launcher: bool,
@@ -1057,7 +1057,7 @@ impl Default for Mouse {
block_hint_launcher: Default::default(),
inside_text_area: Default::default(),
lines_scrolled: Default::default(),
- scroll_px: Default::default(),
+ accumulated_scroll: Default::default(),
x: Default::default(),
y: Default::default(),
}
@@ -1081,6 +1081,16 @@ impl Mouse {
}
}
+/// The amount of scroll accumulated from the pointer events.
+#[derive(Default, Debug)]
+pub struct AccumulatedScroll {
+ /// Scroll we should perform along `x` axis.
+ pub x: f64,
+
+ /// Scroll we should perform along `y` axis.
+ pub y: f64,
+}
+
impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
/// Handle events from winit.
pub fn handle_event(&mut self, event: WinitEvent<'_, Event>) {
diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs
index c8d948ff..33be1bf3 100644
--- a/alacritty/src/input.rs
+++ b/alacritty/src/input.rs
@@ -631,18 +631,19 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
pub fn mouse_wheel_input(&mut self, delta: MouseScrollDelta, phase: TouchPhase) {
match delta {
- MouseScrollDelta::LineDelta(_columns, lines) => {
- let new_scroll_px = lines * self.ctx.size_info().cell_height();
- self.scroll_terminal(f64::from(new_scroll_px));
+ MouseScrollDelta::LineDelta(columns, lines) => {
+ let new_scroll_px_x = columns * self.ctx.size_info().cell_width();
+ let new_scroll_px_y = lines * self.ctx.size_info().cell_height();
+ self.scroll_terminal(new_scroll_px_x as f64, new_scroll_px_y as f64);
},
MouseScrollDelta::PixelDelta(lpos) => {
match phase {
TouchPhase::Started => {
// Reset offset to zero.
- self.ctx.mouse_mut().scroll_px = 0.;
+ self.ctx.mouse_mut().accumulated_scroll = Default::default();
},
TouchPhase::Moved => {
- self.scroll_terminal(lpos.y);
+ self.scroll_terminal(lpos.x, lpos.y);
},
_ => (),
}
@@ -650,18 +651,32 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
}
}
- fn scroll_terminal(&mut self, new_scroll_px: f64) {
+ fn scroll_terminal(&mut self, new_scroll_x_px: f64, new_scroll_y_px: f64) {
+ const MOUSE_WHEEL_UP: u8 = 64;
+ const MOUSE_WHEEL_DOWN: u8 = 65;
+ const MOUSE_WHEEL_LEFT: u8 = 66;
+ const MOUSE_WHEEL_RIGHT: u8 = 67;
+
+ let width = f64::from(self.ctx.size_info().cell_width());
let height = f64::from(self.ctx.size_info().cell_height());
if self.ctx.mouse_mode() {
- self.ctx.mouse_mut().scroll_px += new_scroll_px;
+ self.ctx.mouse_mut().accumulated_scroll.x += new_scroll_x_px;
+ self.ctx.mouse_mut().accumulated_scroll.y += new_scroll_y_px;
- let code = if new_scroll_px > 0. { 64 } else { 65 };
- let lines = (self.ctx.mouse().scroll_px / height).abs() as i32;
+ let code = if new_scroll_y_px > 0. { MOUSE_WHEEL_UP } else { MOUSE_WHEEL_DOWN };
+ let lines = (self.ctx.mouse().accumulated_scroll.y / height).abs() as i32;
for _ in 0..lines {
self.mouse_report(code, ElementState::Pressed);
}
+
+ let code = if new_scroll_x_px > 0. { MOUSE_WHEEL_LEFT } else { MOUSE_WHEEL_RIGHT };
+ let columns = (self.ctx.mouse().accumulated_scroll.x / width).abs() as i32;
+
+ for _ in 0..columns {
+ self.mouse_report(code, ElementState::Pressed);
+ }
} else if self
.ctx
.terminal()
@@ -670,30 +685,45 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
&& !self.ctx.modifiers().shift()
{
let multiplier = f64::from(self.ctx.config().terminal_config.scrolling.multiplier);
- self.ctx.mouse_mut().scroll_px += new_scroll_px * multiplier;
- let cmd = if new_scroll_px > 0. { b'A' } else { b'B' };
- let lines = (self.ctx.mouse().scroll_px / height).abs() as i32;
+ self.ctx.mouse_mut().accumulated_scroll.x += new_scroll_x_px * multiplier;
+ self.ctx.mouse_mut().accumulated_scroll.y += new_scroll_y_px * multiplier;
+
+ // The chars here are the same as for the respective arrow keys.
+ let line_cmd = if new_scroll_y_px > 0. { b'A' } else { b'B' };
+ let column_cmd = if new_scroll_x_px > 0. { b'D' } else { b'C' };
+
+ let lines = (self.ctx.mouse().accumulated_scroll.y / height).abs() as usize;
+ let columns = (self.ctx.mouse().accumulated_scroll.x / width).abs() as usize;
+
+ let mut content = Vec::with_capacity(3 * (lines + columns));
- let mut content = Vec::with_capacity(lines as usize * 3);
for _ in 0..lines {
content.push(0x1b);
content.push(b'O');
- content.push(cmd);
+ content.push(line_cmd);
+ }
+
+ for _ in 0..columns {
+ content.push(0x1b);
+ content.push(b'O');
+ content.push(column_cmd);
}
+
self.ctx.write_to_pty(content);
} else {
let multiplier = f64::from(self.ctx.config().terminal_config.scrolling.multiplier);
- self.ctx.mouse_mut().scroll_px += new_scroll_px * multiplier;
+ self.ctx.mouse_mut().accumulated_scroll.y += new_scroll_y_px * multiplier;
- let lines = (self.ctx.mouse().scroll_px / height) as i32;
+ let lines = (self.ctx.mouse().accumulated_scroll.y / height) as i32;
if lines != 0 {
self.ctx.scroll(Scroll::Delta(lines));
}
}
- self.ctx.mouse_mut().scroll_px %= height;
+ self.ctx.mouse_mut().accumulated_scroll.x %= width;
+ self.ctx.mouse_mut().accumulated_scroll.y %= height;
}
pub fn on_focus_change(&mut self, is_focused: bool) {