Skip to content

Conversation

@ogulcancelik
Copy link
Contributor

@ogulcancelik ogulcancelik commented Jan 22, 2026

Adds support for rendering inline images inside tmux using the Kitty graphics protocol's unicode placeholder mode.

Problem

When running pi inside tmux + Ghostty/Kitty/WezTerm:

  • Direct Kitty graphics sequences get eaten by tmux (without passthrough) or cause "stuck" images (with passthrough)
  • Images orphan on screen redraws, pane switches, or scrolling

Solution

Implement the protocol's multiplexer-safe mode:

  • Detect tmux via TMUX env var
  • Check allow-passthrough setting before attempting image display
  • Wrap sequences in tmux passthrough escapes
  • Use virtual placement (U=1) with unicode placeholders (U+10EEEE)
  • Encode row positions via diacritics (per official spec)

Performance Optimizations

To minimize tmux passthrough overhead:

  • Transmit-once: Image data is transmitted only on first render; subsequent redraws reuse placeholders (image stays in terminal memory by ID)
  • Wrap-once: All Kitty chunks are batched into a single tmux passthrough frame instead of wrapping each 4KB chunk individually
  • Sync passthrough: Synchronized output markers (CSI ?2026 h/l) are passed through to the outer terminal, enabling batched rendering instead of progressive scroll

Backward Compatibility

  • Outside tmux: behavior unchanged, direct placement as before
  • Inside tmux without allow-passthrough: gracefully falls back to text description ([Image: foo.png 800x600])
  • Inside tmux with allow-passthrough all: full image rendering

User Requirement

For images to render in tmux, users need in their tmux.conf:

set -g allow-passthrough all

@ogulcancelik ogulcancelik force-pushed the feat/tmux-kitty-images branch from a7a7ad1 to 046ea9d Compare January 22, 2026 18:01
@aos
Copy link
Contributor

aos commented Jan 25, 2026

Thank you for putting this up! There's dozens of us running pi inside tmux!

@ogulcancelik ogulcancelik force-pushed the feat/tmux-kitty-images branch from 046ea9d to f5905ed Compare January 26, 2026 11:52
use unicode placeholders and passthrough escapes to render
inline images correctly inside tmux without orphaning on redraws
- transmit image data once per image, reuse placeholders on redraws
- wrap all kitty chunks in single tmux passthrough frame instead of per-chunk
- pass synchronized output markers through to outer terminal for batched rendering
- detect kitty placeholder char in containsImage() for proper line handling
@ogulcancelik ogulcancelik force-pushed the feat/tmux-kitty-images branch 2 times, most recently from 5144bab to 60596a1 Compare January 28, 2026 16:37
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