mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
Fix selection copying with mouse outside of window
There was an issue caused by 35efb4619c
which would lead to the current selection not getting copied to the
clipboard if the mouse was released outside of the window.
Instead of aborting any press/release actions when the cursor is not
inside of Alacritty, the handling is now delayed until actual usage.
This commit is contained in:
parent
14e3a0ae5a
commit
3c672cca4b
2 changed files with 34 additions and 29 deletions
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix panic which could occur when quitting Alacritty on Windows if using the Conpty backend
|
- Fix panic which could occur when quitting Alacritty on Windows if using the Conpty backend
|
||||||
|
- Automatic copying of selection to clipboard when mouse is released outside of Alacritty
|
||||||
|
|
||||||
## Version 0.2.9
|
## Version 0.2.9
|
||||||
|
|
||||||
|
|
62
src/input.rs
62
src/input.rs
|
@ -33,7 +33,7 @@ use crate::term::{Term, SizeInfo, Search};
|
||||||
use crate::term::mode::TermMode;
|
use crate::term::mode::TermMode;
|
||||||
use crate::util::fmt::Red;
|
use crate::util::fmt::Red;
|
||||||
use crate::util::start_daemon;
|
use crate::util::start_daemon;
|
||||||
use crate::message_bar;
|
use crate::message_bar::{self, Message};
|
||||||
use crate::ansi::{Handler, ClearMode};
|
use crate::ansi::{Handler, ClearMode};
|
||||||
|
|
||||||
pub const FONT_SIZE_STEP: f32 = 0.5;
|
pub const FONT_SIZE_STEP: f32 = 0.5;
|
||||||
|
@ -394,7 +394,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore motions over the message bar
|
// Ignore motions over the message bar
|
||||||
if self.mouse_over_message_bar(point) {
|
if self.message_at_point(Some(point)).is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,14 +497,14 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_mouse_double_click(&mut self, button: MouseButton, point: Point) {
|
pub fn on_mouse_double_click(&mut self, button: MouseButton, point: Option<Point>) {
|
||||||
if button == MouseButton::Left {
|
if let (Some(point), true) = (point, button == MouseButton::Left) {
|
||||||
self.ctx.semantic_selection(point);
|
self.ctx.semantic_selection(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_mouse_triple_click(&mut self, button: MouseButton, point: Point) {
|
pub fn on_mouse_triple_click(&mut self, button: MouseButton, point: Option<Point>) {
|
||||||
if button == MouseButton::Left {
|
if let (Some(point), true) = (point, button == MouseButton::Left) {
|
||||||
self.ctx.line_selection(point);
|
self.ctx.line_selection(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
&mut self,
|
&mut self,
|
||||||
button: MouseButton,
|
button: MouseButton,
|
||||||
modifiers: ModifiersState,
|
modifiers: ModifiersState,
|
||||||
point: Point,
|
point: Option<Point>,
|
||||||
) {
|
) {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let elapsed = self.ctx.mouse().last_click_timestamp.elapsed();
|
let elapsed = self.ctx.mouse().last_click_timestamp.elapsed();
|
||||||
|
@ -544,7 +544,9 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
|
|
||||||
// Start new empty selection
|
// Start new empty selection
|
||||||
let side = self.ctx.mouse().cell_side;
|
let side = self.ctx.mouse().cell_side;
|
||||||
self.ctx.simple_selection(point, side);
|
if let Some(point) = point {
|
||||||
|
self.ctx.simple_selection(point, side);
|
||||||
|
}
|
||||||
|
|
||||||
let report_modes =
|
let report_modes =
|
||||||
TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
|
TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
|
||||||
|
@ -569,7 +571,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
&mut self,
|
&mut self,
|
||||||
button: MouseButton,
|
button: MouseButton,
|
||||||
modifiers: ModifiersState,
|
modifiers: ModifiersState,
|
||||||
point: Point,
|
point: Option<Point>,
|
||||||
) {
|
) {
|
||||||
let report_modes =
|
let report_modes =
|
||||||
TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
|
TermMode::MOUSE_REPORT_CLICK | TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION;
|
||||||
|
@ -583,7 +585,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
};
|
};
|
||||||
self.mouse_report(code, ElementState::Released, modifiers);
|
self.mouse_report(code, ElementState::Released, modifiers);
|
||||||
return;
|
return;
|
||||||
} else if button == MouseButton::Left {
|
} else if let (Some(point), true) = (point, button == MouseButton::Left) {
|
||||||
self.launch_url(modifiers, point);
|
self.launch_url(modifiers, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,14 +714,13 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
let point = match self.ctx.mouse_coords() {
|
let point = self.ctx.mouse_coords();
|
||||||
Some(point) => point,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Skip normal mouse events if the message bar has been clicked
|
// Skip normal mouse events if the message bar has been clicked
|
||||||
if self.mouse_over_message_bar(point) {
|
if let Some(message) = self.message_at_point(point) {
|
||||||
self.on_message_bar_click(state, point);
|
// Message should never be `Some` if point is `None`
|
||||||
|
debug_assert!(point.is_some());
|
||||||
|
self.on_message_bar_click(state, point.unwrap(), message);
|
||||||
} else {
|
} else {
|
||||||
match state {
|
match state {
|
||||||
ElementState::Pressed => {
|
ElementState::Pressed => {
|
||||||
|
@ -841,28 +842,31 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
has_binding
|
has_binding
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a point is within the message bar
|
/// Return the message bar's message if there is some at the specified point
|
||||||
fn mouse_over_message_bar(&mut self, point: Point) -> bool {
|
fn message_at_point(&mut self, point: Option<Point>) -> Option<Message> {
|
||||||
if let Some(message) = self.ctx.terminal_mut().message_buffer_mut().message() {
|
if let (Some(point), Some(message)) = (
|
||||||
|
point,
|
||||||
|
self.ctx.terminal_mut().message_buffer_mut().message(),
|
||||||
|
) {
|
||||||
let size = self.ctx.size_info();
|
let size = self.ctx.size_info();
|
||||||
point.line.0 >= size.lines().saturating_sub(message.text(&size).len())
|
if point.line.0 >= size.lines().saturating_sub(message.text(&size).len()) {
|
||||||
} else {
|
return Some(message);
|
||||||
false
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle clicks on the message bar.
|
/// Handle clicks on the message bar.
|
||||||
fn on_message_bar_click(&mut self, button_state: ElementState, point: Point) {
|
fn on_message_bar_click(&mut self, button_state: ElementState, point: Point, message: Message) {
|
||||||
match button_state {
|
match button_state {
|
||||||
ElementState::Released => self.copy_selection(),
|
ElementState::Released => self.copy_selection(),
|
||||||
ElementState::Pressed => {
|
ElementState::Pressed => {
|
||||||
let size = self.ctx.size_info();
|
let size = self.ctx.size_info();
|
||||||
if let Some(message) = self.ctx.terminal_mut().message_buffer_mut().message() {
|
if point.col + message_bar::CLOSE_BUTTON_TEXT.len() >= size.cols()
|
||||||
if point.col + message_bar::CLOSE_BUTTON_TEXT.len() >= size.cols()
|
&& point.line == size.lines() - message.text(&size).len()
|
||||||
&& point.line == size.lines() - message.text(&size).len()
|
{
|
||||||
{
|
self.ctx.terminal_mut().message_buffer_mut().pop();
|
||||||
self.ctx.terminal_mut().message_buffer_mut().pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ctx.clear_selection();
|
self.ctx.clear_selection();
|
||||||
|
|
Loading…
Reference in a new issue