feat(termio): port the IO thread, Exec backend and stream handler
Ports the remainder of ZIG/src/termio: Options, backend, message, mailbox, Termio, Thread, Exec and stream_handler. Threading model (replacing libxev): the IO thread owns Termio and runs a single poll(2) loop over the mailbox eventfd, a stop eventfd, the child pidfd and pty POLLOUT, driving Ghostty's timers (25 ms resize coalescing, 1 s synchronized-output, 15 ms selection scroll, 200 ms termios polling). A separate pty read thread locks the shared renderer state and feeds the terminal. Renderer and surface interaction go through RendererMailbox/SurfaceMailbox traits. The stream handler answers all queries (DA, DSR, XTVERSION, DECRQM, OSC color queries, XTGETTCAP, DECRQSS, ...) and forwards titles, pwd, OSC 52, notifications, progress and bell as surface messages. Zig unlocks the renderer mutex when a mailbox is full; here overflow goes to an ordered outbox flushed after the locks drop. IO1's local stand-ins are replaced with the real config types. Open: RendererState lives in termio for now (renderer State.zig is being ported); kitty graphics replies and tmux viewer are not hooked up; wait-after-command lives in Surface (core); Flatpak stop path needs a ghostty-os change. Test Plan: - cargo test -p ghostty-termio (102 unit + 21 end-to-end tests on a real pty, incl. backpressure, DA1 replies, resize coalescing, exits)
This commit is contained in:
1 parent
0c92dd0966
commit
c81375e6f1
19 files changed
+6170
-195
No files matched your search
@@ -0,0 +1,37 @@
|
||||
//! The shared render state (`renderer/State.zig`, the part termio needs).
|
||||
//!
|
||||
//! In Zig the terminal is owned by `Termio` and `renderer.State` holds a
|
||||
//! mutex plus a pointer to it. In Rust the terminal lives inside the mutex,
|
||||
//! shared via `Arc` between the IO thread, the pty read thread, the
|
||||
//! surface (core) thread and the renderer thread.
|
||||
//!
|
||||
//! TODO(integration): `renderer/State.zig` is deferred in ghostty-renderer;
|
||||
//! when it lands, this type should move there (and gain `inspector`,
|
||||
//! `preedit`, `mouse`).
|
||||
|
||||
use std::sync::{Mutex, MutexGuard, PoisonError};
|
||||
|
||||
use ghostty_terminal::terminal::Terminal;
|
||||
|
||||
/// The state shared with the renderer.
|
||||
#[derive(Debug)]
|
||||
pub struct RendererState {
|
||||
/// The terminal emulator state. Hold the lock for as short as possible;
|
||||
/// it is contended by the pty read thread.
|
||||
pub terminal: Mutex<Terminal>,
|
||||
}
|
||||
|
||||
impl RendererState {
|
||||
pub fn new(terminal: Terminal) -> Self {
|
||||
Self {
|
||||
terminal: Mutex::new(terminal),
|
||||
}
|
||||
}
|
||||
|
||||
/// Lock the terminal. Lock poisoning is ignored: a panic on another
|
||||
/// thread must not take the whole terminal down with it (Zig mutexes
|
||||
/// don't poison).
|
||||
pub fn lock(&self) -> MutexGuard<'_, Terminal> {
|
||||
self.terminal.lock().unwrap_or_else(PoisonError::into_inner)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user