diff options
Diffstat (limited to 'alacritty/src')
-rw-r--r-- | alacritty/src/cursor.rs | 14 | ||||
-rw-r--r-- | alacritty/src/display.rs | 7 | ||||
-rw-r--r-- | alacritty/src/event.rs | 71 | ||||
-rw-r--r-- | alacritty/src/input.rs | 32 | ||||
-rw-r--r-- | alacritty/src/renderer/mod.rs | 2 | ||||
-rw-r--r-- | alacritty/src/scheduler.rs | 1 |
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. |