Skip to content

Fix blank first page of scrollback after initial output burst#100

Merged
dakra merged 1 commit intomainfrom
fix-bootstrap-scrollback-blank
Apr 13, 2026
Merged

Fix blank first page of scrollback after initial output burst#100
dakra merged 1 commit intomainfrom
fix-bootstrap-scrollback-blank

Conversation

@dakra
Copy link
Copy Markdown
Owner

@dakra dakra commented Apr 13, 2026

Summary

  • When a fresh terminal received a burst of output, scrolling up in copy mode showed blank lines for the first page instead of actual content
  • The scrollback promotion optimisation incorrectly reused stale empty viewport rows from the initial render
  • Skip promotion when scrollback_in_buffer == 0 and delta >= rows (entire viewport scrolled off during bootstrap)
  • Small deltas (delta < rows) still promote — the top rows sat above the cursor and weren't overwritten, preserving text properties (URLs, prompt markers)

Test plan

  • New test ghostel-test-scrollback-bootstrap-not-blank — fails without fix, passes with it
  • Existing ghostel-test-scrollback-preserves-url-properties still passes (promotion preserved for small deltas)
  • make -j4 all — 140 tests pass
  • Manual: start fresh ghostel, run ls -l /usr, enter copy mode, scroll to top — should show actual content

When a fresh terminal rendered its initial (mostly empty) viewport and
then received a burst of output that overflowed the screen, the
scrollback promotion optimisation incorrectly kept the stale empty
buffer rows as scrollback instead of fetching the real content from
libghostty.

The promotion assumes buffer rows match what libghostty scrolled off.
This holds in steady state (cursor at bottom, top rows scroll off
unmodified) but fails during bootstrap: the cursor starts at the top,
output overwrites the empty viewport rows before they scroll off, so
the buffer has stale content.

Skip promotion when scrollback_in_buffer == 0 AND delta >= rows (the
entire viewport scrolled off).  When delta < rows, only the topmost
rows scrolled off — those sat above the cursor and were not
overwritten, so promotion (and its text-property preservation) remains
safe.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a rendering/scrollback sync edge case where the first page of scrollback could appear blank after a fresh terminal receives an initial burst of output, by preventing promotion of stale viewport rows during bootstrap and instead re-fetching the correct scrollback rows from libghostty.

Changes:

  • Add a regression test covering “bootstrap + burst output” to ensure scrollback contains real content (not stale empty rows).
  • Update scrollback promotion logic in redraw() to skip promotion when scrollback_in_buffer == 0 and the scroll delta is at least a full viewport height, falling back to insertScrollbackRange.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
test/ghostel-test.el Adds an ERT regression test asserting scrollback isn’t populated with blank/stale rows after an initial output burst.
src/render.zig Adjusts scrollback sync/promotion logic during redraw to avoid promoting stale initial viewport rows when the entire viewport scrolls off before first scrollback materialization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dakra dakra merged commit f01de74 into main Apr 13, 2026
24 checks passed
@dakra dakra deleted the fix-bootstrap-scrollback-blank branch April 14, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants