Commit 7381df3

이영수  ·  2026-06-28 09:25:44 -0400 EDT
parent 4e2d02b
fix: forward real terminal pixel size instead of hardcoding 0x0 (#174)

ipc.Resize only carried rows/cols, and getTerminalSize() dropped the
ws_xpixel/ws_ypixel fields read from TIOCGWINSZ. The daemon's three
TIOCSWINSZ call sites (spawnPty, handleInit, handleResize) then hardcoded
ws_xpixel/ws_ypixel to 0 on the inner pty, regardless of what the real
terminal reported.

This breaks Kitty graphics-protocol image sizing for anything running
inside a zmx session, since image dimensions in cells get computed from
a pixel-per-cell ratio that is always 0. nvim plugins like snacks.nvim
report `{cell}: 0 x 0 pixels` and scale images to nothing before sending
them to the terminal.

Add xpixel/ypixel to ipc.Resize, populate them from the real
ioctl(TIOCGWINSZ) result on the client side, and thread them through to
the daemon's TIOCSWINSZ calls instead of hardcoding 0.
2 files changed,  +9, -7
+3, -1
......@@ -38,12 +38,14 @@ pub const Header = packed struct {
3838 pub const Resize = packed struct {
3939 rows: u16,
4040 cols: u16,
41+ xpixel: u16 = 0,
42+ ypixel: u16 = 0,
4143 };
4244
4345 pub fn getTerminalSize(fd: i32) Resize {
4446 var ws: cross.c.struct_winsize = undefined;
4547 if (cross.c.ioctl(fd, cross.c.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) {
46- return .{ .rows = ws.ws_row, .cols = ws.ws_col };
48+ return .{ .rows = ws.ws_row, .cols = ws.ws_col, .xpixel = ws.ws_xpixel, .ypixel = ws.ws_ypixel };
4749 }
4850 return .{ .rows = 24, .cols = 160 };
4951 }
+6, -6
......@@ -702,8 +702,8 @@ const Daemon = struct {
702702 var ws: cross.c.struct_winsize = .{
703703 .ws_row = size.rows,
704704 .ws_col = size.cols,
705- .ws_xpixel = 0,
706- .ws_ypixel = 0,
705+ .ws_xpixel = size.xpixel,
706+ .ws_ypixel = size.ypixel,
707707 };
708708
709709 var master_fd: c_int = undefined;
......@@ -978,8 +978,8 @@ const Daemon = struct {
978978 var ws: cross.c.struct_winsize = .{
979979 .ws_row = resize.rows,
980980 .ws_col = resize.cols,
981- .ws_xpixel = 0,
982- .ws_ypixel = 0,
981+ .ws_xpixel = resize.xpixel,
982+ .ws_ypixel = resize.ypixel,
983983 };
984984 _ = cross.c.ioctl(pty_fd, cross.c.TIOCSWINSZ, &ws);
985985 // Disable prompt_redraw before resize. The daemon's internal terminal
......@@ -1017,8 +1017,8 @@ const Daemon = struct {
10171017 var ws: cross.c.struct_winsize = .{
10181018 .ws_row = resize.rows,
10191019 .ws_col = resize.cols,
1020- .ws_xpixel = 0,
1021- .ws_ypixel = 0,
1020+ .ws_xpixel = resize.xpixel,
1021+ .ws_ypixel = resize.ypixel,
10221022 };
10231023 _ = cross.c.ioctl(pty_fd, cross.c.TIOCSWINSZ, &ws);
10241024 // Disable prompt_redraw before resize (same rationale as handleInit).