Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 25 additions & 44 deletions src/mouse_reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ use cosmic::{
iced::{Event, keyboard::Modifiers, mouse::Button},
};

use crate::terminal::Terminal;

const SCROLL_SPEED: u32 = 3;

#[derive(Default)]
pub struct MouseReporter {
last_movment_x: Option<u32>,
Expand All @@ -17,6 +13,30 @@ pub struct MouseReporter {
}

impl MouseReporter {
pub fn accumulate_scroll(
&mut self,
delta: ScrollDelta,
cell_width: f32,
cell_height: f32,
) -> (i32, i32) {
match delta {
ScrollDelta::Lines { x, y } => {
self.accumulated_scroll_x += x;
self.accumulated_scroll_y += y;
}
ScrollDelta::Pixels { x, y } => {
self.accumulated_scroll_x += x / cell_width;
self.accumulated_scroll_y += y / cell_height;
}
}

let lines_x = self.accumulated_scroll_x as i32;
let lines_y = self.accumulated_scroll_y as i32;
self.accumulated_scroll_x -= lines_x as f32;
self.accumulated_scroll_y -= lines_y as f32;
(lines_x, lines_y)
}

fn button_number(button: Button) -> Option<u8> {
match button {
Button::Left => Some(0),
Expand Down Expand Up @@ -178,24 +198,7 @@ impl MouseReporter {
x: u32,
y: u32,
) -> impl Iterator<Item = Vec<u8>> {
let (lines_x, lines_y) = match delta {
ScrollDelta::Lines { x, y } => (x as i32, y as i32),
ScrollDelta::Pixels { x, y } => {
//Accumulate change
self.accumulated_scroll_x += x / term_cell_width;
self.accumulated_scroll_y += y / term_cell_height;

//Resolve lines crossed
let lines_x = self.accumulated_scroll_x as i32;
let lines_y = self.accumulated_scroll_y as i32;

//Subtract accounted lines from accumulators
self.accumulated_scroll_x -= lines_x as f32;
self.accumulated_scroll_y -= lines_y as f32;

(lines_x, lines_y)
}
};
let (lines_x, lines_y) = self.accumulate_scroll(delta, term_cell_width, term_cell_height);

//Resolve modifier flags
let mut modifier_flags = 0;
Expand Down Expand Up @@ -235,26 +238,4 @@ impl MouseReporter {
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_as_arrows(
terminal: &Terminal,
term_cell_width: f32,
term_cell_height: f32,
delta: ScrollDelta,
) {
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),
};
//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[A".as_slice())
} else if delta_y < 0.0 {
terminal.input_no_scroll(b"\x1B[B".as_slice())
}
}
}
}
34 changes: 25 additions & 9 deletions src/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1025,10 +1025,9 @@ impl Terminal {
x: u32,
y: u32,
) {
let term_lock = self.term.lock();
let mode = term_lock.mode();
let is_sgr = self.term.lock().mode().contains(TermMode::SGR_MOUSE);

if mode.contains(TermMode::SGR_MOUSE) {
if is_sgr {
let codes = self.mouse_reporter.sgr_mouse_wheel_scroll(
self.size().cell_width,
self.size().cell_height,
Expand All @@ -1042,12 +1041,29 @@ impl Terminal {
self.notifier.notify(code);
}
} else {
MouseReporter::report_mouse_wheel_as_arrows(
self,
self.size().cell_width,
self.size().cell_height,
delta,
);
self.scroll_as_arrows(delta);
}
}

pub fn scroll_as_arrows(&mut self, delta: ScrollDelta) {
let cell_width = self.size().cell_width;
let cell_height = self.size().cell_height;
let (_, lines_y) = self
.mouse_reporter
.accumulate_scroll(delta, cell_width, cell_height);
let is_app_cursor = self.term.lock().mode().contains(TermMode::APP_CURSOR);
let (up, down) = if is_app_cursor {
(&b"\x1BOA"[..], &b"\x1BOB"[..])
} else {
(&b"\x1B[A"[..], &b"\x1B[B"[..])
};
const SCROLL_SPEED: u32 = 3;
for _ in 0..(lines_y.unsigned_abs() * SCROLL_SPEED) {
if lines_y > 0 {
self.input_no_scroll(up)
} else if lines_y < 0 {
self.input_no_scroll(down)
}
}
}
}
Expand Down
12 changes: 2 additions & 10 deletions src/terminal_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ use std::{
time::{Duration, Instant},
};

use crate::{
Action, Terminal, TerminalScroll, menu::MenuState, mouse_reporter::MouseReporter,
terminal::Metadata,
};
use crate::{Action, Terminal, TerminalScroll, menu::MenuState, terminal::Metadata};

const AUTOSCROLL_INTERVAL: Duration = Duration::from_millis(100);

Expand Down Expand Up @@ -1551,12 +1548,7 @@ where
let row = y / terminal.size().cell_height;
terminal.scroll_mouse(*delta, &state.modifiers, col as u32, row as u32);
} else if terminal.term.lock().mode().contains(TermMode::ALT_SCREEN) {
MouseReporter::report_mouse_wheel_as_arrows(
&terminal,
terminal.size().cell_width,
terminal.size().cell_height,
*delta,
);
terminal.scroll_as_arrows(*delta);
shell.capture_event();
} else {
match delta {
Expand Down
Loading