Windows was previously only compile-checked. With Wine 11 (staging) and mingw available, scripts/windows-wine-test.sh (`just test-windows-wine`) builds expat/FreeType/fontconfig for mingw under target/wine-deps and runs the test suites of ghostty-vt, unicode, datastruct, input, os, config, terminal, crash, termio and cli under Wine (~2,700 tests). New termio/tests/exec_windows.rs drives real cmd.exe children over ConPTY through Termio (output, exit codes, typing, 120 KiB writes, stop, start failure). Fixes found: Windows paths from fs::canonicalize leaked the \\?\ prefix (new ghostty_os::path::realpath strips it like Zig); ghostty-font compiles hb-ft for bundled HarfBuzz on Windows; ~25 tests had Unix assumptions. Wine limitations are ignored with reasons (ResizePseudoConsole stub, no POSIX rename over existing files) - docs/rewrite/notes/windows-wine.md. +list-themes preview parity (former KNOWN_DIFFERENCES rows 5-9): the search box ports vaxis TextInput (word navigation and editing bindings, grapheme-wise editing), ASCII-only case folding, light initial colors until terminal reports arrive (no COLORFGBG), and load errors end the preview with exit 1; PTY tests compare with /usr/bin/ghostty. Test Plan: - just test-windows-wine - cargo test -p ghostty-cli --test list_themes_pty - cargo test --workspace --no-fail-fast (3601 passed)
4.7 KiB
Windows code under Wine (agent WINE)
just test-windows-wine (= scripts/windows-wine-test.sh [cargo test args])
runs the x86_64-pc-windows-gnu test binaries under Wine 11.19 (staging) with
the mingw-w64 toolchain. Dedicated WINEPREFIX=target/wine-prefix,
WINEDEBUG=-all, no display (console tests only). RUSTC_WRAPPER= (kache
breaks cc-rs), RUSTFLAGS=--cfg wine (lets tests mark Wine limitations as
ignored; cfg(wine) is declared in the workspace lints and ghostty-termio),
WINEPATH for the mingw runtime DLLs (libstdc++ from the bundled HarfBuzz).
Native dependencies
Linking needs real libraries. The script builds them once into
target/wine-deps/prefix (like Ghostty, from source): expat 2.6.4 (tarball is
downloaded, or EXPAT_TARBALL=), FreeType (the sources vendored in
freetype-sys) and fontconfig 2.14.2 (zig package cache copy, FONTCONFIG_SRC=,
or a download) with cmake/meson cross builds. HarfBuzz/FreeType/oniguruma for
the -sys crates come from their bundled features as before.
What ran (final run, exit 0)
| crate | passed | ignored |
|---|---|---|
| ghostty-vt | 486 | 1 (pre-existing) |
| ghostty-unicode | 20 | 0 |
| ghostty-datastruct | 88 | 0 |
| ghostty-input | 237 | 0 |
| ghostty-os | 97 | 0 |
| ghostty-config | 283 + 7 + 4 (integration) | 0 |
| ghostty-terminal | 1275 | 0 |
| ghostty-crash | 33 | 0 |
| ghostty-termio | 107 lib + 2 golden + 10 exec_windows |
1 (Wine) |
| ghostty-cli | 108 | 4 (Wine) |
Before the fixes: cli 7, config 9, os 2, terminal 1, termio 15 failures and a link failure (below).
ghostty-termio/tests/exec_windows.rs is the Windows counterpart of
exec_integration: real cmd.exe children on a real ConPTY through
Termio + Thread (WaitForMultipleObjects loop) + the pipe read thread
against a real Terminal: echo output and exit status, exit 7, Shell
command via %WINDIR%\System32\cmd.exe /C, interactive typing and exit code,
120 KiB of input through the overlapped writer, resize messages
(terminal + ResizePseudoConsole), stop terminating a running child,
messages after exit, start failure shown in the terminal.
Bugs found and fixed
- Link:
harfbuzz-sysbundledis built withoutHAVE_FREETYPE, sohb_ft_font_create_referencedwas missing on Windows.ghostty-font/build.rsnow compileshb-ft.ccagainst the bundled FreeType headers (Zig builds HarfBuzz with FreeType).ccadded as a build-dependency. std::fs::canonicalizereturns\\?\C:\...on Windows, Zig'srealpathreturnsC:\...; the verbatim form rejects/and is not usable as acmd.exeworking directory. Newghostty_os::path::realpathstrips it; used by config path expansion,+new-window,+validate-config, kitty graphics file loading, screen-file writes (faithfulness fix, not a Zig bug).- DEVIANT_FIXES 38: absolute Windows theme paths were rejected (
C:looks like alight:/dark:pair). DEVIANT_FIXES 39:CreateProcessWis called with a literallpApplicationName, so a barecmd.exeargv[0] failed with FileNotFound; PATH is searched first. - Tests with Unix assumptions fixed (platform-aware expectations, no product
change): shell-integration helpers (verbatim path,
;PATH delimiter),xev::prefer(Iocp)(Iocp is a candidate on Windows), i18ninit(no-op on Windows), kitty/proc/guard (POSIX only), config/theme/file-load directory-open errors (Windows givesAccessDeniedfor a directory, matching Zig 0.15OpenFile; soNotAFileisFileOpenFailedthere), path separators,light:/dark:pairs need quoted backslashes (as in Zig),list_themesfile URIs (file://C:%5C..., as Zig'stoUri).
Wine limitations (ignored with wine: reasons)
ResizePseudoConsoleis a stub in Wine 11.19 (fixme:console: ResizePseudoConsole (100,40) stub, faking success): the child never sees the new size.exec_windows::resize_is_applied_to_the_pseudo_consoleis ignored; the terminal-side resize and the API call are still tested.NtSetInformationFile(FileRenameInformationEx, REPLACE_IF_EXISTS| POSIX_SEMANTICS)is unsupported (fixme:file:NtSetInformationFile unsupported flags: 0x3), sostd::fs::renameover an existing file fails withERROR_ACCESS_DENIED. The fourssh_cachedisk-cache tests (atomic temp-file + rename) are ignored; real Windows supports it.- Wine's
cmd.exehas nomode con, and itsfindstrignores/n; tests use a re-run of the test binary as console-size child and%OS%expansion. - Wine maps
/toZ:\; tests on POSIX-looking paths account for it.
Not covered
fontconfig/font discovery and the renderer/core/GTK crates are not run (no Windows apprt); ghostty-font links but its tests are not part of the run.