From 39627e32211efcf7d9022f189b927914bd7edae6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 18 Sep 2024 10:44:03 -0700 Subject: [PATCH] termio: set pw input state on terminal and wake up renderer --- src/terminal/Terminal.zig | 5 +++++ src/termio/Exec.zig | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index b3e19b708..882ef41c0 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -119,6 +119,11 @@ flags: packed struct { /// True if the window is focused. focused: bool = true, + /// True if the terminal is in a password entry mode. This is set + /// to true based on termios state. This is set + /// to true based on termios state. + password_input: bool = false, + /// Dirty flags for the renderer. dirty: Dirty = .{}, } = .{}, diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 41bbc628d..175dc98bf 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -143,6 +143,7 @@ pub fn threadEnter( .read_thread_pipe = pipe[1], .read_thread_fd = pty_fds.read, .termios_timer = termios_timer, + .renderer_wakeup = io.renderer_wakeup, } }; // Start our process watcher @@ -425,7 +426,26 @@ fn termiosTimer( break :err .{}; }; - log.warn("termios mode={}", .{mode}); + // If the mode changed, then we process it. + if (!std.meta.eql(mode, exec.termios_mode)) { + log.debug("termios change mode={}", .{mode}); + exec.termios_mode = mode; + + { + td.renderer_state.mutex.lock(); + defer td.renderer_state.mutex.unlock(); + const t = td.renderer_state.terminal; + + // We assume we're in some sort of password input if we're + // in canonical mode and not echoing. This is a heuristic. + t.flags.password_input = mode.canonical and !mode.echo; + } + + // Notify the renderer of our state change + exec.renderer_wakeup.notify() catch |err| { + log.warn("error notifying renderer err={}", .{err}); + }; + } // Repeat the timer exec.termios_timer.run( @@ -585,6 +605,13 @@ pub const ThreadData = struct { termios_timer: xev.Timer, termios_timer_c: xev.Completion = .{}, + /// The last known termios mode. Used for change detection + /// to prevent unnecessary locking of expensive mutexes. + termios_mode: ptypkg.Mode = .{}, + + /// The handle to wake up the renderer. + renderer_wakeup: xev.Async, + pub fn deinit(self: *ThreadData, alloc: Allocator) void { posix.close(self.read_thread_pipe);