diff --git a/src/pty.zig b/src/pty.zig index 2977efd5b..c0d082411 100644 --- a/src/pty.zig +++ b/src/pty.zig @@ -55,6 +55,11 @@ const NullPty = struct { _ = self; } + pub fn getMode(self: Pty) error{GetModeFailed}!Mode { + _ = self; + return .{}; + } + pub fn setSize(self: *Pty, size: winsize) !void { _ = self; _ = size; diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 07c92c1b0..bb2a27f44 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -947,11 +947,14 @@ pub fn updateFrame( errdefer screen_copy.deinit(); // Whether to draw our cursor or not. - const cursor_style = renderer.cursorStyle( - state, - self.focused, - cursor_blink_visible, - ); + const cursor_style = if (state.terminal.flags.password_input) + .lock + else + renderer.cursorStyle( + state, + self.focused, + cursor_blink_visible, + ); // Get our preedit state const preedit: ?renderer.State.Preedit = preedit: { @@ -2652,24 +2655,52 @@ fn addCursor( break :alpha @intFromFloat(@ceil(alpha)); }; - const sprite: font.Sprite = switch (cursor_style) { - .block => .cursor_rect, - .block_hollow => .cursor_hollow_rect, - .bar => .cursor_bar, - .underline => .underline, - }; + const render = switch (cursor_style) { + .block, + .block_hollow, + .bar, + .underline, + => render: { + const sprite: font.Sprite = switch (cursor_style) { + .block => .cursor_rect, + .block_hollow => .cursor_hollow_rect, + .bar => .cursor_bar, + .underline => .underline, + .lock => unreachable, + }; - const render = self.font_grid.renderGlyph( - self.alloc, - font.sprite_index, - @intFromEnum(sprite), - .{ - .cell_width = if (wide) 2 else 1, - .grid_metrics = self.grid_metrics, + break :render self.font_grid.renderGlyph( + self.alloc, + font.sprite_index, + @intFromEnum(sprite), + .{ + .cell_width = if (wide) 2 else 1, + .grid_metrics = self.grid_metrics, + }, + ) catch |err| { + log.warn("error rendering cursor glyph err={}", .{err}); + return; + }; + }, + + .lock => self.font_grid.renderCodepoint( + self.alloc, + 0xF023, // lock symbol + .regular, + .text, + .{ + .cell_width = if (wide) 2 else 1, + .grid_metrics = self.grid_metrics, + }, + ) catch |err| { + log.warn("error rendering cursor glyph err={}", .{err}); + return; + } orelse { + // This should never happen because we embed nerd + // fonts so we just log and return instead of fallback. + log.warn("failed to find lock symbol for cursor codepoint=0xF023", .{}); + return; }, - ) catch |err| { - log.warn("error rendering cursor glyph err={}", .{err}); - return; }; self.cells.setCursor(.{ diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 6d39eb445..a8f7c385c 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -767,11 +767,14 @@ pub fn updateFrame( errdefer screen_copy.deinit(); // Whether to draw our cursor or not. - const cursor_style = renderer.cursorStyle( - state, - self.focused, - cursor_blink_visible, - ); + const cursor_style = if (state.terminal.flags.password_input) + .lock + else + renderer.cursorStyle( + state, + self.focused, + cursor_blink_visible, + ); // Get our preedit state const preedit: ?renderer.State.Preedit = preedit: { @@ -1537,24 +1540,52 @@ fn addCursor( break :alpha @intFromFloat(@ceil(alpha)); }; - const sprite: font.Sprite = switch (cursor_style) { - .block => .cursor_rect, - .block_hollow => .cursor_hollow_rect, - .bar => .cursor_bar, - .underline => .underline, - }; + const render = switch (cursor_style) { + .block, + .block_hollow, + .bar, + .underline, + => render: { + const sprite: font.Sprite = switch (cursor_style) { + .block => .cursor_rect, + .block_hollow => .cursor_hollow_rect, + .bar => .cursor_bar, + .underline => .underline, + .lock => unreachable, + }; - const render = self.font_grid.renderGlyph( - self.alloc, - font.sprite_index, - @intFromEnum(sprite), - .{ - .cell_width = if (wide) 2 else 1, - .grid_metrics = self.grid_metrics, + break :render self.font_grid.renderGlyph( + self.alloc, + font.sprite_index, + @intFromEnum(sprite), + .{ + .cell_width = if (wide) 2 else 1, + .grid_metrics = self.grid_metrics, + }, + ) catch |err| { + log.warn("error rendering cursor glyph err={}", .{err}); + return null; + }; + }, + + .lock => self.font_grid.renderCodepoint( + self.alloc, + 0xF023, // lock symbol + .regular, + .text, + .{ + .cell_width = if (wide) 2 else 1, + .grid_metrics = self.grid_metrics, + }, + ) catch |err| { + log.warn("error rendering cursor glyph err={}", .{err}); + return null; + } orelse { + // This should never happen because we embed nerd + // fonts so we just log and return instead of fallback. + log.warn("failed to find lock symbol for cursor codepoint=0xF023", .{}); + return null; }, - ) catch |err| { - log.warn("error rendering cursor glyph err={}", .{err}); - return null; }; try self.cells.append(self.alloc, .{ diff --git a/src/renderer/cursor.zig b/src/renderer/cursor.zig index d05acf9e9..d8769d9e2 100644 --- a/src/renderer/cursor.zig +++ b/src/renderer/cursor.zig @@ -6,11 +6,15 @@ const State = @import("State.zig"); /// This is a superset of terminal cursor styles since the renderer supports /// some additional cursor states such as the hollow block. pub const Style = enum { + // Typical cursor input styles block, block_hollow, bar, underline, + // Special cursor styles + lock, + /// Create a cursor style from the terminal style request. pub fn fromTerminal(term: terminal.CursorStyle) ?Style { return switch (term) {