Repository navigation
Resize with OSC 133 prompt redraw accumulates duplicate prompt lines (regression in dde3d4d6b) #13629
Replies: 1 comment
|
Adding a Linux data point on 1.4.0, in case it helps validate the fix. Environment:
Repro on 1.4.0:
Each grid resize leaves another copy of the prompt. After six font changes the window shows roughly 20 stale prompt banners plus an old clock. The stale content is present in a capture of the window itself, so it is not only a full-screen compositor artifact. Controls:
I did not inspect the terminal text model, so I cannot confirm these are the same duplicated cells described in the report; visually the accumulation looks identical. On 1.4.0, #14706 is already included but #14707 is not. Is #14707 expected to cover this Linux case? I can build that branch and report before/after captures. I can also provide the images and logs. AI disclosure: this investigation and draft were assisted by Claude Code; I reviewed the results and verified them on my machine. |
Uh oh!
There was an error while loading. Please reload this page.
Resize with OSC 133 prompt redraw accumulates duplicate prompt lines (regression in dde3d4d)
Summary
After
dde3d4d6b("terminal: screen resize failures are now safe"), resizing the window with a shell that redraws its prompt on SIGWINCH (e.g. zsh + powerlevel10k) leaves stale prompt content behind on every resize. Duplicates accumulate with each zoom/drag cycle. Ghostty 1.3.1 does not have this problem.Environment
7d748097a069768e12fa9bf63d598215a3e8f7a3(1.3.2-dev), libghostty / GhosttyKit consumer on macOS; also reproduced with the stock Ghostty macOS app built at that commit. Still present onmainas of 2026-08-05 (the clear is still after reflow inScreen.resize).Symptom
Open a fresh window, stay at the initial prompt, then resize the window (drag an edge, or double-click the titlebar to zoom/restore). Each resize adds another copy of (part of) the prompt.
ghostty_surface_read_textconfirms the duplicates exist in the terminal text model, so it is not a rendering artifact.Notably, the condition is specific: a prompt whose first line is exactly full-width (p10k's right-aligned segments do this), drawn under OSC 133 marks, with a shell that redraws the prompt on SIGWINCH.
Bisect
89b103dd5(terminal: more full featured resize) — gooddde3d4d6b(terminal: screen resize failures are now safe) — first badI used a deterministic oracle for the bisect: a terminal-level test that replays a real zsh+p10k byte stream captured from a PTY (OSC 133 marks included) through
Terminal+vtStream, performing 5 resize cycles of 80→100→80 cols with the shell's actual redraw bytes in between, then counting prompt occurrences inplainString. Result: 2 occurrences (baseline, same as 1.3.1) beforedde3d4d6b, 7 after it.Root cause
dde3d4d6bmoved the redrawable-prompt clear (clearPromptForRedraw) inScreen.resizefrom beforePageList.resize(reflow) to after it, so that a failed resize leaves the prompt untouched.Clearing after reflow breaks the prompt lookup:
clearPromptForRedrawlocates the prompt start viapromptIterator(.left_up)from the cursor. After reflow mangled the marks (e.g. a split row tail marked.prompt, cursor landing on a.prompt_continuationrow), the iterator finds a later start row.With the pre-
dde3d4d6bordering, reflow operates on already-blanked prompt rows, so nothing stale can survive — this is the behavior 1.3.1 shipped.Proposed fix
Move the clear back before the fallible resize:
and remove the post-resize call. The clear itself is infallible; if the resize then fails, the prompt cells are blank until the shell redraws on the next successful resize — the same trade-off 1.3.1 shipped for years.
One existing test needs a small adjustment:
Screen: resize errors preserve stateasserted the prompt survives a failed resize withprompt_redraw = .true; with the restored ordering that no longer holds, so the test now uses.false(it still verifies the fallible resize work itself is atomic).Verification
dde3d4d6bitself, moving only this call site restores the baseline — no other hunk of that commit is involved.zig build testsuite at7d748097a+ fix: 3271 passed, 0 failed.I have the fix as a patch with the replay regression test and can open a PR if you'd like (I have not gone through the vouch process yet).
Possibly related
Discussion #9903 ("Dragging split divider causes repeated shell prompt insertion") describes a similar symptom, but it predates
dde3d4d6b, so it may be a separate issue.AI disclosure
This investigation (bisect, replay harness, root-cause analysis, fix, and this report) was carried out with AI assistance (Kimi Code). I reviewed the analysis, the fix, and this report, and verified the fix on my machine before submitting.
All reactions