aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/event.rs12
-rw-r--r--src/input.rs74
3 files changed, 55 insertions, 32 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 756bc5e8..a228ad49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix build failure on 32-bit systems
- Windows started as unfocused now show the hollow cursor if the setting is enabled
- Empty lines in selections are now properly copied to the clipboard
+- Selection start point lagging behind initial cursor position
### Deprecated
diff --git a/src/event.rs b/src/event.rs
index da63d5fd..9db0680d 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -82,17 +82,14 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> {
}
fn update_selection(&mut self, point: Point, side: Side) {
- self.terminal.dirty = true;
let point = self.terminal.visible_to_buffer(point);
// Update selection if one exists
- if let Some(ref mut selection) = *self.terminal.selection_mut() {
+ if let Some(ref mut selection) = self.terminal.selection_mut() {
selection.update(point, side);
- return;
}
- // Otherwise, start a regular selection
- *self.terminal.selection_mut() = Some(Selection::simple(point, side));
+ self.terminal.dirty = true;
}
fn simple_selection(&mut self, point: Point, side: Side) {
@@ -131,6 +128,11 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> {
}
#[inline]
+ fn mouse(&self) -> &Mouse {
+ self.mouse
+ }
+
+ #[inline]
fn received_count(&mut self) -> &mut usize {
&mut self.received_count
}
diff --git a/src/input.rs b/src/input.rs
index 59b6605e..cc3f13df 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -63,6 +63,7 @@ pub trait ActionContext {
fn semantic_selection(&mut self, point: Point);
fn line_selection(&mut self, point: Point);
fn mouse_mut(&mut self) -> &mut Mouse;
+ fn mouse(&self) -> &Mouse;
fn mouse_coords(&self) -> Option<Point>;
fn received_count(&mut self) -> &mut usize;
fn suppress_chars(&mut self) -> &mut bool;
@@ -318,41 +319,27 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
let prev_line = mem::replace(&mut self.ctx.mouse_mut().line, point.line);
let prev_col = mem::replace(&mut self.ctx.mouse_mut().column, point.col);
- let cell_x = x.saturating_sub(size_info.padding_x as usize) % size_info.cell_width as usize;
- let half_cell_width = (size_info.cell_width / 2.0) as usize;
-
- let additional_padding = (size_info.width - size_info.padding_x * 2.) % size_info.cell_width;
- let end_of_grid = size_info.width - size_info.padding_x - additional_padding;
- let cell_side = if cell_x > half_cell_width
- // Edge case when mouse leaves the window
- || x as f32 >= end_of_grid
- {
- Side::Right
- } else {
- Side::Left
- };
- self.ctx.mouse_mut().cell_side = cell_side;
-
let motion_mode = TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG;
let report_mode = TermMode::MOUSE_REPORT_CLICK | motion_mode;
- if self.ctx.mouse_mut().left_button_state == ElementState::Pressed &&
+ if self.ctx.mouse().left_button_state == ElementState::Pressed &&
( modifiers.shift || !self.ctx.terminal_mode().intersects(report_mode))
{
+ let cell_side = self.get_mouse_side();
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)
+ && (prev_line != self.ctx.mouse().line || prev_col != self.ctx.mouse().column)
&& size_info.contains_point(x, y)
{
- if self.ctx.mouse_mut().left_button_state == ElementState::Pressed {
+ if self.ctx.mouse().left_button_state == ElementState::Pressed {
self.mouse_report(32, ElementState::Pressed, modifiers);
- } else if self.ctx.mouse_mut().middle_button_state == ElementState::Pressed {
+ } else if self.ctx.mouse().middle_button_state == ElementState::Pressed {
self.mouse_report(33, ElementState::Pressed, modifiers);
- } else if self.ctx.mouse_mut().right_button_state == ElementState::Pressed {
+ } else if self.ctx.mouse().right_button_state == ElementState::Pressed {
self.mouse_report(34, ElementState::Pressed, modifiers);
} else if self.ctx.terminal_mode().contains(TermMode::MOUSE_MOTION) {
self.mouse_report(35, ElementState::Pressed, modifiers);
@@ -361,7 +348,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
pub fn normal_mouse_report(&mut self, button: u8) {
- let (line, column) = (self.ctx.mouse_mut().line, self.ctx.mouse_mut().column);
+ let (line, column) = (self.ctx.mouse().line, self.ctx.mouse().column);
if line < Line(223) && column < Column(223) {
let msg = vec![
@@ -378,7 +365,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
pub fn sgr_mouse_report(&mut self, button: u8, state: ElementState) {
- let (line, column) = (self.ctx.mouse_mut().line, self.ctx.mouse_mut().column);
+ let (line, column) = (self.ctx.mouse().line, self.ctx.mouse().column);
let c = match state {
ElementState::Pressed => 'M',
ElementState::Released => 'm',
@@ -425,10 +412,10 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
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();
+ let elapsed = self.ctx.mouse().last_click_timestamp.elapsed();
self.ctx.mouse_mut().last_click_timestamp = now;
- self.ctx.mouse_mut().click_state = match self.ctx.mouse_mut().click_state {
+ self.ctx.mouse_mut().click_state = match self.ctx.mouse().click_state {
ClickState::Click if elapsed < self.mouse_config.double_click.threshold => {
self.on_mouse_double_click();
ClickState::DoubleClick
@@ -439,6 +426,13 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
},
_ => {
self.ctx.clear_selection();
+
+ // Start new empty selection
+ if let Some(point) = self.ctx.mouse_coords() {
+ let side = self.get_mouse_side();
+ self.ctx.simple_selection(point, side);
+ }
+
let report_modes = TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
if !modifiers.shift && self.ctx.terminal_mode().intersects(report_modes) {
match button {
@@ -456,6 +450,26 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
};
}
+ fn get_mouse_side(&self) -> Side {
+ let size_info = self.ctx.size_info();
+ let x = self.ctx.mouse().x;
+
+ let cell_x = x.saturating_sub(size_info.padding_x as usize) % size_info.cell_width as usize;
+ let half_cell_width = (size_info.cell_width / 2.0) as usize;
+
+ let additional_padding = (size_info.width - size_info.padding_x * 2.) % size_info.cell_width;
+ let end_of_grid = size_info.width - size_info.padding_x - additional_padding;
+
+ if cell_x > half_cell_width
+ // Edge case when mouse leaves the window
+ || x as f32 >= end_of_grid
+ {
+ Side::Right
+ } else {
+ Side::Left
+ }
+ }
+
pub fn on_mouse_release(&mut self, button: MouseButton, modifiers: ModifiersState) {
let report_modes = TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
if !modifiers.shift && self.ctx.terminal_mode().intersects(report_modes)
@@ -479,7 +493,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
pub fn on_mouse_wheel(&mut self, delta: MouseScrollDelta, phase: TouchPhase, modifiers: ModifiersState) {
match delta {
MouseScrollDelta::LineDelta(_columns, lines) => {
- let to_scroll = self.ctx.mouse_mut().lines_scrolled + lines;
+ let to_scroll = self.ctx.mouse().lines_scrolled + lines;
let code = if to_scroll > 0.0 {
64
} else {
@@ -503,8 +517,8 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
self.ctx.mouse_mut().scroll_px += y as i32;
let height = self.ctx.size_info().cell_height as i32;
- while self.ctx.mouse_mut().scroll_px.abs() >= height {
- let code = if self.ctx.mouse_mut().scroll_px > 0 {
+ while self.ctx.mouse().scroll_px.abs() >= height {
+ let code = if self.ctx.mouse().scroll_px > 0 {
self.ctx.mouse_mut().scroll_px -= height;
64
} else {
@@ -757,6 +771,12 @@ mod tests {
fn mouse_mut(&mut self) -> &mut Mouse {
self.mouse
}
+
+ #[inline]
+ fn mouse(&self) -> &Mouse {
+ self.mouse
+ }
+
fn received_count(&mut self) -> &mut usize {
&mut self.received_count
}