aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal')
-rw-r--r--alacritty_terminal/src/ansi.rs10
-rw-r--r--alacritty_terminal/src/event.rs21
-rw-r--r--alacritty_terminal/src/input.rs130
-rw-r--r--alacritty_terminal/src/term/mod.rs15
4 files changed, 111 insertions, 65 deletions
diff --git a/alacritty_terminal/src/ansi.rs b/alacritty_terminal/src/ansi.rs
index 3189b300..eb8283a6 100644
--- a/alacritty_terminal/src/ansi.rs
+++ b/alacritty_terminal/src/ansi.rs
@@ -52,11 +52,7 @@ fn parse_rgb_color(color: &[u8]) -> Option<Rgb> {
Some((255 * value / max) as u8)
};
- Some(Rgb {
- r: scale(colors[0])?,
- g: scale(colors[1])?,
- b: scale(colors[2])?,
- })
+ Some(Rgb { r: scale(colors[0])?, g: scale(colors[1])?, b: scale(colors[2])? })
}
// Parse colors in `#r(rrr)g(ggg)b(bbb)` format
@@ -1449,8 +1445,8 @@ pub mod C1 {
#[cfg(test)]
mod tests {
use super::{
- parse_number, xparse_color, Attr, CharsetIndex, Color, Handler, Processor,
- StandardCharset, TermInfo,
+ parse_number, xparse_color, Attr, CharsetIndex, Color, Handler, Processor, StandardCharset,
+ TermInfo,
};
use crate::index::{Column, Line};
use crate::term::color::Rgb;
diff --git a/alacritty_terminal/src/event.rs b/alacritty_terminal/src/event.rs
index d3daf820..9d2aa78c 100644
--- a/alacritty_terminal/src/event.rs
+++ b/alacritty_terminal/src/event.rs
@@ -7,7 +7,7 @@ use std::sync::mpsc;
use std::time::Instant;
use glutin::dpi::PhysicalSize;
-use glutin::{self, ElementState, Event, ModifiersState, MouseButton};
+use glutin::{self, ElementState, Event, MouseButton};
use parking_lot::MutexGuard;
use crate::clipboard::ClipboardType;
@@ -15,7 +15,7 @@ use crate::config::{self, Config, StartupMode};
use crate::display::OnResize;
use crate::grid::Scroll;
use crate::index::{Column, Line, Point, Side};
-use crate::input::{self, KeyBinding, MouseBinding};
+use crate::input::{self, KeyBinding, Modifiers, MouseBinding};
use crate::selection::Selection;
use crate::sync::FairMutex;
use crate::term::{SizeInfo, Term};
@@ -39,7 +39,7 @@ pub struct ActionContext<'a, N> {
pub mouse: &'a mut Mouse,
pub received_count: &'a mut usize,
pub suppress_chars: &'a mut bool,
- pub last_modifiers: &'a mut ModifiersState,
+ pub modifiers: &'a mut Modifiers,
pub window_changes: &'a mut WindowChanges,
}
@@ -141,8 +141,8 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> {
}
#[inline]
- fn last_modifiers(&mut self) -> &mut ModifiersState {
- &mut self.last_modifiers
+ fn modifiers(&mut self) -> &mut Modifiers {
+ &mut self.modifiers
}
#[inline]
@@ -287,7 +287,7 @@ pub struct Processor<N> {
hide_mouse: bool,
received_count: usize,
suppress_chars: bool,
- last_modifiers: ModifiersState,
+ modifiers: Modifiers,
pending_events: Vec<Event>,
window_changes: WindowChanges,
save_to_clipboard: bool,
@@ -331,7 +331,7 @@ impl<N: Notify> Processor<N> {
hide_mouse: false,
received_count: 0,
suppress_chars: false,
- last_modifiers: Default::default(),
+ modifiers: Default::default(),
pending_events: Vec::with_capacity(4),
window_changes: Default::default(),
save_to_clipboard: config.selection.save_to_clipboard,
@@ -406,11 +406,9 @@ impl<N: Notify> Processor<N> {
*window_is_focused = is_focused;
if is_focused {
- processor.ctx.terminal.dirty = true;
processor.ctx.terminal.next_is_urgent = Some(false);
+ processor.ctx.terminal.dirty = true;
} else {
- processor.ctx.terminal.reset_url_highlight();
- processor.ctx.terminal.reset_mouse_cursor();
processor.ctx.terminal.dirty = true;
*hide_mouse = false;
}
@@ -426,6 +424,7 @@ impl<N: Notify> Processor<N> {
processor.ctx.size_info.dpr = new_dpr;
processor.ctx.terminal.dirty = true;
},
+ CursorLeft { .. } => processor.ctx.terminal.reset_url_highlight(),
_ => (),
}
},
@@ -478,7 +477,7 @@ impl<N: Notify> Processor<N> {
size_info: &mut self.size_info,
received_count: &mut self.received_count,
suppress_chars: &mut self.suppress_chars,
- last_modifiers: &mut self.last_modifiers,
+ modifiers: &mut self.modifiers,
window_changes: &mut self.window_changes,
};
diff --git a/alacritty_terminal/src/input.rs b/alacritty_terminal/src/input.rs
index 5784d9c2..3144e23f 100644
--- a/alacritty_terminal/src/input.rs
+++ b/alacritty_terminal/src/input.rs
@@ -25,7 +25,7 @@ use std::time::Instant;
use glutin::{
ElementState, KeyboardInput, ModifiersState, MouseButton, MouseCursor, MouseScrollDelta,
- TouchPhase,
+ TouchPhase, VirtualKeyCode,
};
use crate::ansi::{ClearMode, Handler};
@@ -73,7 +73,7 @@ pub trait ActionContext {
fn mouse_coords(&self) -> Option<Point>;
fn received_count(&mut self) -> &mut usize;
fn suppress_chars(&mut self) -> &mut bool;
- fn last_modifiers(&mut self) -> &mut ModifiersState;
+ fn modifiers(&mut self) -> &mut Modifiers;
fn scroll(&mut self, scroll: Scroll);
fn hide_window(&mut self);
fn terminal(&self) -> &Term;
@@ -84,6 +84,47 @@ pub trait ActionContext {
fn toggle_simple_fullscreen(&mut self);
}
+#[derive(Debug, Default, Copy, Clone)]
+pub struct Modifiers {
+ mods: ModifiersState,
+ lshift: bool,
+ rshift: bool,
+}
+
+impl Modifiers {
+ pub fn update(&mut self, input: KeyboardInput) {
+ match input.virtual_keycode {
+ Some(VirtualKeyCode::LShift) => self.lshift = input.state == ElementState::Pressed,
+ Some(VirtualKeyCode::RShift) => self.rshift = input.state == ElementState::Pressed,
+ _ => (),
+ }
+
+ self.mods = input.modifiers;
+ }
+
+ pub fn shift(self) -> bool {
+ self.lshift || self.rshift
+ }
+
+ pub fn ctrl(self) -> bool {
+ self.mods.ctrl
+ }
+
+ pub fn logo(self) -> bool {
+ self.mods.logo
+ }
+
+ pub fn alt(self) -> bool {
+ self.mods.alt
+ }
+}
+
+impl From<Modifiers> for ModifiersState {
+ fn from(mods: Modifiers) -> ModifiersState {
+ ModifiersState { shift: mods.shift(), ..mods.mods }
+ }
+}
+
/// Describes a state and action to take in that state
///
/// This is the shared component of `MouseBinding` and `KeyBinding`
@@ -381,41 +422,48 @@ impl From<&'static str> for Action {
}
}
-enum MousePosition {
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum MouseState {
Url(Url),
MessageBar,
MessageBarButton,
- Terminal,
+ Mouse,
+ Text,
}
impl<'a, A: ActionContext + 'a> Processor<'a, A> {
- fn mouse_position(&mut self, point: Point, modifiers: ModifiersState) -> MousePosition {
+ fn mouse_state(&mut self, point: Point) -> MouseState {
let mouse_mode =
TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK;
// Check message bar before URL to ignore URLs in the message bar
if let Some(message) = self.message_at_point(Some(point)) {
if self.message_close_at_point(point, message) {
- return MousePosition::MessageBarButton;
+ return MouseState::MessageBarButton;
} else {
- return MousePosition::MessageBar;
+ return MouseState::MessageBar;
}
}
// Check for URL at point with required modifiers held
- if self.mouse_config.url.mods().relaxed_eq(modifiers)
- && (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift)
+ let mods = *self.ctx.modifiers();
+ if self.mouse_config.url.mods().relaxed_eq(mods.into())
+ && (!self.ctx.terminal().mode().intersects(mouse_mode) || mods.shift())
&& self.mouse_config.url.launcher.is_some()
{
let buffer_point = self.ctx.terminal().visible_to_buffer(point);
if let Some(url) =
self.ctx.terminal().urls().drain(..).find(|url| url.contains(buffer_point))
{
- return MousePosition::Url(url);
+ return MouseState::Url(url);
}
}
- MousePosition::Terminal
+ if self.ctx.terminal().mode().intersects(mouse_mode) && !self.ctx.modifiers().shift() {
+ MouseState::Mouse
+ } else {
+ MouseState::Text
+ }
}
#[inline]
@@ -445,27 +493,18 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
// Don't launch URLs if mouse has moved
self.ctx.mouse_mut().block_url_launcher = true;
- match self.mouse_position(point, modifiers) {
- MousePosition::Url(url) => {
+ let mouse_state = self.mouse_state(point);
+ self.update_mouse_cursor(mouse_state);
+ match mouse_state {
+ MouseState::Url(url) => {
let url_bounds = url.linear_bounds(self.ctx.terminal());
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 => {
+ MouseState::MessageBar | MouseState::MessageBarButton => {
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();
- },
+ _ => self.ctx.terminal_mut().reset_url_highlight(),
}
if self.ctx.mouse().left_button_state == ElementState::Pressed
@@ -798,9 +837,20 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
/// Process key input
pub fn process_key(&mut self, input: KeyboardInput) {
+ self.ctx.modifiers().update(input);
+
+ // Update mouse cursor for temporarily disabling mouse mode
+ if input.virtual_keycode == Some(VirtualKeyCode::LShift)
+ || input.virtual_keycode == Some(VirtualKeyCode::RShift)
+ {
+ if let Some(point) = self.ctx.mouse_coords() {
+ let mouse_state = self.mouse_state(point);
+ self.update_mouse_cursor(mouse_state);
+ }
+ }
+
match input.state {
ElementState::Pressed => {
- *self.ctx.last_modifiers() = input.modifiers;
*self.ctx.received_count() = 0;
*self.ctx.suppress_chars() = false;
@@ -830,7 +880,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
if self.alt_send_esc
&& *self.ctx.received_count() == 0
- && self.ctx.last_modifiers().alt
+ && self.ctx.modifiers().alt()
&& utf8_len == 1
{
bytes.insert(0, b'\x1b');
@@ -934,8 +984,9 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
ElementState::Released => self.copy_selection(),
ElementState::Pressed => {
if self.message_close_at_point(point, message) {
+ let mouse_state = self.mouse_state(point);
+ self.update_mouse_cursor(mouse_state);
self.ctx.terminal_mut().message_buffer_mut().pop();
- self.ctx.terminal_mut().reset_mouse_cursor();
}
self.ctx.clear_selection();
@@ -950,6 +1001,17 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
}
self.ctx.copy_selection(ClipboardType::Selection);
}
+
+ #[inline]
+ fn update_mouse_cursor(&mut self, mouse_state: MouseState) {
+ let mouse_cursor = match mouse_state {
+ MouseState::Url(_) | MouseState::MessageBarButton => MouseCursor::Hand,
+ MouseState::Text => MouseCursor::Text,
+ _ => MouseCursor::Default,
+ };
+
+ self.ctx.terminal_mut().set_mouse_cursor(mouse_cursor);
+ }
}
#[cfg(test)]
@@ -968,7 +1030,7 @@ mod tests {
use crate::selection::Selection;
use crate::term::{SizeInfo, Term, TermMode};
- use super::{Action, Binding, Processor};
+ use super::{Action, Binding, Modifiers, Processor};
const KEY: VirtualKeyCode = VirtualKeyCode::Key0;
@@ -1112,7 +1174,7 @@ mod tests {
pub last_action: MultiClick,
pub received_count: usize,
pub suppress_chars: bool,
- pub last_modifiers: ModifiersState,
+ pub modifiers: Modifiers,
pub window_changes: &'a mut WindowChanges,
}
@@ -1189,8 +1251,8 @@ mod tests {
&mut self.suppress_chars
}
- fn last_modifiers(&mut self) -> &mut ModifiersState {
- &mut self.last_modifiers
+ fn modifiers(&mut self) -> &mut Modifiers {
+ &mut self.modifiers
}
}
@@ -1232,7 +1294,7 @@ mod tests {
last_action: MultiClick::None,
received_count: 0,
suppress_chars: false,
- last_modifiers: ModifiersState::default(),
+ modifiers: Default::default(),
window_changes: &mut WindowChanges::default(),
};
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index 2d1ec392..042ad1d0 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -841,9 +841,9 @@ impl Term {
#[inline]
pub fn scroll_display(&mut self, scroll: Scroll) {
+ self.set_mouse_cursor(MouseCursor::Text);
self.grid.scroll_display(scroll);
self.reset_url_highlight();
- self.reset_mouse_cursor();
self.dirty = true;
}
@@ -1296,18 +1296,7 @@ impl Term {
#[inline]
pub fn set_url_highlight(&mut self, hl: RangeInclusive<index::Linear>) {
self.grid.url_highlight = Some(hl);
- }
-
- #[inline]
- 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) {
- MouseCursor::Default
- } else {
- MouseCursor::Text
- };
- self.set_mouse_cursor(mouse_cursor);
+ self.dirty = true;
}
#[inline]