Add Sixel image rendering and pixel cleanup for display-popup#4868
Open
gwpl wants to merge 4 commits intotmux:mastertmux/tmux:masterfrom
VariousForks:i4867-sixel-display-popupVariousForks/tmux:i4867-sixel-display-popupCopy head branch name to clipboard
Open
Add Sixel image rendering and pixel cleanup for display-popup#4868gwpl wants to merge 4 commits intotmux:mastertmux/tmux:masterfrom VariousForks:i4867-sixel-display-popupVariousForks/tmux:i4867-sixel-display-popupCopy head branch name to clipboard
gwpl wants to merge 4 commits intotmux:mastertmux/tmux:masterfrom
VariousForks:i4867-sixel-display-popupVariousForks/tmux:i4867-sixel-display-popupCopy head branch name to clipboard
Conversation
When a program running inside a tmux popup outputs Sixel images, they were silently discarded and never rendered. Two separate issues prevented this from working: 1. input_dcs_dispatch() bailed out early with `if (wp == NULL) return` before reaching the sixel parsing code. Popups don't have a window_pane, so all DCS sequences (including sixel) were dropped. Fix by moving the sixel handling before the wp == NULL guard and sourcing pixel dimensions from the client's tty when no window pane is available. 2. popup_draw_cb() only drew text lines via tty_draw_line() and ignored images stored in the popup screen's image list. Fix by iterating pd->s.images and calling tty_write_one(tty_cmd_sixelimage) with a tty_ctx that delegates offset calculation to the existing popup_set_client_cb callback. Expose tty_write_one() (previously static in tty.c) via tmux.h so popup.c can use the same single-client write path as tty_draw_images(). Force CLIENT_REDRAWWINDOW on popup close when images were present, to repaint the underlying pane. Note: stale sixel pixels from the popup may still persist on screen in some terminal emulators because text redraws do not erase pixel-level content; this is a known limitation that requires terminal-level clearing to fully resolve. Add a regression test (regress/display-popup-sixel.sh) that verifies Sixel image output in both bordered and borderless (-B) popup modes. Co-Authored-By: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a popup containing sixel images closes, pixel artifacts persist because terminal emulators render sixel in a separate graphics layer that standard text escape sequences don't clear. Implement four cleanup strategies in popup_free_cb(), selectable via compile-time bitmask SIXEL_CLEAR_STRATEGIES (default: all enabled): 0x1 SCREEN - RMCUP/SMCUP alternate screen toggle + ED2/DECSED 0x2 SPACES - Overwrite entire popup area with space characters 0x4 DECFRA - VT420 DECFRA rectangle fill per image 0x8 BLANK_SIXEL - Blank sixel with P2=2 background erase per image Testing on Konsole shows SCREEN (RMCUP/SMCUP toggle) accounts for ~90% of the cleanup effect -- toggling the alternate screen buffer discards the graphics layer. Other strategies provide additional coverage for terminals where the alternate buffer toggle alone is insufficient. Strategy can be overridden at compile time for A/B testing: make CPPFLAGS="-DSIXEL_CLEAR_STRATEGIES=0x1" popup.o Test toolkit and methodology: [tmux Sixel Popup Cleanup Testing Toolkit](https://gist.github.com/gwpl/722cd9bab3b92b2cf4ae1bbcb16544d1) Related to tmux#4867 at tmux#4867 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
display-popupoverlays (both bordered and borderless)Fixes #4867
Changes
Commit 1: Sixel rendering in popups
input_dcs_dispatch()beforewp == NULLguard, sourcing pixel dimensions from client tty when no window pane is availablepopup_draw_cb()viatty_write_one(tty_cmd_sixelimage, ...)tty_write_one()(previously static) so popup.c can call itregress/display-popup-sixel.shCommit 2: Multi-strategy pixel cleanup
Four cleanup strategies in
popup_free_cb(), selectable via compile-time bitmask:Testing shows SCREEN (RMCUP/SMCUP toggle) accounts for ~90% of the cleanup
effect on Konsole -- toggling the alternate screen buffer discards the
graphics layer.
Testing
Regression results on Konsole (WhiteOnBlack, Hack 10pt, threshold=300):
Screenshots
(Screenshots to be attached: sixel in popup, cleanup result on dark/light backgrounds)
Test plan
regress/display-popup-sixel.sh)Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com