Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/renderer/state/terminal-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,16 @@ export const useTerminalStore = create<TerminalStore>((set, get) => ({
updates.terminalOpacity = (config as any).terminalOpacity;
document.documentElement.style.setProperty('--terminal-opacity', String((config as any).terminalOpacity));
}
// Seed the live zoom size from the configured baseline. Without this the
// store keeps its hardcoded initial 14 and TerminalPanel's fontSize effect
// writes that back over the xterm instance on mount, so a configured size
// only ever took effect via updateConfig (Settings) or zoomReset (Ctrl+0)
// - never on startup. It also left the status-bar zoom badge showing
// 14 / configured instead of 100%.
const baseFontSize = config?.terminal?.fontSize;
if (typeof baseFontSize === 'number' && baseFontSize > 0) {
updates.fontSize = baseFontSize;
}
// Seed AI session load limits from config so subsequent
// loadCopilotSessions / loadClaudeCodeSessions calls in App.init
// honor the user's preference (0 = no scan).
Expand Down
82 changes: 82 additions & 0 deletions tests/unit/renderer/load-config-font-size.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// loadConfig must seed the store's live zoom size from terminal.fontSize.
//
// Without it the store kept its hardcoded initial 14 while the status-bar
// badge divided by the configured baseline, so a configured 17.5 rendered at
// 14px and showed 80%. terminal-store reads window at module load, so the
// stubs go in before a dynamic import (test env is 'node').
import { describe, test, expect, beforeAll, beforeEach } from 'vitest';

const getConfigResult: { value: unknown } = { value: {} };

(globalThis as any).window = (globalThis as any).window ?? {};
(globalThis as any).window.terminalAPI = {
getConfig: async () => getConfigResult.value,
};
(globalThis as any).document = (globalThis as any).document ?? {
hasFocus: () => true,
documentElement: { style: { setProperty: () => {} } },
};

let useTerminalStore: typeof import('../../../src/renderer/state/terminal-store').useTerminalStore;

beforeAll(async () => {
({ useTerminalStore } = await import('../../../src/renderer/state/terminal-store'));
});

beforeEach(() => {
// The hardcoded initial state, so each case starts from the pre-load value.
useTerminalStore.setState({ fontSize: 14 });
});

describe('loadConfig - terminal font size', () => {
test('seeds fontSize from the configured baseline', async () => {
getConfigResult.value = { terminal: { fontSize: 17.5 } };

await useTerminalStore.getState().loadConfig();

expect(useTerminalStore.getState().fontSize).toBe(17.5);
});

test('a configured baseline equal to the default is still applied', async () => {
getConfigResult.value = { terminal: { fontSize: 14 } };

await useTerminalStore.getState().loadConfig();

expect(useTerminalStore.getState().fontSize).toBe(14);
});

test('keeps the default when config carries no terminal section', async () => {
getConfigResult.value = {};

await useTerminalStore.getState().loadConfig();

expect(useTerminalStore.getState().fontSize).toBe(14);
});

test('ignores a non-numeric font size', async () => {
getConfigResult.value = { terminal: { fontSize: '18' } };

await useTerminalStore.getState().loadConfig();

expect(useTerminalStore.getState().fontSize).toBe(14);
});

test('ignores a zero or negative font size', async () => {
getConfigResult.value = { terminal: { fontSize: 0 } };
await useTerminalStore.getState().loadConfig();
expect(useTerminalStore.getState().fontSize).toBe(14);

getConfigResult.value = { terminal: { fontSize: -4 } };
await useTerminalStore.getState().loadConfig();
expect(useTerminalStore.getState().fontSize).toBe(14);
});

test('config itself is still stored alongside the seeded size', async () => {
getConfigResult.value = { terminal: { fontSize: 20 }, defaultShellId: 'zsh' };

await useTerminalStore.getState().loadConfig();

expect(useTerminalStore.getState().fontSize).toBe(20);
expect(useTerminalStore.getState().config?.terminal?.fontSize).toBe(20);
});
});