Update CSS and font handling for ghostty-web

- Remove xterm.js-specific CSS selectors (.xterm, .xterm-viewport, etc.)
- Add canvas-specific styles for ghostty-web renderer
- Add waitForFonts() to ensure fonts are loaded before fitting
- Keep same font stack (ui-monospace, SFMono-Regular, Fira Code, etc.)
- Font is passed to ghostty-web via fontFamily option
This commit is contained in:
GitHub Copilot
2026-01-28 00:58:50 +00:00
parent 5dbb91ca32
commit d406cc1fcb
3 changed files with 28 additions and 42 deletions
File diff suppressed because one or more lines are too long
+18 -2
View File
@@ -113,8 +113,12 @@ class WebTerminal {
/** Initialize event handlers and connect */ /** Initialize event handlers and connect */
private initialize(): void { private initialize(): void {
// Fit to container // Wait for fonts to load before fitting to ensure correct measurements
this.fitAddon.fit(); this.waitForFonts().then(() => {
this.fitAddon.fit();
});
// Start observing resize immediately
this.fitAddon.observeResize(); this.fitAddon.observeResize();
// Handle window resize (some browsers don't trigger ResizeObserver on window resize) // Handle window resize (some browsers don't trigger ResizeObserver on window resize)
@@ -139,6 +143,18 @@ class WebTerminal {
this.connect(); this.connect();
} }
/** Wait for fonts to be loaded */
private async waitForFonts(): Promise<void> {
if (!("fonts" in document)) {
return;
}
try {
await document.fonts.ready;
} catch {
// Ignore font loading errors
}
}
/** Validate terminal dimensions */ /** Validate terminal dimensions */
private isValidSize(cols: number, rows: number): boolean { private isValidSize(cols: number, rows: number): boolean {
return cols >= 2 && cols <= 500 && rows >= 1 && rows <= 200; return cols >= 2 && cols <= 500 && rows >= 1 && rows <= 200;
+9 -39
View File
@@ -22,13 +22,7 @@ html, body {
font-family: var(--textual-webterm-mono); font-family: var(--textual-webterm-mono);
} }
/* /* Terminal container - works with ghostty-web canvas renderer */
textual_serve's bundled textual.js hard-codes xterm's Terminal fontFamily:
"'Roboto Mono', Monaco, 'Courier New', monospace".
If Roboto Mono isn't available, it falls back to Courier and looks wrong.
We override that here with higher specificity + !important.
*/
.textual-terminal { .textual-terminal {
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -41,51 +35,27 @@ html, body {
contain: strict; /* Performance optimization */ contain: strict; /* Performance optimization */
} }
.textual-terminal .xterm, /* ghostty-web renders to a canvas element */
.textual-terminal .xterm .xterm-rows, .textual-terminal canvas {
.textual-terminal .xterm .xterm-helper-textarea,
.textual-terminal .xterm .xterm-viewport,
.textual-terminal .xterm .xterm-screen {
font-family: var(--textual-webterm-mono) !important;
}
/* Critical layout fixes for xterm.js */
.textual-terminal .xterm {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
display: flex; display: block;
flex-direction: column;
position: relative;
overflow: hidden;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.textual-terminal .xterm .xterm-viewport { /* Hidden textarea for keyboard input */
flex: 1 1 auto; .textual-terminal textarea {
min-width: 0;
min-height: 0;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
}
.textual-terminal .xterm .xterm-screen {
position: absolute; position: absolute;
top: 0; opacity: 0;
left: 0; pointer-events: none;
right: 0;
bottom: 0;
overflow: hidden;
} }
/* High DPI display handling */ /* High DPI display handling */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.textual-terminal { .textual-terminal {
/* Consider adjusting font sizes for high DPI */ /* ghostty-web handles DPI scaling via devicePixelRatio */
font-size: 14px;
} }
} }