summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Chibisov <wchibisovkirill@gmail.com>2019-07-28 20:04:26 +0300
committerChristian Duerr <chrisduerr@users.noreply.github.com>2019-07-28 17:04:26 +0000
commit72dfa477a9785289931e8e05dfc8244bb6a4e81c (patch)
treeec6c959deda0aea2a6c6571dac0242a4ce7a084a
parent14a48a25332ebad2ab227fad618d06efe2501d43 (diff)
Fix cursor flickering on url hover
This commit fixes the regression introduced in 84aca67 and also fixes url highlight bounds computation when url ends on a last column. Fixes #2665.
-rw-r--r--alacritty_terminal/src/event.rs1
-rw-r--r--alacritty_terminal/src/input.rs146
-rw-r--r--alacritty_terminal/src/term/mod.rs3
3 files changed, 86 insertions, 64 deletions
diff --git a/alacritty_terminal/src/event.rs b/alacritty_terminal/src/event.rs
index bb34d2f2..d3daf820 100644
--- a/alacritty_terminal/src/event.rs
+++ b/alacritty_terminal/src/event.rs
@@ -410,6 +410,7 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.next_is_urgent = Some(false);
} else {
processor.ctx.terminal.reset_url_highlight();
+ processor.ctx.terminal.reset_mouse_cursor();
processor.ctx.terminal.dirty = true;
*hide_mouse = false;
}
diff --git a/alacritty_terminal/src/input.rs b/alacritty_terminal/src/input.rs
index 83ab0261..92e08af5 100644
--- a/alacritty_terminal/src/input.rs
+++ b/alacritty_terminal/src/input.rs
@@ -383,7 +383,30 @@ impl From<&'static str> for Action {
}
}
+enum MousePosition {
+ Url(Url),
+ MessageBar,
+ MessageBarButton,
+ Terminal,
+}
+
impl<'a, A: ActionContext + 'a> Processor<'a, A> {
+ fn mouse_position(&mut self, point: Point) -> MousePosition {
+ if let Some(message) = self.message_at_point(Some(point)) {
+ if self.message_close_at_point(point, message) {
+ MousePosition::MessageBarButton
+ } else {
+ MousePosition::MessageBar
+ }
+ // Check for url should be after check for message bar, since we're not looking into
+ // message bar content.
+ } else if let Some(url) = self.ctx.terminal().url_search(point.into()) {
+ MousePosition::Url(url)
+ } else {
+ MousePosition::Terminal
+ }
+ }
+
#[inline]
pub fn mouse_moved(&mut self, x: usize, y: usize, modifiers: ModifiersState) {
self.ctx.mouse_mut().x = x;
@@ -408,21 +431,38 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
return;
}
- // Only report motions when cell changed and mouse is not over the message bar
- if let Some(message) = self.message_at_point(Some(point)) {
- self.update_message_cursor(point, message);
-
- return;
- } else {
- self.ctx.terminal_mut().reset_mouse_cursor();
- }
-
// Don't launch URLs if mouse has moved
self.ctx.mouse_mut().block_url_launcher = true;
- // Underline URLs and change cursor on hover
- if cell_changed {
- self.update_url_highlight(point, modifiers);
+ match self.mouse_position(point) {
+ MousePosition::Url(url) => {
+ let mouse_mode =
+ TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK;
+
+ if self.mouse_config.url.mods().relaxed_eq(modifiers)
+ && (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift)
+ && self.mouse_config.url.launcher.is_some()
+ {
+ let url_bounds = self.url_bounds_at_point(url, point);
+ self.ctx.terminal_mut().set_url_highlight(url_bounds);
+ self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
+ self.ctx.terminal_mut().dirty = true;
+ }
+ },
+ MousePosition::MessageBar => {
+ self.ctx.terminal_mut().reset_url_highlight();
+ self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Default);
+ return;
+ },
+ MousePosition::MessageBarButton => {
+ self.ctx.terminal_mut().reset_url_highlight();
+ self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
+ return;
+ },
+ MousePosition::Terminal => {
+ self.ctx.terminal_mut().reset_url_highlight();
+ self.ctx.terminal_mut().reset_mouse_cursor();
+ },
}
if self.ctx.mouse().left_button_state == ElementState::Pressed
@@ -445,50 +485,45 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
}
- /// Underline URLs and change the mouse cursor when URL hover state changes.
- fn update_url_highlight(&mut self, point: Point, modifiers: ModifiersState) {
- let mouse_mode =
- TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK;
+ fn url_bounds_at_point(&self, url: Url, point: Point) -> RangeInclusive<Linear> {
+ let Url { origin, text } = url;
+ let cols = self.ctx.size_info().cols().0;
- // Only show URLs as launchable when all required modifiers are pressed
- let url = if self.mouse_config.url.mods().relaxed_eq(modifiers)
- && (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift)
- && self.mouse_config.url.launcher.is_some()
- {
- self.ctx.terminal().url_search(point.into())
+ // Calculate the URL's start position
+ let lines_before = (origin + cols - point.col.0 - 1) / cols;
+ let (start_col, start_line) = if lines_before > point.line.0 {
+ (0, 0)
} else {
- None
+ let start_col = (cols + point.col.0 - origin % cols) % cols;
+ let start_line = point.line.0 - lines_before;
+ (start_col, start_line)
};
- if let Some(Url { origin, text }) = url {
- let cols = self.ctx.size_info().cols().0;
-
- // Calculate the URL's start position
- let lines_before = (origin + cols - point.col.0 - 1) / cols;
- let (start_col, start_line) = if lines_before > point.line.0 {
- (0, 0)
- } else {
- let start_col = (cols + point.col.0 - origin % cols) % cols;
- let start_line = point.line.0 - lines_before;
- (start_col, start_line)
- };
- let start = Point::new(start_line, Column(start_col));
+ let start = Point::new(start_line, Column(start_col));
- // Calculate the URL's end position
- let len = text.width();
- let end_col = (point.col.0 + len - origin) % cols - 1;
- let end_line = point.line.0 + (point.col.0 + len - origin) / cols;
- let end = Point::new(end_line, Column(end_col));
+ // Calculate the URL's highlight end position
+ let len = text.width();
+ let url_end_col_denormilized = point.col.0 + len - origin;
- let start = Linear::from_point(Column(cols), start);
- let end = Linear::from_point(Column(cols), end);
+ // This means that url ends at the last cell of the line
+ let end_col = if url_end_col_denormilized % cols == 0 {
+ cols - 1
+ } else {
+ url_end_col_denormilized % cols - 1
+ };
- self.ctx.terminal_mut().set_url_highlight(RangeInclusive::new(start, end));
- self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
- self.ctx.terminal_mut().dirty = true;
+ let end_line = if end_col == cols - 1 {
+ point.line.0 + (url_end_col_denormilized) / cols - 1
} else {
- self.ctx.terminal_mut().reset_url_highlight();
- }
+ point.line.0 + (url_end_col_denormilized) / cols
+ };
+
+ let end = Point::new(end_line, Column(end_col));
+
+ let start = Linear::from_point(Column(cols), start);
+ let end = Linear::from_point(Column(cols), end);
+
+ RangeInclusive::new(start, end)
}
fn get_mouse_side(&self) -> Side {
@@ -908,15 +943,6 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
has_binding
}
- /// Set the cursor depending on where the mouse is on the message bar
- fn update_message_cursor(&mut self, point: Point, message: Message) {
- if self.message_close_at_point(point, message) {
- self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
- } else {
- self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Default);
- }
- }
-
/// Return the message bar's message if there is some at the specified point
fn message_at_point(&mut self, point: Option<Point>) -> Option<Message> {
if let (Some(point), Some(message)) =
@@ -945,11 +971,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
ElementState::Pressed => {
if self.message_close_at_point(point, message) {
self.ctx.terminal_mut().message_buffer_mut().pop();
- if let Some(message) = self.message_at_point(Some(point)) {
- self.update_message_cursor(point, message);
- } else {
- self.ctx.terminal_mut().reset_mouse_cursor();
- }
+ self.ctx.terminal_mut().reset_mouse_cursor();
}
self.ctx.clear_selection();
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index 34d06b21..691a4fe1 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -896,6 +896,7 @@ impl Term {
pub fn scroll_display(&mut self, scroll: Scroll) {
self.grid.scroll_display(scroll);
self.reset_url_highlight();
+ self.reset_mouse_cursor();
self.dirty = true;
}
@@ -1360,8 +1361,6 @@ impl Term {
#[inline]
pub fn reset_url_highlight(&mut self) {
- self.reset_mouse_cursor();
-
self.grid.url_highlight = None;
self.dirty = true;
}