aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event.rs12
-rw-r--r--src/input.rs61
-rw-r--r--src/selection.rs27
-rw-r--r--src/term/mod.rs22
4 files changed, 71 insertions, 51 deletions
diff --git a/src/event.rs b/src/event.rs
index af5053f4..c079ddfb 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -154,8 +154,8 @@ pub enum ClickState {
/// State of the mouse
pub struct Mouse {
- pub x: u32,
- pub y: u32,
+ pub x: usize,
+ pub y: usize,
pub left_button_state: ElementState,
pub last_click_timestamp: Instant,
pub click_state: ClickState,
@@ -311,13 +311,11 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.dirty = true;
},
CursorMoved { position: (x, y), modifiers, .. } => {
- let x = x as i32;
- let y = y as i32;
- let x = limit(x, 0, processor.ctx.size_info.width as i32);
- let y = limit(y, 0, processor.ctx.size_info.height as i32);
+ let x = limit(x as i32, 0, processor.ctx.size_info.width as i32);
+ let y = limit(y as i32, 0, processor.ctx.size_info.height as i32);
*hide_cursor = false;
- processor.mouse_moved(x as u32, y as u32, modifiers);
+ processor.mouse_moved(x as usize, y as usize, modifiers);
},
MouseWheel { delta, phase, modifiers, .. } => {
*hide_cursor = false;
diff --git a/src/input.rs b/src/input.rs
index af45c6ef..def20b4d 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -262,44 +262,43 @@ impl From<&'static str> for Action {
impl<'a, A: ActionContext + 'a> Processor<'a, A> {
#[inline]
- pub fn mouse_moved(&mut self, x: u32, y: u32, modifiers: ModifiersState) {
+ pub fn mouse_moved(&mut self, x: usize, y: usize, modifiers: ModifiersState) {
self.ctx.mouse_mut().x = x;
self.ctx.mouse_mut().y = y;
let size_info = self.ctx.size_info();
- if let Some(point) = size_info.pixels_to_coords(x as usize, y as usize) {
- 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 point = size_info.pixels_to_coords(x, y);
- let cell_x = (x as usize - 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 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_side = if cell_x > half_cell_width
- // Edge case when mouse leaves the window
- || x as f32 >= size_info.width - size_info.padding_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 cell_side = if cell_x > half_cell_width
+ // Edge case when mouse leaves the window
+ || x as f32 >= size_info.width - size_info.padding_x
+ {
+ Side::Right
+ } else {
+ Side::Left
+ };
+ 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)
+ && size_info.contains_point(x, y)
{
- Side::Right
- } else {
- Side::Left
- };
- 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);
- }
+ self.mouse_report(32, ElementState::Pressed);
}
}
}
diff --git a/src/selection.rs b/src/selection.rs
index 8e7fa29b..d49236a4 100644
--- a/src/selection.rs
+++ b/src/selection.rs
@@ -253,8 +253,31 @@ impl Selection {
// Handle some edge cases
if start.line > end.line {
- start.col += 1;
- end.col -= 1;
+ if end.col > Column(0) {
+ start.col += 1;
+ end.col -= 1;
+ }
+ // Special case for when a multi-line selection to the
+ // bottom ends on a new line with just one cell selected
+ // and the first cell should not be selected
+ else {
+ if start_side == Side::Right {
+ start.col += 1;
+ }
+
+ // Remove the single selected cell if mouse left window
+ if end_side == Side::Left {
+ end.line += 1;
+ end.col = cols - 1;
+ }
+
+ return Some(Span {
+ cols,
+ front: end,
+ tail: start,
+ ty: SpanType::Inclusive,
+ });
+ }
} else if start.line < end.line {
start.col -= 1;
end.col += 1;
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 511d6fbd..a721501a 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -790,25 +790,21 @@ impl SizeInfo {
Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize)
}
- fn contains_point(&self, x: usize, y:usize) -> bool {
+ pub fn contains_point(&self, x: usize, y:usize) -> bool {
x <= (self.width - self.padding_x) as usize &&
x >= self.padding_x as usize &&
y <= (self.height - self.padding_y) as usize &&
y >= self.padding_y as usize
}
- pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {
- if !self.contains_point(x, y) {
- return None;
- }
+ pub fn pixels_to_coords(&self, x: usize, y: usize) -> Point {
+ let col = Column(x.saturating_sub(self.padding_x as usize) / (self.cell_width as usize));
+ let line = Line(y.saturating_sub(self.padding_y as usize) / (self.cell_height as usize));
- let col = Column((x - self.padding_x as usize) / (self.cell_width as usize));
- let line = Line((y - self.padding_y as usize) / (self.cell_height as usize));
-
- Some(Point {
+ Point {
line: min(line, self.lines() - 1),
col: min(col, self.cols() - 1)
- })
+ }
}
}
@@ -1034,7 +1030,11 @@ impl Term {
///
/// Returns None if the coordinates are outside the screen
pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {
- self.size_info().pixels_to_coords(x, y)
+ if self.size_info.contains_point(x, y) {
+ Some(self.size_info.pixels_to_coords(x, y))
+ } else {
+ None
+ }
}
/// Access to the raw grid data structure