aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/input.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/input.rs')
-rw-r--r--alacritty/src/input.rs113
1 files changed, 78 insertions, 35 deletions
diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs
index d43bb26f..b0a6eb80 100644
--- a/alacritty/src/input.rs
+++ b/alacritty/src/input.rs
@@ -492,44 +492,80 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
};
self.mouse_report(code, ElementState::Pressed);
- } else if button == MouseButton::Left {
- self.on_left_click();
} else {
- // Do nothing when using buttons other than LMB.
- self.ctx.mouse_mut().click_state = ClickState::None;
+ // Calculate time since the last click to handle double/triple clicks.
+ let now = Instant::now();
+ let elapsed = now - self.ctx.mouse().last_click_timestamp;
+ self.ctx.mouse_mut().last_click_timestamp = now;
+
+ // Update multi-click state.
+ let mouse_config = &self.ctx.config().ui_config.mouse;
+ self.ctx.mouse_mut().click_state = match self.ctx.mouse().click_state {
+ // Reset click state if button has changed.
+ _ if button != self.ctx.mouse().last_click_button => {
+ self.ctx.mouse_mut().last_click_button = button;
+ ClickState::Click
+ },
+ ClickState::Click if elapsed < mouse_config.double_click.threshold => {
+ ClickState::DoubleClick
+ },
+ ClickState::DoubleClick if elapsed < mouse_config.triple_click.threshold => {
+ ClickState::TripleClick
+ },
+ _ => ClickState::Click,
+ };
+
+ // Load mouse point, treating message bar and padding as the closest cell.
+ let mouse = self.ctx.mouse();
+ let mut point = self.ctx.size_info().pixels_to_coords(mouse.x, mouse.y);
+ point.line = min(point.line, self.ctx.terminal().grid().num_lines() - 1);
+
+ match button {
+ MouseButton::Left => self.on_left_click(point),
+ MouseButton::Right => self.on_right_click(point),
+ // Do nothing when using buttons other than LMB.
+ _ => self.ctx.mouse_mut().click_state = ClickState::None,
+ }
}
}
- /// Handle left click selection and vi mode cursor movement.
- fn on_left_click(&mut self) {
- // Calculate time since the last click to handle double/triple clicks in normal mode.
- let now = Instant::now();
- let elapsed = now - self.ctx.mouse().last_click_timestamp;
- self.ctx.mouse_mut().last_click_timestamp = now;
+ /// Handle selection expansion on right click.
+ fn on_right_click(&mut self, point: Point) {
+ match self.ctx.mouse().click_state {
+ ClickState::Click => {
+ let selection_type = if self.ctx.modifiers().ctrl() {
+ SelectionType::Block
+ } else {
+ SelectionType::Simple
+ };
- // Load mouse point, treating message bar and padding as closest cell.
- let mouse = self.ctx.mouse();
- let mut point = self.ctx.size_info().pixels_to_coords(mouse.x, mouse.y);
- point.line = min(point.line, self.ctx.terminal().grid().num_lines() - 1);
+ self.expand_selection(point, selection_type);
+ },
+ ClickState::DoubleClick => self.expand_selection(point, SelectionType::Semantic),
+ ClickState::TripleClick => self.expand_selection(point, SelectionType::Lines),
+ ClickState::None => (),
+ }
+ }
+
+ /// Expand existing selection.
+ fn expand_selection(&mut self, point: Point, selection_type: SelectionType) {
+ let cell_side = self.ctx.mouse().cell_side;
+
+ let selection = match &mut self.ctx.terminal_mut().selection {
+ Some(selection) => selection,
+ None => return,
+ };
+
+ selection.ty = selection_type;
+ self.ctx.update_selection(point, cell_side);
+ }
+ /// Handle left click selection and vi mode cursor movement.
+ fn on_left_click(&mut self, point: Point) {
let side = self.ctx.mouse().cell_side;
- self.ctx.mouse_mut().click_state = match self.ctx.mouse().click_state {
- ClickState::Click
- if elapsed < self.ctx.config().ui_config.mouse.double_click.threshold =>
- {
- self.ctx.mouse_mut().block_url_launcher = true;
- self.ctx.start_selection(SelectionType::Semantic, point, side);
- ClickState::DoubleClick
- }
- ClickState::DoubleClick
- if elapsed < self.ctx.config().ui_config.mouse.triple_click.threshold =>
- {
- self.ctx.mouse_mut().block_url_launcher = true;
- self.ctx.start_selection(SelectionType::Lines, point, side);
- ClickState::TripleClick
- }
- _ => {
+ match self.ctx.mouse().click_state {
+ ClickState::Click => {
// Don't launch URLs if this click cleared the selection.
self.ctx.mouse_mut().block_url_launcher = !self.ctx.selection_is_empty();
@@ -541,9 +577,16 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
} else {
self.ctx.start_selection(SelectionType::Simple, point, side);
}
-
- ClickState::Click
},
+ ClickState::DoubleClick => {
+ self.ctx.mouse_mut().block_url_launcher = true;
+ self.ctx.start_selection(SelectionType::Semantic, point, side);
+ },
+ ClickState::TripleClick => {
+ self.ctx.mouse_mut().block_url_launcher = true;
+ self.ctx.start_selection(SelectionType::Lines, point, side);
+ },
+ ClickState::None => (),
};
// Move vi mode cursor to mouse position.
@@ -1080,7 +1123,7 @@ mod tests {
unimplemented!();
}
- fn scheduler_mut (&mut self) -> &mut Scheduler {
+ fn scheduler_mut(&mut self) -> &mut Scheduler {
unimplemented!();
}
}
@@ -1209,7 +1252,7 @@ mod tests {
},
window_id: unsafe { std::mem::transmute_copy(&0) },
},
- end_state: ClickState::None,
+ end_state: ClickState::Click,
}
test_clickstate! {
@@ -1273,7 +1316,7 @@ mod tests {
},
window_id: unsafe { std::mem::transmute_copy(&0) },
},
- end_state: ClickState::None,
+ end_state: ClickState::Click,
}
test_process_binding! {