From 8ab9dc5a11c5999836c424615012230be5b3b3a2 Mon Sep 17 00:00:00 2001 From: Stefan de Vogelaere Date: Sun, 18 Jan 2026 15:22:21 +0100 Subject: [PATCH] fix: use user's terminal font settings for dev server logs XtermLogViewer was passing DEFAULT_TERMINAL_FONT directly to xterm.js, but this value is 'default' - a sentinel string for the dropdown selector, not a valid CSS font family. Also the font size was hardcoded to 13px. Now reads the user's font preference from terminalState: - fontFamily: Uses getTerminalFontFamily() to convert to CSS font stack - defaultFontSize: Uses store value when fontSize prop not provided Also adds useEffects to update font settings dynamically when they change. This ensures dev server logs respect Settings > Terminal settings. --- .../ui/src/components/ui/xterm-log-viewer.tsx | 34 ++++++++++++++----- .../components/dev-server-logs-panel.tsx | 1 - 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/apps/ui/src/components/ui/xterm-log-viewer.tsx b/apps/ui/src/components/ui/xterm-log-viewer.tsx index 7c6cc7b4..da72eecf 100644 --- a/apps/ui/src/components/ui/xterm-log-viewer.tsx +++ b/apps/ui/src/components/ui/xterm-log-viewer.tsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useCallback, useState, forwardRef, useImperativeHandle } from 'react'; import { useAppStore } from '@/store/app-store'; -import { getTerminalTheme, DEFAULT_TERMINAL_FONT } from '@/config/terminal-themes'; +import { getTerminalTheme, getTerminalFontFamily } from '@/config/terminal-themes'; // Types for dynamically imported xterm modules type XTerminal = InstanceType; @@ -20,7 +20,7 @@ export interface XtermLogViewerRef { export interface XtermLogViewerProps { /** Initial content to display */ initialContent?: string; - /** Font size in pixels (default: 13) */ + /** Font size in pixels (uses terminal settings if not provided) */ fontSize?: number; /** Whether to auto-scroll to bottom when new content is added (default: true) */ autoScroll?: boolean; @@ -42,7 +42,7 @@ export const XtermLogViewer = forwardRef ( { initialContent, - fontSize = 13, + fontSize, autoScroll = true, className, minHeight = 300, @@ -58,9 +58,14 @@ export const XtermLogViewer = forwardRef const autoScrollRef = useRef(autoScroll); const pendingContentRef = useRef([]); - // Get theme from store + // Get theme and font settings from store const getEffectiveTheme = useAppStore((state) => state.getEffectiveTheme); const effectiveTheme = getEffectiveTheme(); + const terminalFontFamily = useAppStore((state) => state.terminalState.fontFamily); + const terminalFontSize = useAppStore((state) => state.terminalState.defaultFontSize); + + // Use prop if provided, otherwise use store value, fallback to 13 + const effectiveFontSize = fontSize ?? terminalFontSize ?? 13; // Track system dark mode for "system" theme const [systemIsDark, setSystemIsDark] = useState(() => { @@ -102,12 +107,17 @@ export const XtermLogViewer = forwardRef const terminalTheme = getTerminalTheme(resolvedTheme); + // Get font settings from store at initialization time + const terminalState = useAppStore.getState().terminalState; + const fontFamily = getTerminalFontFamily(terminalState.fontFamily); + const initFontSize = fontSize ?? terminalState.defaultFontSize ?? 13; + const terminal = new Terminal({ cursorBlink: false, cursorStyle: 'underline', cursorInactiveStyle: 'none', - fontSize, - fontFamily: DEFAULT_TERMINAL_FONT, + fontSize: initFontSize, + fontFamily, lineHeight: 1.2, theme: terminalTheme, disableStdin: true, // Read-only mode @@ -181,10 +191,18 @@ export const XtermLogViewer = forwardRef // Update font size when it changes useEffect(() => { if (xtermRef.current && isReady) { - xtermRef.current.options.fontSize = fontSize; + xtermRef.current.options.fontSize = effectiveFontSize; fitAddonRef.current?.fit(); } - }, [fontSize, isReady]); + }, [effectiveFontSize, isReady]); + + // Update font family when it changes + useEffect(() => { + if (xtermRef.current && isReady) { + xtermRef.current.options.fontFamily = getTerminalFontFamily(terminalFontFamily); + fitAddonRef.current?.fit(); + } + }, [terminalFontFamily, isReady]); // Handle resize useEffect(() => { diff --git a/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx b/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx index 8405fbca..02dcdb29 100644 --- a/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx +++ b/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx @@ -256,7 +256,6 @@ export function DevServerLogsPanel({ ref={xtermRef} className="h-full" minHeight={280} - fontSize={13} autoScroll={autoScrollEnabled} onScrollAwayFromBottom={() => setAutoScrollEnabled(false)} onScrollToBottom={() => setAutoScrollEnabled(true)}