diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 66db754c9..6b1adb12f 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -14,6 +14,7 @@ - Fixed LaTeX legacy font switches falling back to raw source, centered `cases` layouts around surrounding equations, and vertically laid out unsupported and nested display scripts ([#8827](https://github.com/earendil-works/pi/issues/8827), [#9564](https://github.com/earendil-works/pi/issues/9564), [#7929](https://github.com/earendil-works/pi/issues/7929)). - Fixed fullscreen clipboard failures hiding actionable backend error messages behind a generic notice, and extended failure notices to five seconds ([#9618](https://github.com/earendil-works/pi/issues/9618)). +- Fixed fullscreen Kitty images being erased by later row clears in WezTerm ([#9169](https://github.com/earendil-works/pi/issues/9169)). ## [0.85.1] - 2026-09-05 diff --git a/packages/tui/src/tui-alt-screen.ts b/packages/tui/src/tui-alt-screen.ts index 4b5bfaaaf..1b3d2614d 100644 --- a/packages/tui/src/tui-alt-screen.ts +++ b/packages/tui/src/tui-alt-screen.ts @@ -1705,9 +1705,24 @@ export class TuiAltScreen extends TuiBase implements ViewportTUI { } buffer += preparedKittyScreen.evictedImageDeletion; + // WezTerm erases intersecting Kitty image cells when a later EL clears a covered row. + // Only separate clearing from drawing for WezTerm frames that place images; preserve the + // existing interleaved output for text-only frames and every other terminal. + const clearRowsBeforeKittyImages = + redrawImages && + this.imageProtocol === "kitty" && + screen.some(isImageLine) && + (Boolean(process.env.WEZTERM_PANE) || process.env.TERM_PROGRAM?.toLowerCase() === "wezterm"); + if (clearRowsBeforeKittyImages) { + for (let row = 0; row < height; row++) { + if (!fullRedraw && !imagesNeedRedraw && screen[row] === this.previousScreen[row]) continue; + buffer += `\x1b[${row + 1};1H\x1b[2K`; + } + } + for (let row = 0; row < height; row++) { if (!fullRedraw && !imagesNeedRedraw && screen[row] === this.previousScreen[row]) continue; - buffer += `\x1b[${row + 1};1H\x1b[2K${preparedKittyScreen.lines[row] ?? ""}`; + buffer += `\x1b[${row + 1};1H${clearRowsBeforeKittyImages ? "" : "\x1b[2K"}${preparedKittyScreen.lines[row] ?? ""}`; } if (cursorPos) {