Improve SGR Scroll Wheel support

This commit is contained in:
Mattias Eriksson 2024-01-31 15:43:20 +01:00 committed by Jeremy Soller
parent 01b7b1c9d9
commit e91bf807ec
3 changed files with 78 additions and 12 deletions

View file

@ -172,9 +172,50 @@ impl MouseReporter {
}
}
pub fn report_sgr_mouse_wheel_scroll(
&self,
terminal: &Terminal,
term_cell_width: f32,
term_cell_height: f32,
delta: ScrollDelta,
modifiers: &Modifiers,
x: u32,
y: u32,
) {
let (delta_x, delta_y) = match delta {
ScrollDelta::Lines { x, y } => (x, y),
ScrollDelta::Pixels { x, y } => (x / term_cell_width, y / term_cell_height),
};
let (mut button_no, amount) = if delta_y > 0.0 {
(64, delta_y.abs()) //Wheel UP
} else if delta_y < 0.0 {
(65, delta_y.abs()) //Wheel Down
} else if delta_x < 0.0 {
(66, delta_x.abs()) //Wheel Left
} else if delta_x > 0.0 {
(67, delta_x.abs()) //Wheel Right
} else {
return;
};
if modifiers.shift() {
button_no += 4;
}
if modifiers.alt() {
button_no += 8;
}
if modifiers.control() {
button_no += 16;
}
let term_code = format!("\x1b[<{};{};{}M", button_no, x + 1, y + 1);
for _ in 0..amount as u32 {
terminal.input_no_scroll(term_code.as_bytes().to_vec());
}
}
//Emulate mouse wheel scroll with up/down arrows. Using mouse spec uses
//scroll-back and scroll-forw actions, which moves whole windows like page up/page down.
pub fn report_mouse_wheel_scroll(
pub fn report_mouse_wheel_as_arrows(
&self,
terminal: &Terminal,
term_cell_width: f32,
@ -188,9 +229,9 @@ impl MouseReporter {
//Send delta_y * SCROLL_SPEED number of Up/Down arrows
for _ in 0..(delta_y.abs() as u32 * SCROLL_SPEED) {
if delta_y > 0.0 {
terminal.input_no_scroll(b"\x1B[1;3A".as_slice())
terminal.input_no_scroll(b"\x1B[A".as_slice())
} else if delta_y < 0.0 {
terminal.input_no_scroll(b"\x1B[1;3B".as_slice())
terminal.input_no_scroll(b"\x1B[B".as_slice())
}
}
}

View file

@ -805,13 +805,33 @@ impl Terminal {
}
}
}
pub fn scroll_mouse(&mut self, delta: ScrollDelta) {
self.mouse_reporter.report_mouse_wheel_scroll(
self,
self.size().cell_width,
self.size().cell_height,
delta,
);
pub fn scroll_mouse(
&mut self,
delta: ScrollDelta,
modifiers: &cosmic::iced::keyboard::Modifiers,
x: u32,
y: u32,
) {
let term_lock = self.term.lock();
let mode = term_lock.mode();
if mode.contains(TermMode::SGR_MOUSE) {
self.mouse_reporter.report_sgr_mouse_wheel_scroll(
self,
self.size().cell_width,
self.size().cell_height,
delta,
modifiers,
x,
y,
);
} else {
self.mouse_reporter.report_mouse_wheel_as_arrows(
self,
self.size().cell_width,
self.size().cell_height,
delta,
);
}
}
}

View file

@ -1191,9 +1191,14 @@ where
}
}
Event::Mouse(MouseEvent::WheelScrolled { delta }) => {
if let Some(_p) = cursor_position.position_in(layout.bounds()) {
if let Some(p) = cursor_position.position_in(layout.bounds()) {
if is_mouse_mode {
terminal.scroll_mouse(delta);
let x = (p.x - layout.bounds().x) - self.padding.left;
let y = (p.y - layout.bounds().y) - self.padding.top;
//TODO: better calculation of position
let col = x / terminal.size().cell_width;
let row = y / terminal.size().cell_height;
terminal.scroll_mouse(delta, &state.modifiers, col as u32, row as u32);
} else {
match delta {
ScrollDelta::Lines { x: _, y } => {