Skip to content

libghostty-vt: clearing scrollback makes historical Kitty images reappear at the top-left #14831

Closed

Description

@jcollie

Discussed in #14830

Originally posted by IdrisGit October 24, 2026

Issue Description

I first encountered this while using Pi inside Herdr with a session containing images.

After exiting Pi with Ctrl+C twice, I ran clear. The text disappeared, but an image from earlier in the conversation appeared over the top-left of the terminal, covering the shell prompt. The shell still accepted input behind the image. Running clear a second time removed it.

I used Pi to help investigate terminal image handling. That investigation helped me produced the a corresponding image-placement failure through the public C API on unmodified upstream libghostty-vt.

The reproduction does not require Pi, Herdr, a GUI, PNG decoding or image files.

Separate tests in my installed Ghostty 1.3.1+omarchy.3 stable application did not reproduce the symptom, including synthetic Pi image-session exit/clear tests. This report concerns the libghostty-vt: library.

Expected Behavior

Clearing the visible display and scrollback once should not make an image from the discarded history visible again. A second clear should not be necessary.

Screen-only clearing should preserve images wholly in retained scrollback; subsequently discarding that history should not relocate those images onto unrelated visible rows.

Actual Behavior

After CSI H, CSI 2J, then CSI 3J, the historical image placement moves from viewport row -31 to (0, 0) and reports viewport_visible = true.

Repeating the complete clear command removes it.

Reproduction Steps

The attached repro.c:

  1. Creates a 40-column, 10-row in-memory terminal.
  2. Displays a synthetic one-pixel RGBA image over 8 columns and 3 rows.
  3. Prints 40 lines, moving the image entirely into scrollback.
  4. Sends \x1b[H\x1b[2J, then \x1b[3J, inspecting placements between operations.
  5. Repeats the complete clear and inspects placements again.

From a Ghostty checkout at 22f100c6367045bb5fc86172f837047dee2f7670, using Zig v0.17.0:

   REPRO=/repro.c
   PREFIX=/tmp/ghostty-image-clear-prefix

   zig build --prefix "$PREFIX" \
     -Demit-lib-vt \
     -Demit-xcframework=false \
     -Doptimize=ReleaseFast -j2

   cc -std=c11 -Wall -Wextra -Werror \
     -I "$PREFIX/include" "$REPRO" \
     -L "$PREFIX/lib" -Wl,-rpath,"$PREFIX/lib" \
     -lghostty-vt -o /tmp/ghostty-image-clear-repro

   /tmp/ghostty-image-clear-repro

The program exits 1 when the cleared historical image becomes visible again. It should exit 0 once corrected.

The repro.c file

Ghostty Logs

Output from the C reproduction, not a GUI log:
 
   placed: image=42 visible=1 row=0 col=0 total=1 visible=1
   in scrollback: image=42 visible=0 row=-31 col=0 total=1 visible=0
   after ED2: image=42 visible=0 row=-31 col=0 total=1 visible=0
   after first clear: image=42 visible=1 row=0 col=0 total=1 visible=1
   after second clear: total=0 visible=0
   FAIL: cleared historical image became visible again

Ghostty Version

The AI-assisted investigation reproduced the library failure against freshly built, unmodified upstream revisions:
 - `22f100c6367045bb5fc86172f837047dee2f7670`, using Zig v0.17.0.
 - `44f2a44df7e8c4a0c6df3f7d872ef3d7ead88e51`, using Zig v0.16.0.

The same reproduction also fails against Herdr’s vendored copy of the latter revision.

The installed `Ghostty 1.3.1+omarchy.3` stable GUI did not reproduce the symptom in the completed synthetic tests.

OS Version Information

Omarchy 4.0.6 (Arch Linux)

(Linux only) Display Server

Wayland

(Linux only) Desktop Environment/Window Manager

Not required for the headless C reproduction. Separate GUI controls used Wayland/Hyprland.

Minimal Ghostty Configuration

None. The C reproduction does not load a Ghostty application configuration.

Additional Relevant Configuration

The original user-visible symptom occurred with Herdr 0.9.5 stable and Pi 1.4.0.

[!IMPORTANT]
AI Disclosure
I used Pi with OpenAI models (gpt-6.1-sol) throughout this investigation, including triage, source inspection, creating and running reproductions, and drafting this report, however I used that draft to file the issue myself with edits.
I initially suspected Pi, then Herdr. The early investigation pointed at Herdr, but I asked it to distinguish Herdr's own code from its vendored libghostty-vt dependency and check whether the behavior was already fixed upstream. We then compared the vendored source with upstream Ghostty and ran standalone reproductions against unmodified upstream library revisions, where the placement-state failure also reproduced.
I supplied the original observations and screenshots and guided the investigation. Pi wrote and refined repro.c and performed the recorded automated tests. The report distinguishes my original user-visible observation from those AI-assisted test results, including the negative results in the installed stable Ghostty GUI.

I acknowledge that:

  • I have reviewed the FAQ and confirm that my issue is NOT among them.
  • I have searched the Ghostty documentation and confirm there doesn't exist a configuration option that solves my issue.
  • I have searched the Ghostty repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion.
  • I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (```) on separate lines.

Activity

  1. added
    needs-confirmationA reproduction has been reported, but the bug hasn't been confirmed or reproduced by a maintainer.
    and removed
    needs-confirmationA reproduction has been reported, but the bug hasn't been confirmed or reproduced by a maintainer.
    on Oct 24, 2026
  2. added this to the 1.4.0 milestone on Oct 24, 2026
  3. added 2 commits that reference this issue on Oct 24, 2026
    9cac2bd
    bcfe577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions