aboutsummaryrefslogtreecommitdiff
path: root/alacritty
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty')
-rw-r--r--alacritty/src/cursor.rs14
-rw-r--r--alacritty/src/display.rs7
-rw-r--r--alacritty/src/event.rs71
-rw-r--r--alacritty/src/input.rs32
-rw-r--r--alacritty/src/renderer/mod.rs2
-rw-r--r--alacritty/src/scheduler.rs1
6 files changed, 100 insertions, 27 deletions
diff --git a/alacritty/src/cursor.rs b/alacritty/src/cursor.rs
index 8c782185..edf76bf3 100644
--- a/alacritty/src/cursor.rs
+++ b/alacritty/src/cursor.rs
@@ -2,10 +2,10 @@
use crossfont::{BitmapBuffer, Metrics, RasterizedGlyph};
-use alacritty_terminal::ansi::CursorStyle;
+use alacritty_terminal::ansi::CursorShape;
pub fn get_cursor_glyph(
- cursor: CursorStyle,
+ cursor: CursorShape,
metrics: Metrics,
offset_x: i8,
offset_y: i8,
@@ -26,11 +26,11 @@ pub fn get_cursor_glyph(
}
match cursor {
- CursorStyle::HollowBlock => get_box_cursor_glyph(height, width, line_width),
- CursorStyle::Underline => get_underline_cursor_glyph(width, line_width),
- CursorStyle::Beam => get_beam_cursor_glyph(height, line_width),
- CursorStyle::Block => get_block_cursor_glyph(height, width),
- CursorStyle::Hidden => RasterizedGlyph::default(),
+ CursorShape::HollowBlock => get_box_cursor_glyph(height, width, line_width),
+ CursorShape::Underline => get_underline_cursor_glyph(width, line_width),
+ CursorShape::Beam => get_beam_cursor_glyph(height, line_width),
+ CursorShape::Block => get_block_cursor_glyph(height, width),
+ CursorShape::Hidden => RasterizedGlyph::default(),
}
}
diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs
index af21001e..451874c8 100644
--- a/alacritty/src/display.rs
+++ b/alacritty/src/display.rs
@@ -160,6 +160,9 @@ pub struct Display {
#[cfg(not(any(target_os = "macos", windows)))]
pub is_x11: bool,
+ /// UI cursor visibility for blinking.
+ pub cursor_hidden: bool,
+
renderer: QuadRenderer,
glyph_cache: GlyphCache,
meter: Meter,
@@ -300,6 +303,7 @@ impl Display {
is_x11,
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
wayland_event_queue,
+ cursor_hidden: false,
})
}
@@ -442,8 +446,9 @@ impl Display {
let viewport_match = search_state
.focused_match()
.and_then(|focused_match| terminal.grid().clamp_buffer_range_to_visible(focused_match));
+ let cursor_hidden = self.cursor_hidden || search_state.regex().is_some();
- let grid_cells = terminal.renderable_cells(config, !search_active).collect::<Vec<_>>();
+ let grid_cells = terminal.renderable_cells(config, !cursor_hidden).collect::<Vec<_>>();
let visual_bell_intensity = terminal.visual_bell.intensity();
let background_color = terminal.background_color();
let cursor_point = terminal.grid().cursor.point;
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index c1f81300..8ecf6f00 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -67,6 +67,7 @@ pub enum Event {
Scroll(Scroll),
ConfigReload(PathBuf),
Message(Message),
+ BlinkCursor,
SearchNext,
}
@@ -150,6 +151,7 @@ pub struct ActionContext<'a, N, T> {
pub urls: &'a Urls,
pub scheduler: &'a mut Scheduler,
pub search_state: &'a mut SearchState,
+ cursor_hidden: &'a mut bool,
cli_options: &'a CLIOptions,
font_size: &'a mut Size,
}
@@ -495,6 +497,28 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
}
}
+ /// Handle keyboard typing start.
+ ///
+ /// This will temporarily disable some features like terminal cursor blinking or the mouse
+ /// cursor.
+ ///
+ /// All features are re-enabled again automatically.
+ #[inline]
+ fn on_typing_start(&mut self) {
+ // Disable cursor blinking.
+ let blink_interval = self.config.cursor.blink_interval();
+ if let Some(timer) = self.scheduler.get_mut(TimerId::BlinkCursor) {
+ timer.deadline = Instant::now() + Duration::from_millis(blink_interval);
+ *self.cursor_hidden = false;
+ self.terminal.dirty = true;
+ }
+
+ // Hide mouse cursor.
+ if self.config.ui_config.mouse.hide_when_typing {
+ self.window.set_mouse_visible(false);
+ }
+ }
+
#[inline]
fn search_direction(&self) -> Direction {
self.search_state.direction
@@ -667,6 +691,33 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
origin.line = (origin.line as isize + self.search_state.display_offset_delta) as usize;
origin
}
+
+ /// Update the cursor blinking state.
+ fn update_cursor_blinking(&mut self) {
+ // Get config cursor style.
+ let mut cursor_style = self.config.cursor.style;
+ if self.terminal.mode().contains(TermMode::VI) {
+ cursor_style = self.config.cursor.vi_mode_style.unwrap_or(cursor_style);
+ };
+
+ // Check terminal cursor style.
+ let terminal_blinking = self.terminal.cursor_style().blinking;
+ let blinking = cursor_style.blinking_override().unwrap_or(terminal_blinking);
+
+ // Update cursor blinking state.
+ self.scheduler.unschedule(TimerId::BlinkCursor);
+ if blinking && self.terminal.is_focused {
+ self.scheduler.schedule(
+ GlutinEvent::UserEvent(Event::BlinkCursor),
+ Duration::from_millis(self.config.cursor.blink_interval()),
+ true,
+ TimerId::BlinkCursor,
+ )
+ } else {
+ *self.cursor_hidden = false;
+ self.terminal.dirty = true;
+ }
+ }
}
#[derive(Debug, Eq, PartialEq)]
@@ -804,6 +855,12 @@ impl<N: Notify + OnResize> Processor<N> {
{
let mut scheduler = Scheduler::new();
+ // Start the initial cursor blinking timer.
+ if self.config.cursor.style().blinking {
+ let event: Event = TerminalEvent::CursorBlinkingChange(true).into();
+ self.event_queue.push(event.into());
+ }
+
event_loop.run_return(|event, event_loop, control_flow| {
if self.config.ui_config.debug.print_events {
info!("glutin event: {:?}", event);
@@ -873,6 +930,7 @@ impl<N: Notify + OnResize> Processor<N> {
scheduler: &mut scheduler,
search_state: &mut self.search_state,
cli_options: &self.cli_options,
+ cursor_hidden: &mut self.display.cursor_hidden,
event_loop,
};
let mut processor = input::Processor::new(context, &self.display.highlighted_url);
@@ -953,6 +1011,10 @@ impl<N: Notify + OnResize> Processor<N> {
Event::SearchNext => processor.ctx.goto_match(None),
Event::ConfigReload(path) => Self::reload_config(&path, processor),
Event::Scroll(scroll) => processor.ctx.scroll(scroll),
+ Event::BlinkCursor => {
+ *processor.ctx.cursor_hidden ^= true;
+ processor.ctx.terminal.dirty = true;
+ },
Event::TerminalEvent(event) => match event {
TerminalEvent::Title(title) => {
let ui_config = &processor.ctx.config.ui_config;
@@ -983,6 +1045,9 @@ impl<N: Notify + OnResize> Processor<N> {
},
TerminalEvent::MouseCursorDirty => processor.reset_mouse_cursor(),
TerminalEvent::Exit => (),
+ TerminalEvent::CursorBlinkingChange(_) => {
+ processor.ctx.update_cursor_blinking();
+ },
},
},
GlutinEvent::RedrawRequested(_) => processor.ctx.terminal.dirty = true,
@@ -1033,6 +1098,7 @@ impl<N: Notify + OnResize> Processor<N> {
processor.ctx.window.set_mouse_visible(true);
}
+ processor.ctx.update_cursor_blinking();
processor.on_focus_change(is_focused);
}
},
@@ -1111,7 +1177,7 @@ impl<N: Notify + OnResize> Processor<N> {
processor.ctx.terminal.update_config(&config);
- // Reload cursor if we've changed its thickness.
+ // Reload cursor if its thickness has changed.
if (processor.ctx.config.cursor.thickness() - config.cursor.thickness()).abs()
> std::f64::EPSILON
{
@@ -1154,6 +1220,9 @@ impl<N: Notify + OnResize> Processor<N> {
*processor.ctx.config = config;
+ // Update cursor blinking.
+ processor.ctx.update_cursor_blinking();
+
processor.ctx.terminal.dirty = true;
}
diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs
index 348db610..ce89625b 100644
--- a/alacritty/src/input.rs
+++ b/alacritty/src/input.rs
@@ -103,6 +103,7 @@ pub trait ActionContext<T: EventListener> {
fn advance_search_origin(&mut self, direction: Direction);
fn search_direction(&self) -> Direction;
fn search_active(&self) -> bool;
+ fn on_typing_start(&mut self);
}
trait Execute<T: EventListener> {
@@ -138,9 +139,7 @@ impl<T: EventListener> Execute<T> for Action {
fn execute<A: ActionContext<T>>(&self, ctx: &mut A) {
match *self {
Action::Esc(ref s) => {
- if ctx.config().ui_config.mouse.hide_when_typing {
- ctx.window_mut().set_mouse_visible(false);
- }
+ ctx.on_typing_start();
ctx.clear_selection();
ctx.scroll(Scroll::Bottom);
@@ -167,10 +166,7 @@ impl<T: EventListener> Execute<T> for Action {
Action::ClearSelection => ctx.clear_selection(),
Action::ToggleViMode => ctx.terminal_mut().toggle_vi_mode(),
Action::ViMotion(motion) => {
- if ctx.config().ui_config.mouse.hide_when_typing {
- ctx.window_mut().set_mouse_visible(false);
- }
-
+ ctx.on_typing_start();
ctx.terminal_mut().vi_motion(motion)
},
Action::ViAction(ViAction::ToggleNormalSelection) => {
@@ -870,6 +866,13 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
self.ctx.window_mut().set_mouse_cursor(mouse_state.into());
}
+ /// Reset mouse cursor based on modifier and terminal state.
+ #[inline]
+ pub fn reset_mouse_cursor(&mut self) {
+ let mouse_state = self.mouse_state();
+ self.ctx.window_mut().set_mouse_cursor(mouse_state.into());
+ }
+
/// Process a received character.
pub fn received_char(&mut self, c: char) {
let suppress_chars = *self.ctx.suppress_chars();
@@ -890,9 +893,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
return;
}
- if self.ctx.config().ui_config.mouse.hide_when_typing {
- self.ctx.window_mut().set_mouse_visible(false);
- }
+ self.ctx.on_typing_start();
self.ctx.scroll(Scroll::Bottom);
self.ctx.clear_selection();
@@ -917,13 +918,6 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
*self.ctx.received_count() += 1;
}
- /// Reset mouse cursor based on modifier and terminal state.
- #[inline]
- pub fn reset_mouse_cursor(&mut self) {
- let mouse_state = self.mouse_state();
- self.ctx.window_mut().set_mouse_cursor(mouse_state.into());
- }
-
/// Attempt to find a binding and execute its action.
///
/// The provided mode, mods, and key must match what is allowed by a binding
@@ -1270,6 +1264,10 @@ mod tests {
fn scheduler_mut(&mut self) -> &mut Scheduler {
unimplemented!();
}
+
+ fn on_typing_start(&mut self) {
+ unimplemented!();
+ }
}
macro_rules! test_clickstate {
diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs
index f63f92fd..af1f3c3e 100644
--- a/alacritty/src/renderer/mod.rs
+++ b/alacritty/src/renderer/mod.rs
@@ -1010,7 +1010,7 @@ impl<'a> RenderApi<'a> {
let metrics = glyph_cache.metrics;
let glyph = glyph_cache.cursor_cache.entry(cursor_key).or_insert_with(|| {
self.load_glyph(&cursor::get_cursor_glyph(
- cursor_key.style,
+ cursor_key.shape,
metrics,
self.config.font.offset.x,
self.config.font.offset.y,
diff --git a/alacritty/src/scheduler.rs b/alacritty/src/scheduler.rs
index db6180ca..5e454141 100644
--- a/alacritty/src/scheduler.rs
+++ b/alacritty/src/scheduler.rs
@@ -14,6 +14,7 @@ type Event = GlutinEvent<'static, AlacrittyEvent>;
pub enum TimerId {
SelectionScrolling,
DelayedSearch,
+ BlinkCursor,
}
/// Event scheduled to be emitted at a specific time.