Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/config/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,18 @@ palette: Palette = .{},
/// * `block_hollow`
@"cursor-style": terminal.CursorStyle = .block,

/// The style of the unfocused cursor. When a window loses focus,
/// its cursor is always shown so its position stays visible.
///
/// The default is `block_hollow`, which preserves the original behavior.
///
/// When the window is focused, the cursor style is unaffected by this option
/// and instead follows `cursor-style`, `DECSCUSR` (`CSI q`), and shell
/// integration.
///
/// Accepts the same values as `cursor-style`.
@"cursor-style-unfocused": terminal.CursorStyle = .block_hollow,

/// Sets the default blinking state of the cursor. This is just the default
/// state; running programs may override the cursor style using `DECSCUSR` (`CSI
/// q`).
Expand Down
28 changes: 27 additions & 1 deletion src/renderer/cursor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub const StyleOptions = struct {
preedit: bool = false,
focused: bool = false,
blink_visible: bool = false,
unfocused_style: Style = .block_hollow,
};

/// Returns the cursor style to use for the current render state or null
Expand Down Expand Up @@ -57,7 +58,7 @@ pub fn style(

// If we're not focused, our cursor is always visible so that
// we can show the hollow box.
if (!opts.focused) return .block_hollow;
if (!opts.focused) return opts.unfocused_style;

// If the cursor is blinking and our blink state is not visible,
// then we don't show the cursor.
Expand Down Expand Up @@ -86,6 +87,31 @@ test "cursor: default uses configured style" {
try testing.expect(style(&state, .{ .preedit = false, .focused = true, .blink_visible = false }) == null);
}

test "cursor: unfocused uses configured unfocused style" {
const testing = std.testing;
const alloc = testing.allocator;
var term: terminal.Terminal = try .init(alloc, .{ .cols = 10, .rows = 10 });
defer term.deinit(alloc);

term.screens.active.cursor.cursor_style = .bar;
term.modes.set(.cursor_blinking, true);

var state: terminal.RenderState = .empty;
defer state.deinit(alloc);
try state.update(alloc, &term);

try testing.expect(style(&state, .{ .focused = false, .unfocused_style = .bar, .blink_visible = true }) == .bar);
try testing.expect(style(&state, .{ .focused = false, .unfocused_style = .bar, .blink_visible = false }) == .bar);
try testing.expect(style(&state, .{ .focused = false, .unfocused_style = .underline }) == .underline);
try testing.expect(style(&state, .{ .focused = false, .unfocused_style = .block }) == .block);

try testing.expect(style(&state, .{ .focused = false }) == .block_hollow);

try testing.expect(style(&state, .{ .focused = true, .unfocused_style = .underline, .blink_visible = true }) == .bar);

try testing.expect(style(&state, .{ .preedit = true, .focused = false, .unfocused_style = .bar }) == .block);
}

test "cursor: blinking disabled" {
const testing = std.testing;
const alloc = testing.allocator;
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/generic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
cursor_color: ?configpkg.Config.TerminalColor,
cursor_opacity: f64,
cursor_text: ?configpkg.Config.TerminalColor,
cursor_style_unfocused: terminal.CursorStyle,
background: terminal.color.RGB,
background_opacity: f64,
background_opacity_cells: bool,
Expand Down Expand Up @@ -616,6 +617,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
.cursor_color = config.@"cursor-color",
.cursor_text = config.@"cursor-text",
.cursor_opacity = @max(0, @min(1, config.@"cursor-opacity")),
.cursor_style_unfocused = config.@"cursor-style-unfocused",

.background = config.background.toTerminalRGB(),
.foreground = config.foreground.toTerminalRGB(),
Expand Down Expand Up @@ -1379,6 +1381,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
.preedit = critical.preedit != null,
.focused = self.focused,
.blink_visible = cursor_blink_visible,
.unfocused_style = .fromTerminal(self.config.cursor_style_unfocused),
}),
&critical.links,
) catch |err| {
Expand Down