booterm: fitFull() bypasses FitAddon scrollbar subtraction; push initial PTY size

FitAddon's proposeDimensions() always subtracts a phantom scrollbar width even
when CSS hides the scrollbar — losing one column of usable width. fitFull()
divides host clientWidth/clientHeight by the renderer's reported cell size
directly. Also POSTs the resized cols/rows back to /api/term/.../resize on
initial mount and after fonts.ready so bash/opencode get the correct PTY
size before the user types.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 17:32:42 +00:00
parent fccab20920
commit 3fceea064a

View File

@@ -184,8 +184,35 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props
term.loadAddon(search);
term.loadAddon(new WebLinksAddon());
term.open(container);
// v1.10.4 gap fix: bypass FitAddon's proposeDimensions(), which subtracts
// a phantom scrollbar width even when CSS hides the scrollbar. Compute
// cols/rows directly from the host's clientWidth/clientHeight divided by
// the renderer's reported cell size. Falls back to FitAddon if cell
// metrics aren't ready yet (e.g. on very first mount).
const fitFull = (): void => {
const host = containerRef.current;
const t = termRef.current;
if (!host || !t) return;
if (!t.element || !(t.element as HTMLElement).offsetParent) return;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const core: any = (t as any)._core;
const cellW: number | undefined = core?._renderService?.dimensions?.css?.cell?.width;
const cellH: number | undefined = core?._renderService?.dimensions?.css?.cell?.height;
if (!cellW || !cellH || cellW <= 0 || cellH <= 0) {
try { fit.fit(); } catch { /* not ready */ }
return;
}
const cols = Math.max(2, Math.floor(host.clientWidth / cellW));
const rows = Math.max(1, Math.floor(host.clientHeight / cellH));
if (cols !== t.cols || rows !== t.rows) {
try { t.resize(cols, rows); } catch { /* ignore */ }
}
};
try {
fit.fit();
fitFull();
// v1.10.4: also push initial size to PTY so opencode/bash get correct cols/rows
api.terminals.resize(sessionId, paneId, term.cols, term.rows).catch(() => {});
} catch {
/* container not yet sized */
}
@@ -199,7 +226,8 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props
.then(() => {
if (disposed) return;
try {
fit.fit();
fitFull();
api.terminals.resize(sessionId, paneId, term.cols, term.rows).catch(() => {});
} catch {
/* ignore */
}
@@ -363,7 +391,7 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props
const fireResize = (): void => {
try {
fit.fit();
fitFull();
} catch {
return;
}