Implement faux scrolling

This patch implements faux scrolling inside the alternate screen buffer.

Whenever the user scrolls up or down while the alternate screen buffer
is active, instead of actual scrolling three up/down arrow keys are
inserted.
This commit is contained in:
Christian Duerr 2017-12-16 15:46:28 +01:00 committed by Joe Wilm
parent 41296a555e
commit e0993587e7
2 changed files with 47 additions and 21 deletions

View File

@ -365,7 +365,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
pub fn on_mouse_wheel(&mut self, delta: MouseScrollDelta, phase: TouchPhase) {
let modes = mode::MOUSE_REPORT_CLICK | mode::MOUSE_MOTION | mode::SGR_MOUSE;
let modes = mode::MOUSE_REPORT_CLICK | mode::MOUSE_MOTION | mode::SGR_MOUSE | mode::ALT_SCREEN_BUF;
if !self.ctx.terminal_mode().intersects(modes) {
return;
}
@ -374,6 +374,18 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
MouseScrollDelta::LineDelta(_columns, lines) => {
let to_scroll = self.ctx.mouse_mut().lines_scrolled + lines;
// Faux scrolling
if self.ctx.terminal_mode().intersects(mode::ALT_SCREEN_BUF) {
if to_scroll > 0. {
// Scroll up three lines
self.ctx.write_to_pty("\x1bOA\x1bOA\x1bOA".as_bytes());
} else {
// Scroll down three lines
self.ctx.write_to_pty("\x1bOB\x1bOB\x1bOB".as_bytes());
}
return;
}
let code = if to_scroll > 0.0 {
64
} else {
@ -396,15 +408,26 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
let height = self.ctx.size_info().cell_height as i32;
while self.ctx.mouse_mut().scroll_px.abs() >= height {
let button = if self.ctx.mouse_mut().scroll_px > 0 {
self.ctx.mouse_mut().scroll_px -= height;
64
if self.ctx.terminal_mode().intersects(mode::ALT_SCREEN_BUF) {
// Faux scrolling
if self.ctx.mouse_mut().scroll_px > 0 {
// Scroll up three lines
self.ctx.write_to_pty("\x1bOA\x1bOA\x1bOA".as_bytes());
} else {
// Scroll down three lines
self.ctx.write_to_pty("\x1bOB\x1bOB\x1bOB".as_bytes());
}
} else {
self.ctx.mouse_mut().scroll_px += height;
65
};
let button = if self.ctx.mouse_mut().scroll_px > 0 {
self.ctx.mouse_mut().scroll_px -= height;
64
} else {
self.ctx.mouse_mut().scroll_px += height;
65
};
self.normal_mouse_report(button);
self.normal_mouse_report(button);
}
}
},
_ => (),

View File

@ -416,19 +416,20 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
pub mod mode {
bitflags! {
pub struct TermMode: u16 {
const SHOW_CURSOR = 0b000000000001;
const APP_CURSOR = 0b000000000010;
const APP_KEYPAD = 0b000000000100;
const MOUSE_REPORT_CLICK = 0b000000001000;
const BRACKETED_PASTE = 0b000000010000;
const SGR_MOUSE = 0b000000100000;
const MOUSE_MOTION = 0b000001000000;
const LINE_WRAP = 0b000010000000;
const LINE_FEED_NEW_LINE = 0b000100000000;
const ORIGIN = 0b001000000000;
const INSERT = 0b010000000000;
const FOCUS_IN_OUT = 0b100000000000;
const ANY = 0b111111111111;
const SHOW_CURSOR = 0b0000000000001;
const APP_CURSOR = 0b0000000000010;
const APP_KEYPAD = 0b0000000000100;
const MOUSE_REPORT_CLICK = 0b0000000001000;
const BRACKETED_PASTE = 0b0000000010000;
const SGR_MOUSE = 0b0000000100000;
const MOUSE_MOTION = 0b0000001000000;
const LINE_WRAP = 0b0000010000000;
const LINE_FEED_NEW_LINE = 0b0000100000000;
const ORIGIN = 0b0001000000000;
const INSERT = 0b0010000000000;
const FOCUS_IN_OUT = 0b0100000000000;
const ALT_SCREEN_BUF = 0b1000000000000;
const ANY = 0b1111111111111;
const NONE = 0;
}
}
@ -1789,6 +1790,7 @@ impl ansi::Handler for Term {
trace!("set_mode: {:?}", mode);
match mode {
ansi::Mode::SwapScreenAndSetRestoreCursor => {
self.mode.insert(mode::ALT_SCREEN_BUF);
self.save_cursor_position();
if !self.alt {
self.swap_alt();
@ -1818,6 +1820,7 @@ impl ansi::Handler for Term {
trace!("unset_mode: {:?}", mode);
match mode {
ansi::Mode::SwapScreenAndSetRestoreCursor => {
self.mode.remove(mode::ALT_SCREEN_BUF);
self.restore_cursor_position();
if self.alt {
self.swap_alt();