diff --git a/src/config/Config.zig b/src/config/Config.zig index baac2cde7..2ed084a64 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -478,6 +478,41 @@ foreground: Color = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF }, /// This value does not apply to Emoji or images. @"minimum-contrast": f64 = 1, +/// The amount of time it takes for blinking text and cursors to toggle between +/// being invisible and visible. +/// Any cell on the screen could be set to blink by setting SGR attribute 5, +/// while cursor blinking is controlled by the `cursor-style-blink` setting. +/// +/// The interval is specified as a series of numbers followed by time units. +/// Whitespace is allowed between numbers and units. Each number and unit will +/// be added together to form the total interval. +/// +/// Blinking is disabled when the interval is set to zero. +/// +/// The allowed time units are as follows: +/// +/// * `y` - 365 SI days, or 8760 hours, or 31536000 seconds. No adjustments +/// are made for leap years or leap seconds. +/// * `d` - one SI day, or 86400 seconds. +/// * `h` - one hour, or 3600 seconds. +/// * `m` - one minute, or 60 seconds. +/// * `s` - one second. +/// * `ms` - one millisecond, or 0.001 second. +/// * `us` or `µs` - one microsecond, or 0.000001 second. +/// * `ns` - one nanosecond, or 0.000000001 second. +/// +/// Examples: +/// * `1h30m` +/// * `45s` +/// +/// Units can be repeated and will be added together. This means that +/// `1h1h` is equivalent to `2h`. This is confusing and should be avoided. +/// A future update may disallow this. +/// +/// The maximum value is `584y 49w 23h 34m 33s 709ms 551µs 615ns`. Any +/// value larger than this will be clamped to the maximum value. +@"blink-interval": Duration = .{ .duration = 600 * std.time.ns_per_ms }, + /// Color palette for the 256 color form that many terminal applications use. /// The syntax of this configuration is `N=COLOR` where `N` is 0 to 255 (for /// the 256 colors in the terminal color table) and `COLOR` is a typical RGB diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 87bdeba93..796907b8e 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -18,7 +18,6 @@ const Allocator = std.mem.Allocator; const log = std.log.scoped(.renderer_thread); const DRAW_INTERVAL = 8; // 120 FPS -const BLINK_INTERVAL = 600; /// The type used for sending messages to the IO thread. For now this is /// hardcoded with a capacity. We can make this a comptime parameter in @@ -112,10 +111,18 @@ flags: packed struct { pub const DerivedConfig = struct { custom_shader_animation: configpkg.CustomShaderAnimation, + blink_interval: u64, pub fn init(config: *const configpkg.Config) DerivedConfig { + const blink_interval = std.math.divTrunc( + u64, + config.@"blink-interval".duration, + std.time.ns_per_ms, + ) catch std.math.maxInt(u64); + return .{ .custom_shader_animation = config.@"custom-shader-animation", + .blink_interval = blink_interval, }; } }; @@ -238,14 +245,16 @@ fn threadMain_(self: *Thread) !void { try self.wakeup.notify(); // Start the blinking timer. - self.blink_h.run( - &self.loop, - &self.blink_c, - BLINK_INTERVAL, - Thread, - self, - blinkTimerCallback, - ); + if (self.config.blink_interval > 0) { + self.blink_h.run( + &self.loop, + &self.blink_c, + self.config.blink_interval, + Thread, + self, + blinkTimerCallback, + ); + } // Start the draw timer self.startDrawTimer(); @@ -385,14 +394,16 @@ fn drainMailbox(self: *Thread) !void { self.startDrawTimer(); // If we're focused, we immediately start blinking again - self.blink_h.run( - &self.loop, - &self.blink_c, - BLINK_INTERVAL, - Thread, - self, - blinkTimerCallback, - ); + if (self.blink_c.state() != .active and self.config.blink_interval > 0) { + self.blink_h.run( + &self.loop, + &self.blink_c, + self.config.blink_interval, + Thread, + self, + blinkTimerCallback, + ); + } } }, @@ -632,7 +643,8 @@ fn blinkTimerCallback( t.wakeup.notify() catch {}; - t.blink_h.run(&t.loop, &t.blink_c, BLINK_INTERVAL, Thread, t, blinkTimerCallback); + t.blink_h.run(&t.loop, &t.blink_c, t.config.blink_interval, Thread, t, blinkTimerCallback); + return .disarm; }