Measure the terminal cell instead of guessing it, and stop telling the PTY zero

TERMINAL_CELL_WIDTH was 8.4 — a number nobody had measured. Asking the text
system for the advance of `0` in the face actually being painted gives ~7.3, so
the guess was 13% wide and the terminal was losing eighteen columns: the same
window that reported 122 columns now reports 140. Layout and paint now read the
same measurement, so they cannot drift apart again.

The plan claimed ws_xpixel disagreed with the painted width by 0.4 px per
column. It did not: the app only ever called TerminalSize::new, which passes no
pixel dimensions, so ws_xpixel and ws_ypixel were both *zero*. Every program
doing pixel arithmetic — sixel, the kitty graphics protocol, anything sizing an
image to the viewport — was being told the window has no size at all. Both the
spawn and the resize paths now report the real extent.

TerminalDimensions gains cell_width/cell_height accessors: it was already
carrying the values and nothing could read them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Metal Agent
2026-09-01 00:13:30 -07:00
co-authored by Claude Opus 5
parent e5d7a3efd5
commit f9f4f85402
2 changed files with 143 additions and 23 deletions
+17
View File
@@ -66,6 +66,23 @@ impl TerminalDimensions {
self.rows
}
/// The measured width of one cell, in pixels.
///
/// Carried so a caller can report the viewport's pixel extent to a PTY.
/// `ws_xpixel` is the whole window, not one cell, so it is this times the
/// column count — and a terminal that reports zero there tells every program
/// doing pixel arithmetic that the window has no size.
#[must_use]
pub const fn cell_width(self) -> u16 {
self.cell_width
}
/// The height of one row, in pixels.
#[must_use]
pub const fn cell_height(self) -> u16 {
self.cell_height
}
#[must_use]
pub const fn columns(self) -> u16 {
self.columns