Resolves the 4 P3 items in docs/rewrite/notes/review-rv13-codex.md
(final-Z16.md):
- async-backend now takes effect like Ghostty: ghostty_os::xev ports
libxev's backend detection (io_uring, then epoll); global init detects
and logs it, the GTK startup applies the config with Zig's messages,
and +version reports the real backend. The termio IO loop runs on a
new reactor with epoll, io_uring (io-uring crate) and poll(2) (kept
for macOS, where libxev uses kqueue). The 21 exec integration tests
run under every backend; io_uring was exercised here.
- auto-update-channel defaults to the build's release channel.
- Windows error names: sharing violation -> AccessDenied, plus
ERROR_FILE_EXISTS -> PathAlreadyExists and virus errors ->
AntivirusInterference, mirroring std.os.windows.OpenFile's NTSTATUS
mapping in Zig 0.15.2 (verified against its source by the
orchestrator).
- Exact ports of std.fs.path.basenameWindows/basenamePosix for theme
name validation (drive, UNC and device roots).
Test Plan:
- cargo test --workspace --no-fail-fast (3555 passed, exit 0)
- just check-macos (both), just check-windows, just check-wasm
- +show-config --default --docs vs /usr/bin/ghostty (only the
build-specific gtk-opengl-debug line differs)
Ports the macOS-specific Zig code behind cfg(target_os = "macos"):
- renderer: a GraphicsApi trait with generic::Renderer<G>; Metal backend
(all renderer/metal/* files, shaders.metal verbatim, runtime library
compile, IOSurface layer, CVDisplayLink), shadertoy -> MSL via naga;
OpenGL remains the backend elsewhere.
- font: CoreText face, shaper and discovery with build.rs backend
selection (coretext default; coretext-freetype / coretext-harfbuzz /
coretext-noshape features), no fontconfig/freetype/harfbuzz on Apple.
- input: KeymapDarwin via UCKeyTranslate, option-as-alt, mac keycodes.
- os: macos, mach, cf_release_thread, NSProcessInfo args and macOS
branches; config: macOS defaults, keybinds, Application Support paths.
- termio/core: login(1) wrapping, openpty/execvpe, Darwin child exit
handling, os_log logging.
Compile-checked for aarch64/x86_64-apple-darwin (clippy -D warnings
clean) using the cross setup in docs/rewrite/notes/macos-M1.md; cannot
run here. The embedded runtime/C API (embedded.zig) is the next step.
Also includes the cross-platform integration edits shared by the crash,
verification, Windows and macOS work (Cargo target-gating, thread
crash-context hooks, apprt-gtk surface/IME refactor, termio/os cfg
gates), a cfg fix so ghostty-config builds on wasm32, and an allow for
the intentional recursion in the crash overflow test.
Test Plan:
- cargo test --workspace (3224 passed)
- cargo clippy --workspace --all-targets -- -D warnings
- cargo check --target aarch64-apple-darwin -p ghostty-renderer (with
the documented cross env)
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)
Ports the parts of Ghostty's IO layer that don't depend on the terminal:
- pty.zig: pty pair, window size, mode, child-side setsid/TIOCSCTTY;
master is CLOEXEC with IUTF8 set
- Command.zig: fork/execvpe with Ghostty's exact child setup (stdio
dup2, best-effort chdir, rlimit restore, os/runtime pre-exec hooks,
cgroup handling) and exit status decoding
- shell_integration.zig for bash/zsh/fish/elvish/nushell plus feature
flags; scripts copied verbatim to resources/shell-integration/
- terminfo generator for xterm-ghostty, byte-identical to Zig's encode
output (golden file produced with the real Zig code)
This crate opts into unsafe_code = "deny" (fork/exec need it) with
allow + SAFETY comments on minimal items.
Integration left: config-derived option types are local stand-ins;
cgroup D-Bus scope creation is a closure hook; Exec/Termio/Thread/
stream_handler wait for ghostty-terminal. Pty now closes both fds on
drop (Zig never auto-closed the slave) - to re-check when wiring Exec.
Test Plan:
- cargo test -p ghostty-termio (52 tests, incl. real pty spawn test
expecting "hi\r\n31 97\r\n" from `echo hi; stty size`)
Start of the full Rust rewrite of Ghostty 1.3.1 (reference source in
../ghostty). Sets up a workspace whose crates mirror Ghostty's Zig modules
(vt, unicode, datastruct, os, input, config, terminal, font, renderer,
termio, core, apprt-gtk) so porting work can proceed in parallel per crate.
Also adds:
- docs/rewrite/{ARCHITECTURE,PLAN,STATUS,AGENT_GUIDE}.md: crate map, core
design decisions (safe Rust, slab-based PageList, logical capacity
accounting), phased plan, progress tracker, and porting rules.
- Workspace clippy config relaxing pedantic lints that are pure noise for
low-level terminal code (casts, long functions).
- Shared vt types needed by several work packages up front: kitty
keyboard flags (kitty/key.rs) and the CSI separator bitset (SepList).
Test Plan:
- cargo test -p ghostty-vt (3 tests pass)
- cargo clippy -p ghostty-vt --all-targets -- -D warnings