Skip synchronized-update markers inside tmux (fixes stray glyphs on scroll)#2400
Open
Agrejus wants to merge 1 commit into
Open
Skip synchronized-update markers inside tmux (fixes stray glyphs on scroll)#2400Agrejus wants to merge 1 commit into
Agrejus wants to merge 1 commit into
Conversation
Each frame is wrapped in DEC private mode 2026 (Begin/EndSynchronizedUpdate) to avoid tearing. Inside tmux those markers are passed through to the outer terminal unwrapped, and tmux's handling can drop individual cell-clear updates from a frame diff — leaving stale cells (a leftover box-drawing border glyph, etc.) on otherwise-blank lines until a full redraw (Ctrl-L). Gate the markers on not running inside tmux (TMUX unset). tmux already batches its own pane refreshes, so synchronized update buys nothing there; outside tmux the tear-free behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5 tasks
Owner
|
I use tmux all the time and haven't seen an issue. |
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.
The bug
When scrolling inside tmux, stray box-drawing glyphs (e.g. a leftover
│) get left behind on otherwise-blank lines and stay there until a full redraw (Ctrl-L).Root cause
Every frame is wrapped in DEC private mode 2026 synchronized-update markers (
Begin/EndSynchronizedUpdate) in the render loop, sent straight to stdout:Inside tmux those markers pass through to the outer terminal unwrapped, and tmux's handling can drop individual cell-clear updates from a frame diff. The composed frame buffer is correct, but the cell that should have been cleared never reaches the screen — so the old glyph persists until the whole screen is repainted.
How I narrowed it down
Ctrl-L.The fix
Gate the markers on not running inside tmux (
TMUXenv unset):tmux already batches its own pane refreshes per display cycle, so synchronized update buys nothing there. Outside tmux, the tear-free behavior is unchanged.
Risk / testing
Low — one boolean gate around two escape writes; the actual frame draw is untouched, and non-tmux behavior is identical.
No automated test: this is terminal-output (escape-sequence) behavior under tmux specifically. The headless backend used in tests composes a fresh, correct buffer every frame and so cannot reproduce a tmux passthrough drop (that's exactly why the bug was invisible to CI). Verified manually: built a release binary, ran inside tmux, scrolled a decoration-heavy buffer, and confirmed zero stray cells across many scroll passes (vs. reliably reproducible before).
Split out of #2325 (closed); this is one of the non-graphics pieces broken out for easier review. Independent of the other splits — branches from
masterand can merge in any order.