diff --git a/CHANGELOG.md b/CHANGELOG.md index 88c0feaf..0af307ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow setting general window class on X11 using CLI or config (`window.class.general`) - Config option `window.gtk_theme_variant` to set GTK theme variant - Completions for `--class` and `-t` (short title) +- Change the mouse cursor when hovering over the message bar and its close button ### Fixed diff --git a/alacritty_terminal/src/input.rs b/alacritty_terminal/src/input.rs index b4ea5910..697c439f 100644 --- a/alacritty_terminal/src/input.rs +++ b/alacritty_terminal/src/input.rs @@ -412,11 +412,19 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { let cell_changed = prev_line != self.ctx.mouse().line || prev_col != self.ctx.mouse().column; - let mouse_moved = cell_changed || prev_side != cell_side; + + // If the mouse hasn't changed cells, do nothing + if cell_changed || prev_side != cell_side { + return; + } // Only report motions when cell changed and mouse is not over the message bar - if self.message_at_point(Some(point)).is_some() || !mouse_moved { + 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 @@ -910,6 +918,15 @@ 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) -> Option { if let (Some(point), Some(message)) = @@ -924,16 +941,25 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { None } + /// Whether the point is over the message bar's close button + fn message_close_at_point(&self, point: Point, message: Message) -> bool { + let size = self.ctx.size_info(); + point.col + message_bar::CLOSE_BUTTON_TEXT.len() >= size.cols() + && point.line == size.lines() - message.text(&size).len() + } + /// Handle clicks on the message bar. fn on_message_bar_click(&mut self, button_state: ElementState, point: Point, message: Message) { match button_state { ElementState::Released => self.copy_selection(), ElementState::Pressed => { - let size = self.ctx.size_info(); - if point.col + message_bar::CLOSE_BUTTON_TEXT.len() >= size.cols() - && point.line == size.lines() - message.text(&size).len() - { + 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.clear_selection(); diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index c167875b..7de82a8d 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -1347,7 +1347,7 @@ impl Term { } #[inline] - pub fn reset_url_highlight(&mut self) { + pub fn reset_mouse_cursor(&mut self) { let mouse_mode = TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK; let mouse_cursor = if self.mode().intersects(mouse_mode) { @@ -1356,6 +1356,11 @@ impl Term { MouseCursor::Text }; self.set_mouse_cursor(mouse_cursor); + } + + #[inline] + pub fn reset_url_highlight(&mut self) { + self.reset_mouse_cursor(); self.grid.url_highlight = None; self.dirty = true; @@ -1404,6 +1409,7 @@ impl ansi::Handler for Term { #[inline] fn set_mouse_cursor(&mut self, cursor: MouseCursor) { self.next_mouse_cursor = Some(cursor); + self.dirty = true; } /// A character to be displayed diff --git a/alacritty_terminal/src/window.rs b/alacritty_terminal/src/window.rs index d4c673ba..0292cab9 100644 --- a/alacritty_terminal/src/window.rs +++ b/alacritty_terminal/src/window.rs @@ -61,6 +61,9 @@ pub struct Window { windowed_context: glutin::WindowedContext, mouse_visible: bool, + /// Keep track of the current mouse cursor to avoid unnecessarily changing it + current_mouse_cursor: MouseCursor, + /// Whether or not the window is the focused window. pub is_focused: bool, } @@ -164,8 +167,13 @@ impl Window { // Set OpenGL symbol loader. This call MUST be after window.make_current on windows. gl::load_with(|symbol| windowed_context.get_proc_address(symbol) as *const _); - let window = - Window { event_loop, windowed_context, mouse_visible: true, is_focused: false }; + let window = Window { + event_loop, + current_mouse_cursor: MouseCursor::Default, + windowed_context, + mouse_visible: true, + is_focused: false, + }; window.run_os_extensions(); @@ -239,8 +247,11 @@ impl Window { } #[inline] - pub fn set_mouse_cursor(&self, cursor: MouseCursor) { - self.window().set_cursor(cursor); + pub fn set_mouse_cursor(&mut self, cursor: MouseCursor) { + if cursor != self.current_mouse_cursor { + self.current_mouse_cursor = cursor; + self.window().set_cursor(cursor); + } } /// Set mouse cursor visible