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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user