Skip to content

pty: forward client pixel size (ws_xpixel/ws_ypixel) from window size messages - #1560

Open
ViktorBarzin wants to merge 1 commit into
tsl0922:mainfrom
ViktorBarzin:pty-pixel-size
Open

pty: forward client pixel size (ws_xpixel/ws_ypixel) from window size messages#1560
ViktorBarzin wants to merge 1 commit into
tsl0922:mainfrom
ViktorBarzin:pty-pixel-size

Conversation

@ViktorBarzin

Copy link
Copy Markdown

Problem

Programs that query the terminal's pixel dimensions via TIOCGWINSZ always see 0x0 under ttyd: the winsize passed to forkpty() / TIOCSWINSZ hard-codes ws_xpixel/ws_ypixel to 0.

The most visible casualty is sixel graphics under tmux. tmux (≥ 3.4, built with sixel) stores images emitted by pane programs, but refuses to scale and re-emit them to a client whose tty reports a zero pixel size — tty.c: tty_cmd_sixelimage falls back to the SIXEL IMAGE (WxH) text placeholder. So image tools (viu, img2sixel, matplotlib sixel backends) show placeholders inside tmux under ttyd, even when the frontend (e.g. xterm.js with @xterm/addon-image) renders sixel natively.

Change

Accept optional xpixel / ypixel fields in the initial JSON handshake and in RESIZE_TERMINAL messages, and carry them into the pty's winsize on spawn and resize.

  • Backward compatible: clients that don't send the fields get exactly the previous behavior (0x0).
  • Windows path untouched (ResizePseudoConsole has no pixel concept).

Testing

Verified end-to-end against tmux 3.4 (sixel-enabled) with an xterm.js 5.5 + @xterm/addon-image frontend sending real cell metrics: with the fields present, tmux re-emits sixel and real images render through tmux in the browser (first paint, after resizes, and across reconnects); without them, behavior is byte-identical to current master. Happy to extend the bundled html client to send these fields in a follow-up if you're open to it.

🤖 Generated with Claude Code

… messages

Programs that query the terminal's pixel dimensions via TIOCGWINSZ
currently always see 0x0 under ttyd, because the winsize passed to
forkpty()/TIOCSWINSZ hard-codes ws_xpixel/ws_ypixel to 0.

The most visible casualty is sixel graphics under tmux: tmux (>= 3.4,
built with sixel) refuses to scale and re-emit sixel images to a client
whose tty reports a zero pixel size (tty.c: tty_cmd_sixelimage falls
back to the "SIXEL IMAGE (WxH)" text placeholder), so image tools like
viu or img2sixel show placeholders inside tmux even when the browser
terminal renders sixel natively.

Accept optional "xpixel"/"ypixel" fields in the initial JSON handshake
and in RESIZE_TERMINAL messages, and carry them into the pty's winsize
on spawn and resize. Clients that don't send the fields get exactly the
previous behavior (0x0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant