Surfaced via wintty-bench diagnostic instrumentation. Wintty replies to a CSI 6 n cursor-position request with an 18-byte payload before the terminating 'R', vs the canonical 6 bytes (\e[<row>;<col>) that Windows Terminal and the VT100 spec emit.
Evidence
From a cursor-query throughput measurement run via wintty-bench (--cells=C5 --terminals=wintty,wt), with bash diagnostic capturing read -d R exit code and response length:
WT (11 iters): stty_exit=0 read_exit=0 resp_len=6
Wintty (11 iters): stty_exit=1 read_exit=0 resp_len=18
Both stty-related symptoms (libghostty's PTY appears to ignore stty -icanon -echo) and resp_len divergence are wintty-side. WT under the same fixture matches the spec.
Why it matters
- Spec deviation: any conformance-checking VT client (vtebench, applications using cursor-position queries for layout, etc.) may misbehave or flag this.
- Performance side-effect: clients reading byte-by-byte until 'R' do 3x more stdin work per query under wintty than under spec-compliant terminals.
- Concrete impact: wintty-bench C5/wsl-unicode cell drifts ~35% under its baseline because of the extra stdin I/O per cursor-query iter.
Likely causes (theories, not yet confirmed)
- Wintty's CSI 6 n handler emits a parameterized form (e.g.
\e[?<row>;<col>;<flag>R) instead of canonical \e[<row>;<col>R.
- Wintty's libghostty PTY is concatenating the cursor reply with another auto-response (DA1, OSC, etc.).
- Wintty double-replies because it processes the query through both its internal parser and a forwarded path.
Reproduce
From a real pwsh terminal:
cd C:\Users\Alessandro\CODE\OSS\wintty-bench
# Add `printf 'hex='; printf '%s' "$_resp" | xxd -p; printf '\n'` after the read in BuildWslCommand
dotnet run --project harness -- --mode=ci --cells=C5 --terminals=wintty --target="<release Wintty.exe>"
Get-Content ${env:TEMP}\wintty-bench-scripts\C5-*.log
The hex of _resp pins the exact byte sequence wintty emits.
Scope
Investigate where wintty handles CSI 6 n (likely in libghostty's terminal/parser layer or in the PTY response path) and ensure the response is the canonical \e[<row>;<col>R form. Add a regression test if the parser/terminal layer has unit-test coverage.
Tracked from wintty-bench side at deblasis/wintty-bench # 25 (closed; cross-reference for context).
Surfaced via wintty-bench diagnostic instrumentation. Wintty replies to a CSI 6 n cursor-position request with an 18-byte payload before the terminating 'R', vs the canonical 6 bytes (
\e[<row>;<col>) that Windows Terminal and the VT100 spec emit.Evidence
From a cursor-query throughput measurement run via wintty-bench (--cells=C5 --terminals=wintty,wt), with bash diagnostic capturing
read -d Rexit code and response length:Both stty-related symptoms (libghostty's PTY appears to ignore
stty -icanon -echo) and resp_len divergence are wintty-side. WT under the same fixture matches the spec.Why it matters
Likely causes (theories, not yet confirmed)
\e[?<row>;<col>;<flag>R) instead of canonical\e[<row>;<col>R.Reproduce
From a real pwsh terminal:
The hex of
_resppins the exact byte sequence wintty emits.Scope
Investigate where wintty handles CSI 6 n (likely in libghostty's terminal/parser layer or in the PTY response path) and ensure the response is the canonical
\e[<row>;<col>Rform. Add a regression test if the parser/terminal layer has unit-test coverage.Tracked from wintty-bench side at deblasis/wintty-bench # 25 (closed; cross-reference for context).