summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-07-01 11:40:27 +0300
committerGitHub <noreply@github.com>2022-07-01 11:40:27 +0300
commitebc6922eaae28173532235222f9790c8ab3fdaa7 (patch)
tree7f3e50f0dddb3fb74d3969d46b90e3dd8e207f54
parent28e3fc7c64a7f375ad843145a0a8f78e31bff05e (diff)
Add `cursor.blink_timeout` config option
This option should prevent extensive power usage due to cursor blinking when there's no user activity being performed. Fixes #5992.
-rw-r--r--CHANGELOG.md2
-rw-r--r--alacritty.yml5
-rw-r--r--alacritty/src/event.rs59
-rw-r--r--alacritty/src/scheduler.rs1
-rw-r--r--alacritty/src/window_context.rs3
-rw-r--r--alacritty_terminal/src/config/mod.rs18
6 files changed, 75 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8591416e..6c8816d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,12 +21,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Escape sequence to reset underline color (`CSI 59 m`)
- Vi mode keybinding (z) to center view around vi mode cursor
- Accept hexadecimal values starting with `0x` for `--embed`
+- Config option `cursor.blink_timeout` to timeout cursor blinking after inactivity
### Changed
- The `--help` output was reworked with a new colorful syntax
- OSC 52 is now disabled on unfocused windows
- `SpawnNewInstance` no longer inherits initial `--command`
+- Blinking cursor will timeout after `5` seconds by default
### Fixed
diff --git a/alacritty.yml b/alacritty.yml
index 3ba6a7f5..511a10d6 100644
--- a/alacritty.yml
+++ b/alacritty.yml
@@ -412,6 +412,11 @@
# Cursor blinking interval in milliseconds.
#blink_interval: 750
+ # Time after which cursor stops blinking, in seconds.
+ #
+ # Specifying '0' will disable timeout for blinking.
+ #blink_timeout: 5
+
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
#unfocused_hollow: true
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 2955ab8c..f91ef962 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -90,6 +90,7 @@ pub enum EventType {
Scroll(Scroll),
CreateWindow(WindowOptions),
BlinkCursor,
+ BlinkCursorTimeout,
SearchNext,
}
@@ -180,6 +181,7 @@ pub struct ActionContext<'a, N, T> {
pub display: &'a mut Display,
pub message_buffer: &'a mut MessageBuffer,
pub config: &'a mut UiConfig,
+ pub cursor_blink_timed_out: &'a mut bool,
pub event_loop: &'a EventLoopWindowTarget<Event>,
pub event_proxy: &'a EventLoopProxy<Event>,
pub scheduler: &'a mut Scheduler,
@@ -647,14 +649,15 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
fn on_typing_start(&mut self) {
// Disable cursor blinking.
let timer_id = TimerId::new(Topic::BlinkCursor, self.display.window.id());
- if let Some(timer) = self.scheduler.unschedule(timer_id) {
- let interval =
- Duration::from_millis(self.config.terminal_config.cursor.blink_interval());
- self.scheduler.schedule(timer.event, interval, true, timer.id);
+ if self.scheduler.unschedule(timer_id).is_some() {
+ self.schedule_blinking();
self.display.cursor_hidden = false;
- *self.dirty = true;
+ } else if *self.cursor_blink_timed_out {
+ self.update_cursor_blinking();
}
+ *self.dirty = true;
+
// Hide mouse cursor.
if self.config.mouse.hide_when_typing {
self.display.window.set_mouse_visible(false);
@@ -945,18 +948,44 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
blinking &= vi_mode || self.terminal().mode().contains(TermMode::SHOW_CURSOR);
// Update cursor blinking state.
- let timer_id = TimerId::new(Topic::BlinkCursor, self.display.window.id());
- self.scheduler.unschedule(timer_id);
+ let window_id = self.display.window.id();
+ self.scheduler.unschedule(TimerId::new(Topic::BlinkCursor, window_id));
+ self.scheduler.unschedule(TimerId::new(Topic::BlinkTimeout, window_id));
+
+ // Reset blinkinig timeout.
+ *self.cursor_blink_timed_out = false;
+
if blinking && self.terminal.is_focused {
- let event = Event::new(EventType::BlinkCursor, self.display.window.id());
- let interval =
- Duration::from_millis(self.config.terminal_config.cursor.blink_interval());
- self.scheduler.schedule(event, interval, true, timer_id);
+ self.schedule_blinking();
+ self.schedule_blinking_timeout();
} else {
self.display.cursor_hidden = false;
*self.dirty = true;
}
}
+
+ fn schedule_blinking(&mut self) {
+ let window_id = self.display.window.id();
+ let timer_id = TimerId::new(Topic::BlinkCursor, window_id);
+ let event = Event::new(EventType::BlinkCursor, window_id);
+ let blinking_interval =
+ Duration::from_millis(self.config.terminal_config.cursor.blink_interval());
+ self.scheduler.schedule(event, blinking_interval, true, timer_id);
+ }
+
+ fn schedule_blinking_timeout(&mut self) {
+ let blinking_timeout = self.config.terminal_config.cursor.blink_timeout();
+ if blinking_timeout == 0 {
+ return;
+ }
+
+ let window_id = self.display.window.id();
+ let blinking_timeout_interval = Duration::from_secs(blinking_timeout);
+ let event = Event::new(EventType::BlinkCursorTimeout, window_id);
+ let timer_id = TimerId::new(Topic::BlinkTimeout, window_id);
+
+ self.scheduler.schedule(event, blinking_timeout_interval, false, timer_id);
+ }
}
#[derive(Debug, Eq, PartialEq)]
@@ -1048,6 +1077,14 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
self.ctx.display.cursor_hidden ^= true;
*self.ctx.dirty = true;
},
+ EventType::BlinkCursorTimeout => {
+ // Disable blinking after timeout reached.
+ let timer_id = TimerId::new(Topic::BlinkCursor, self.ctx.display.window.id());
+ self.ctx.scheduler.unschedule(timer_id);
+ self.ctx.display.cursor_hidden = false;
+ *self.ctx.cursor_blink_timed_out = true;
+ *self.ctx.dirty = true;
+ },
EventType::Message(message) => {
self.ctx.message_buffer.push(message);
self.ctx.display.pending_update.dirty = true;
diff --git a/alacritty/src/scheduler.rs b/alacritty/src/scheduler.rs
index 924f5904..08388b94 100644
--- a/alacritty/src/scheduler.rs
+++ b/alacritty/src/scheduler.rs
@@ -27,6 +27,7 @@ pub enum Topic {
SelectionScrolling,
DelayedSearch,
BlinkCursor,
+ BlinkTimeout,
}
/// Event scheduled to be emitted at a specific time.
diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs
index f04a8e04..a45b9404 100644
--- a/alacritty/src/window_context.rs
+++ b/alacritty/src/window_context.rs
@@ -43,6 +43,7 @@ pub struct WindowContext {
pub display: Display,
event_queue: Vec<GlutinEvent<'static, Event>>,
terminal: Arc<FairMutex<Term<EventProxy>>>,
+ cursor_blink_timed_out: bool,
modifiers: ModifiersState,
search_state: SearchState,
received_count: usize,
@@ -151,6 +152,7 @@ impl WindowContext {
master_fd,
#[cfg(not(windows))]
shell_pid,
+ cursor_blink_timed_out: Default::default(),
suppress_chars: Default::default(),
message_buffer: Default::default(),
received_count: Default::default(),
@@ -267,6 +269,7 @@ impl WindowContext {
let old_is_searching = self.search_state.history_index.is_some();
let context = ActionContext {
+ cursor_blink_timed_out: &mut self.cursor_blink_timed_out,
message_buffer: &mut self.message_buffer,
received_count: &mut self.received_count,
suppress_chars: &mut self.suppress_chars,
diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs
index 40c42d4f..5822d591 100644
--- a/alacritty_terminal/src/config/mod.rs
+++ b/alacritty_terminal/src/config/mod.rs
@@ -1,4 +1,4 @@
-use std::cmp::max;
+use std::cmp;
use std::collections::HashMap;
use std::path::PathBuf;
@@ -13,6 +13,7 @@ use crate::ansi::{CursorShape, CursorStyle};
pub use crate::config::scrolling::{Scrolling, MAX_SCROLLBACK_LINES};
pub const LOG_TARGET_CONFIG: &str = "alacritty_config_derive";
+
const MIN_BLINK_INTERVAL: u64 = 10;
/// Top-level config type.
@@ -75,6 +76,7 @@ pub struct Cursor {
thickness: Percentage,
blink_interval: u64,
+ blink_timeout: u8,
}
impl Default for Cursor {
@@ -83,6 +85,7 @@ impl Default for Cursor {
thickness: Percentage(0.15),
unfocused_hollow: true,
blink_interval: 750,
+ blink_timeout: 5,
style: Default::default(),
vi_mode_style: Default::default(),
}
@@ -107,7 +110,18 @@ impl Cursor {
#[inline]
pub fn blink_interval(self) -> u64 {
- max(self.blink_interval, MIN_BLINK_INTERVAL)
+ cmp::max(self.blink_interval, MIN_BLINK_INTERVAL)
+ }
+
+ #[inline]
+ pub fn blink_timeout(self) -> u64 {
+ const MILLIS_IN_SECOND: u64 = 1000;
+ match self.blink_timeout {
+ 0 => 0,
+ blink_timeout => {
+ cmp::max(self.blink_interval * 5 / MILLIS_IN_SECOND, blink_timeout as u64)
+ },
+ }
}
}