Skip to content

Commit 3aad8ec

Browse files
authored
Merge pull request #2267 from ghostty-org/pwinput-msg
termio: use surface messages to trigger password input state
2 parents 42e7cbc + e3d528c commit 3aad8ec

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

src/Surface.zig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,9 +818,28 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
818818
.report_color_scheme => try self.reportColorScheme(),
819819

820820
.present_surface => try self.presentSurface(),
821+
822+
.password_input => |v| try self.passwordInput(v),
821823
}
822824
}
823825

826+
/// Called when the terminal detects there is a password input prompt.
827+
fn passwordInput(self: *Surface, v: bool) !void {
828+
{
829+
self.renderer_state.mutex.lock();
830+
defer self.renderer_state.mutex.unlock();
831+
832+
// If our password input state is unchanged then we don't
833+
// waste time doing anything more.
834+
const old = self.io.terminal.flags.password_input;
835+
if (old == v) return;
836+
837+
self.io.terminal.flags.password_input = v;
838+
}
839+
840+
try self.queueRender();
841+
}
842+
824843
/// Sends a DSR response for the current color scheme to the pty.
825844
fn reportColorScheme(self: *Surface) !void {
826845
const output = switch (self.color_scheme) {

src/apprt/surface.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ pub const Message = union(enum) {
6565
/// a window and switching tabs.
6666
present_surface: void,
6767

68+
/// Notifies the surface that password input has started within
69+
/// the terminal. This should always be followed by a false value
70+
/// unless the surface exits.
71+
password_input: bool,
72+
6873
pub const ReportTitleStyle = enum {
6974
csi_21_t,
7075

src/termio/Exec.zig

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ pub fn threadEnter(
143143
.read_thread_pipe = pipe[1],
144144
.read_thread_fd = pty_fds.read,
145145
.termios_timer = termios_timer,
146-
.renderer_wakeup = io.renderer_wakeup,
147146
} };
148147

149148
// Start our process watcher
@@ -460,24 +459,31 @@ fn termiosTimer(
460459
};
461460

462461
// If the mode changed, then we process it.
463-
if (!std.meta.eql(mode, exec.termios_mode)) {
462+
if (!std.meta.eql(mode, exec.termios_mode)) mode_change: {
464463
log.debug("termios change mode={}", .{mode});
465464
exec.termios_mode = mode;
466465

466+
// We assume we're in some sort of password input if we're
467+
// in canonical mode and not echoing. This is a heuristic.
468+
const password_input = mode.canonical and !mode.echo;
469+
470+
// If our password input state changed on the terminal then
471+
// we notify the surface.
467472
{
468473
td.renderer_state.mutex.lock();
469474
defer td.renderer_state.mutex.unlock();
470475
const t = td.renderer_state.terminal;
471-
472-
// We assume we're in some sort of password input if we're
473-
// in canonical mode and not echoing. This is a heuristic.
474-
t.flags.password_input = mode.canonical and !mode.echo;
476+
if (t.flags.password_input == password_input) {
477+
break :mode_change;
478+
}
475479
}
476480

477-
// Notify the renderer of our state change
478-
exec.renderer_wakeup.notify() catch |err| {
479-
log.warn("error notifying renderer err={}", .{err});
480-
};
481+
// We have to notify the surface that we're in password input.
482+
// We must block on this because the balanced true/false state
483+
// of this is critical to apprt behavior.
484+
_ = td.surface_mailbox.push(.{
485+
.password_input = password_input,
486+
}, .{ .forever = {} });
481487
}
482488

483489
// Repeat the timer
@@ -645,9 +651,6 @@ pub const ThreadData = struct {
645651
/// to prevent unnecessary locking of expensive mutexes.
646652
termios_mode: ptypkg.Mode = .{},
647653

648-
/// The handle to wake up the renderer.
649-
renderer_wakeup: xev.Async,
650-
651654
pub fn deinit(self: *ThreadData, alloc: Allocator) void {
652655
posix.close(self.read_thread_pipe);
653656

0 commit comments

Comments
 (0)