aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/event.rs4
-rw-r--r--src/input.rs99
-rw-r--r--src/term/mod.rs39
3 files changed, 92 insertions, 50 deletions
diff --git a/src/event.rs b/src/event.rs
index 8c4107ca..770ac53e 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -148,6 +148,8 @@ pub struct Mouse {
pub x: u32,
pub y: u32,
pub left_button_state: ElementState,
+ pub middle_button_state: ElementState,
+ pub right_button_state: ElementState,
pub last_click_timestamp: Instant,
pub click_state: ClickState,
pub scroll_px: i32,
@@ -164,6 +166,8 @@ impl Default for Mouse {
y: 0,
last_click_timestamp: Instant::now(),
left_button_state: ElementState::Released,
+ middle_button_state: ElementState::Released,
+ right_button_state: ElementState::Released,
click_state: ClickState::None,
scroll_px: 0,
line: Line(0),
diff --git a/src/input.rs b/src/input.rs
index ff1eb796..06fd5e5b 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -278,21 +278,33 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
};
self.ctx.mouse_mut().cell_side = cell_side;
- if self.ctx.mouse_mut().left_button_state == ElementState::Pressed {
- let report_mode = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_MOTION;
- if modifiers.shift || !self.ctx.terminal_mode().intersects(report_mode) {
- self.ctx.update_selection(Point {
- line: point.line,
- col: point.col
- }, cell_side);
- } else if self.ctx.terminal_mode().contains(mode::TermMode::MOUSE_MOTION)
- // Only report motion when changing cells
- && (
- prev_line != self.ctx.mouse_mut().line
- || prev_col != self.ctx.mouse_mut().column
- )
- {
- self.mouse_report(32, ElementState::Pressed);
+ let report_mode = mode::TermMode::MOUSE_REPORT_CLICK;
+ let motion_mode = mode::TermMode::MOUSE_MOTION | mode::TermMode::MOUSE_DRAG;
+ if self.ctx.mouse_mut().left_button_state == ElementState::Pressed
+ && (
+ modifiers.shift
+ || !self.ctx.terminal_mode().intersects(report_mode | motion_mode)
+ )
+ {
+ self.ctx.update_selection(Point {
+ line: point.line,
+ col: point.col
+ }, cell_side);
+ } else if self.ctx.terminal_mode().intersects(motion_mode)
+ // Only report motion when changing cells
+ && (
+ prev_line != self.ctx.mouse_mut().line
+ || prev_col != self.ctx.mouse_mut().column
+ )
+ {
+ if self.ctx.mouse_mut().left_button_state == ElementState::Pressed {
+ self.mouse_report(32 + 0, ElementState::Pressed);
+ } else if self.ctx.mouse_mut().middle_button_state == ElementState::Pressed {
+ self.mouse_report(32 + 1, ElementState::Pressed);
+ } else if self.ctx.mouse_mut().right_button_state == ElementState::Pressed {
+ self.mouse_report(32 + 2, ElementState::Pressed);
+ } else if self.ctx.terminal_mode().contains(mode::TermMode::MOUSE_MOTION) {
+ self.mouse_report(32 + 3, ElementState::Pressed);
}
}
}
@@ -330,7 +342,11 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
if self.ctx.terminal_mode().contains(mode::TermMode::SGR_MOUSE) {
self.sgr_mouse_report(button, state);
} else {
- self.normal_mouse_report(button);
+ if let ElementState::Released = state {
+ self.normal_mouse_report(3);
+ } else {
+ self.normal_mouse_report(button);
+ }
}
}
@@ -346,7 +362,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
}
- pub fn on_mouse_press(&mut self, modifiers: ModifiersState) {
+ pub fn on_mouse_press(&mut self, button: MouseButton, modifiers: ModifiersState) {
let now = Instant::now();
let elapsed = self.ctx.mouse_mut().last_click_timestamp.elapsed();
self.ctx.mouse_mut().last_click_timestamp = now;
@@ -362,9 +378,15 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
},
_ => {
self.ctx.clear_selection();
- let report_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_MOTION;
+ let report_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_DRAG | mode::TermMode::MOUSE_MOTION;
if !modifiers.shift && self.ctx.terminal_mode().intersects(report_modes) {
- self.mouse_report(0, ElementState::Pressed);
+ match button {
+ MouseButton::Left => self.mouse_report(0, ElementState::Pressed),
+ MouseButton::Middle => self.mouse_report(1, ElementState::Pressed),
+ MouseButton::Right => self.mouse_report(2, ElementState::Pressed),
+ // Can't properly report more than three buttons.
+ MouseButton::Other(_) => (),
+ };
return;
}
@@ -373,11 +395,17 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
};
}
- pub fn on_mouse_release(&mut self, modifiers: ModifiersState) {
- let report_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_MOTION;
+ pub fn on_mouse_release(&mut self, button: MouseButton, modifiers: ModifiersState) {
+ let report_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_DRAG | mode::TermMode::MOUSE_MOTION;
if !modifiers.shift && self.ctx.terminal_mode().intersects(report_modes)
{
- self.mouse_report(3, ElementState::Released);
+ match button {
+ MouseButton::Left => self.mouse_report(0, ElementState::Released),
+ MouseButton::Middle => self.mouse_report(1, ElementState::Released),
+ MouseButton::Right => self.mouse_report(2, ElementState::Released),
+ // Can't properly report more than three buttons.
+ MouseButton::Other(_) => (),
+ };
return;
}
@@ -385,7 +413,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
pub fn on_mouse_wheel(&mut self, delta: MouseScrollDelta, phase: TouchPhase) {
- let mouse_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_MOTION | mode::TermMode::SGR_MOUSE;
+ let mouse_modes = mode::TermMode::MOUSE_REPORT_CLICK | mode::TermMode::MOUSE_DRAG | mode::TermMode::MOUSE_MOTION | mode::TermMode::SGR_MOUSE;
if !self.ctx.terminal_mode().intersects(mouse_modes | mode::TermMode::ALT_SCREEN) {
return;
}
@@ -466,17 +494,20 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
pub fn mouse_input(&mut self, state: ElementState, button: MouseButton, modifiers: ModifiersState) {
- if let MouseButton::Left = button {
- let state = mem::replace(&mut self.ctx.mouse_mut().left_button_state, state);
- if self.ctx.mouse_mut().left_button_state != state {
- match self.ctx.mouse_mut().left_button_state {
- ElementState::Pressed => {
- self.on_mouse_press(modifiers);
- },
- ElementState::Released => {
- self.on_mouse_release(modifiers);
- }
- }
+ let button_state = match button {
+ MouseButton::Left => Some(mem::replace(&mut self.ctx.mouse_mut().left_button_state, state)),
+ MouseButton::Middle => Some(mem::replace(&mut self.ctx.mouse_mut().middle_button_state, state)),
+ MouseButton::Right => Some(mem::replace(&mut self.ctx.mouse_mut().right_button_state, state)),
+ // Can't properly report more than three buttons.
+ MouseButton::Other(_) => None,
+ };
+
+ if let Some(button_state) = button_state {
+ if button_state != state {
+ match state {
+ ElementState::Pressed => self.on_mouse_press(button, modifiers),
+ ElementState::Released => self.on_mouse_release(button, modifiers),
+ };
}
}
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 88e4b63c..5ba192ff 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -418,20 +418,21 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
pub mod mode {
bitflags! {
pub struct TermMode: u16 {
- const SHOW_CURSOR = 0b0_0000_0000_0001;
- const APP_CURSOR = 0b0_0000_0000_0010;
- const APP_KEYPAD = 0b0_0000_0000_0100;
- const MOUSE_REPORT_CLICK = 0b0_0000_0000_1000;
- const BRACKETED_PASTE = 0b0_0000_0001_0000;
- const SGR_MOUSE = 0b0_0000_0010_0000;
- const MOUSE_MOTION = 0b0_0000_0100_0000;
- const LINE_WRAP = 0b0_0000_1000_0000;
- const LINE_FEED_NEW_LINE = 0b0_0001_0000_0000;
- const ORIGIN = 0b0_0010_0000_0000;
- const INSERT = 0b0_0100_0000_0000;
- const FOCUS_IN_OUT = 0b0_1000_0000_0000;
- const ALT_SCREEN = 0b1_0000_0000_0000;
- const ANY = 0b1_1111_1111_1111;
+ const SHOW_CURSOR = 0b00_0000_0000_0001;
+ const APP_CURSOR = 0b00_0000_0000_0010;
+ const APP_KEYPAD = 0b00_0000_0000_0100;
+ const MOUSE_REPORT_CLICK = 0b00_0000_0000_1000;
+ const BRACKETED_PASTE = 0b00_0000_0001_0000;
+ const SGR_MOUSE = 0b00_0000_0010_0000;
+ const MOUSE_MOTION = 0b00_0000_0100_0000;
+ const LINE_WRAP = 0b00_0000_1000_0000;
+ const LINE_FEED_NEW_LINE = 0b00_0001_0000_0000;
+ const ORIGIN = 0b00_0010_0000_0000;
+ const INSERT = 0b00_0100_0000_0000;
+ const FOCUS_IN_OUT = 0b00_1000_0000_0000;
+ const ALT_SCREEN = 0b01_0000_0000_0000;
+ const MOUSE_DRAG = 0b10_0000_0000_0000;
+ const ANY = 0b11_1111_1111_1111;
const NONE = 0;
}
}
@@ -1832,7 +1833,10 @@ impl ansi::Handler for Term {
self.mode.insert(mode::TermMode::MOUSE_REPORT_CLICK);
self.set_mouse_cursor(MouseCursor::Arrow);
},
- ansi::Mode::ReportCellMouseMotion |
+ ansi::Mode::ReportCellMouseMotion => {
+ self.mode.insert(mode::TermMode::MOUSE_DRAG);
+ self.set_mouse_cursor(MouseCursor::Arrow);
+ },
ansi::Mode::ReportAllMouseMotion => {
self.mode.insert(mode::TermMode::MOUSE_MOTION);
self.set_mouse_cursor(MouseCursor::Arrow);
@@ -1869,7 +1873,10 @@ impl ansi::Handler for Term {
self.mode.remove(mode::TermMode::MOUSE_REPORT_CLICK);
self.set_mouse_cursor(MouseCursor::Text);
},
- ansi::Mode::ReportCellMouseMotion |
+ ansi::Mode::ReportCellMouseMotion => {
+ self.mode.remove(mode::TermMode::MOUSE_DRAG);
+ self.set_mouse_cursor(MouseCursor::Text);
+ },
ansi::Mode::ReportAllMouseMotion => {
self.mode.remove(mode::TermMode::MOUSE_MOTION);
self.set_mouse_cursor(MouseCursor::Text);