mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
Merge pull request #2267 from ghostty-org/pwinput-msg
termio: use surface messages to trigger password input state
This commit is contained in:
@ -818,9 +818,28 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
|
|||||||
.report_color_scheme => try self.reportColorScheme(),
|
.report_color_scheme => try self.reportColorScheme(),
|
||||||
|
|
||||||
.present_surface => try self.presentSurface(),
|
.present_surface => try self.presentSurface(),
|
||||||
|
|
||||||
|
.password_input => |v| try self.passwordInput(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called when the terminal detects there is a password input prompt.
|
||||||
|
fn passwordInput(self: *Surface, v: bool) !void {
|
||||||
|
{
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
|
// If our password input state is unchanged then we don't
|
||||||
|
// waste time doing anything more.
|
||||||
|
const old = self.io.terminal.flags.password_input;
|
||||||
|
if (old == v) return;
|
||||||
|
|
||||||
|
self.io.terminal.flags.password_input = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.queueRender();
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends a DSR response for the current color scheme to the pty.
|
/// Sends a DSR response for the current color scheme to the pty.
|
||||||
fn reportColorScheme(self: *Surface) !void {
|
fn reportColorScheme(self: *Surface) !void {
|
||||||
const output = switch (self.color_scheme) {
|
const output = switch (self.color_scheme) {
|
||||||
|
@ -65,6 +65,11 @@ pub const Message = union(enum) {
|
|||||||
/// a window and switching tabs.
|
/// a window and switching tabs.
|
||||||
present_surface: void,
|
present_surface: void,
|
||||||
|
|
||||||
|
/// Notifies the surface that password input has started within
|
||||||
|
/// the terminal. This should always be followed by a false value
|
||||||
|
/// unless the surface exits.
|
||||||
|
password_input: bool,
|
||||||
|
|
||||||
pub const ReportTitleStyle = enum {
|
pub const ReportTitleStyle = enum {
|
||||||
csi_21_t,
|
csi_21_t,
|
||||||
|
|
||||||
|
@ -143,7 +143,6 @@ pub fn threadEnter(
|
|||||||
.read_thread_pipe = pipe[1],
|
.read_thread_pipe = pipe[1],
|
||||||
.read_thread_fd = pty_fds.read,
|
.read_thread_fd = pty_fds.read,
|
||||||
.termios_timer = termios_timer,
|
.termios_timer = termios_timer,
|
||||||
.renderer_wakeup = io.renderer_wakeup,
|
|
||||||
} };
|
} };
|
||||||
|
|
||||||
// Start our process watcher
|
// Start our process watcher
|
||||||
@ -460,24 +459,31 @@ fn termiosTimer(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If the mode changed, then we process it.
|
// If the mode changed, then we process it.
|
||||||
if (!std.meta.eql(mode, exec.termios_mode)) {
|
if (!std.meta.eql(mode, exec.termios_mode)) mode_change: {
|
||||||
log.debug("termios change mode={}", .{mode});
|
log.debug("termios change mode={}", .{mode});
|
||||||
exec.termios_mode = mode;
|
exec.termios_mode = mode;
|
||||||
|
|
||||||
|
// We assume we're in some sort of password input if we're
|
||||||
|
// in canonical mode and not echoing. This is a heuristic.
|
||||||
|
const password_input = mode.canonical and !mode.echo;
|
||||||
|
|
||||||
|
// If our password input state changed on the terminal then
|
||||||
|
// we notify the surface.
|
||||||
{
|
{
|
||||||
td.renderer_state.mutex.lock();
|
td.renderer_state.mutex.lock();
|
||||||
defer td.renderer_state.mutex.unlock();
|
defer td.renderer_state.mutex.unlock();
|
||||||
const t = td.renderer_state.terminal;
|
const t = td.renderer_state.terminal;
|
||||||
|
if (t.flags.password_input == password_input) {
|
||||||
// We assume we're in some sort of password input if we're
|
break :mode_change;
|
||||||
// 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
|
// We have to notify the surface that we're in password input.
|
||||||
exec.renderer_wakeup.notify() catch |err| {
|
// We must block on this because the balanced true/false state
|
||||||
log.warn("error notifying renderer err={}", .{err});
|
// of this is critical to apprt behavior.
|
||||||
};
|
_ = td.surface_mailbox.push(.{
|
||||||
|
.password_input = password_input,
|
||||||
|
}, .{ .forever = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeat the timer
|
// Repeat the timer
|
||||||
@ -645,9 +651,6 @@ pub const ThreadData = struct {
|
|||||||
/// to prevent unnecessary locking of expensive mutexes.
|
/// to prevent unnecessary locking of expensive mutexes.
|
||||||
termios_mode: ptypkg.Mode = .{},
|
termios_mode: ptypkg.Mode = .{},
|
||||||
|
|
||||||
/// The handle to wake up the renderer.
|
|
||||||
renderer_wakeup: xev.Async,
|
|
||||||
|
|
||||||
pub fn deinit(self: *ThreadData, alloc: Allocator) void {
|
pub fn deinit(self: *ThreadData, alloc: Allocator) void {
|
||||||
posix.close(self.read_thread_pipe);
|
posix.close(self.read_thread_pipe);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user