Improve SGR Scroll Wheel support
This commit is contained in:
parent
01b7b1c9d9
commit
e91bf807ec
3 changed files with 78 additions and 12 deletions
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 } => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue