Fix screen damage when the terminal is resized with an inline-image chart - #31
Merged
Merged
Conversation
…hart
Found reviewing glassnode-terminal (VS Code / iTerm2, Ink incrementalRendering):
after a resize, rows outside the chart were wiped and stayed wiped.
- When a resize settled, the render effect ran once more with the old committed
size, stamping an old-size image recorded against the new terminal size; the
next commit then blanked that stale area. Skip drawing while the committed
size lags the requested one (the committed update re-runs it at the right size).
- Blanking now skips when the terminal size changed since the stamp (the
terminal reflowed and the host repainted), never writes past the right edge
(a wrapped blank wipes the next row), and never targets rows below Ink's
cursor line ("moving up" a negative amount is a no-op, so those rows all
landed on the cursor's own line, e.g. the host's status bar).
- The iTerm2 redraw interval skips while resizing or at stale coordinates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
From review of this PR: - Ink throttles frame writes and the PNG is often ready first, so the image was placed relative to the cursor of the *previous* frame (misplaced after height changes in non-fullscreen layouts; the removed stale draw used to hide this race). Out-of-band draws now await useApp().waitUntilRenderFlush() (Ink >= 7; one throttle interval on older Ink) before reading the anchor. - Skipping the blank on any size change left old image cells behind on width grow / non-fullscreen height change (Ink doesn't clear, unchanged lines are not rewritten). Skip only when the width shrank (Ink cleared and the terminal reflowed) or a fullscreen frame's row count changed (its anchor moved). - Blank rows above the screen's top line are skipped (cursor-up clamps, so they all rewrote row 1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
…ncremental rendering Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Found while reviewing glassnode-terminal PR #13, in VS Code and iTerm2 (inline images) with Ink
incrementalRendering. After a terminal resize with a chart on screen, parts of the host UI were wiped and stayed wiped:Root cause
Fix (
src/InkUPlot.tsx), revised after reviewmainand that the stale draw removed above had been hiding. Image writes now awaituseApp().waitUntilRenderFlush()(Ink ≥ 7, or one throttle interval on older Ink) before reading the anchor.Verification
New tests in
test/inline-cleanup.test.tsx:All three fail on
main.Added after review:
test/render-flush.test.tsx: no image is written untilwaitUntilRenderFlushresolves92 tests pass.
An image-aware emulator (it paints inline images as cells that text writes and erases remove, like xterm.js):
main.glassnode-terminal in a pseudo-terminal plus terminal emulator (
pyte), with the chart shown and the terminal resized from 160×30 to 110×30, 160×24, 200×30 and 160×40, in both VS Code and iTerm2 modes: