mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-06 19:58:43 +02:00
fix: sync title bar overlay colors with app theme
The Windows title bar overlay (minimize/maximize/close buttons) was hardcoded to dark colors and did not update when switching themes. - Add titleBarTheme helper that maps AppearanceTheme to overlay and background colors, using nativeTheme for the system preference - Call applyTitleBarTheme from the setTheme IPC handler so the overlay updates immediately on theme change - Apply persisted theme on startup so the overlay matches from launch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { app, BrowserWindow } from 'electron';
|
|||||||
import { registerIpcHandlers } from '@main/ipc/registerIpcHandlers';
|
import { registerIpcHandlers } from '@main/ipc/registerIpcHandlers';
|
||||||
import { EryxAppService } from '@main/EryxAppService';
|
import { EryxAppService } from '@main/EryxAppService';
|
||||||
import { createMainWindow } from '@main/windows/createMainWindow';
|
import { createMainWindow } from '@main/windows/createMainWindow';
|
||||||
|
import { applyTitleBarTheme } from '@main/windows/titleBarTheme';
|
||||||
|
|
||||||
let mainWindow: BrowserWindow | undefined;
|
let mainWindow: BrowserWindow | undefined;
|
||||||
let appService: EryxAppService | undefined;
|
let appService: EryxAppService | undefined;
|
||||||
@@ -13,6 +14,10 @@ async function bootstrap(): Promise<void> {
|
|||||||
mainWindow = createMainWindow();
|
mainWindow = createMainWindow();
|
||||||
registerIpcHandlers(mainWindow, appService);
|
registerIpcHandlers(mainWindow, appService);
|
||||||
|
|
||||||
|
// Apply persisted theme to the title bar overlay
|
||||||
|
const workspace = await appService.loadWorkspace();
|
||||||
|
applyTitleBarTheme(mainWindow, workspace.settings.theme);
|
||||||
|
|
||||||
if (!app.isPackaged) {
|
if (!app.isPackaged) {
|
||||||
mainWindow.webContents.openDevTools({ mode: 'detach' });
|
mainWindow.webContents.openDevTools({ mode: 'detach' });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import type { QuerySessionsInput } from '@shared/domain/sessionLibrary';
|
|||||||
import type { AppearanceTheme } from '@shared/domain/tooling';
|
import type { AppearanceTheme } from '@shared/domain/tooling';
|
||||||
|
|
||||||
import { EryxAppService } from '@main/EryxAppService';
|
import { EryxAppService } from '@main/EryxAppService';
|
||||||
|
import { applyTitleBarTheme } from '@main/windows/titleBarTheme';
|
||||||
|
|
||||||
export function registerIpcHandlers(window: BrowserWindow, service: EryxAppService): void {
|
export function registerIpcHandlers(window: BrowserWindow, service: EryxAppService): void {
|
||||||
ipcMain.handle(ipcChannels.describeSidecarCapabilities, () => service.describeSidecarCapabilities());
|
ipcMain.handle(ipcChannels.describeSidecarCapabilities, () => service.describeSidecarCapabilities());
|
||||||
@@ -34,9 +35,11 @@ export function registerIpcHandlers(window: BrowserWindow, service: EryxAppServi
|
|||||||
ipcMain.handle(ipcChannels.setPatternFavorite, (_event, input: SetPatternFavoriteInput) =>
|
ipcMain.handle(ipcChannels.setPatternFavorite, (_event, input: SetPatternFavoriteInput) =>
|
||||||
service.setPatternFavorite(input.patternId, input.isFavorite),
|
service.setPatternFavorite(input.patternId, input.isFavorite),
|
||||||
);
|
);
|
||||||
ipcMain.handle(ipcChannels.setTheme, (_event, theme: AppearanceTheme) =>
|
ipcMain.handle(ipcChannels.setTheme, async (_event, theme: AppearanceTheme) => {
|
||||||
service.setTheme(theme),
|
const result = await service.setTheme(theme);
|
||||||
);
|
applyTitleBarTheme(window, theme);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
ipcMain.handle(ipcChannels.saveMcpServer, (_event, input: SaveMcpServerInput) =>
|
ipcMain.handle(ipcChannels.saveMcpServer, (_event, input: SaveMcpServerInput) =>
|
||||||
service.saveMcpServer(input.server),
|
service.saveMcpServer(input.server),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { nativeTheme, type BrowserWindow } from 'electron';
|
||||||
|
|
||||||
|
import type { AppearanceTheme } from '@shared/domain/tooling';
|
||||||
|
|
||||||
|
interface TitleBarColors {
|
||||||
|
backgroundColor: string;
|
||||||
|
overlay: { color: string; symbolColor: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
const darkColors: TitleBarColors = {
|
||||||
|
backgroundColor: '#09090b',
|
||||||
|
overlay: { color: '#09090b', symbolColor: '#a1a1aa' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const lightColors: TitleBarColors = {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
overlay: { color: '#ffffff', symbolColor: '#52525b' },
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveEffectiveTheme(theme: AppearanceTheme): 'dark' | 'light' {
|
||||||
|
if (theme === 'light') return 'light';
|
||||||
|
if (theme === 'dark') return 'dark';
|
||||||
|
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
function colorsForTheme(theme: AppearanceTheme): TitleBarColors {
|
||||||
|
return resolveEffectiveTheme(theme) === 'light' ? lightColors : darkColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyTitleBarTheme(window: BrowserWindow, theme: AppearanceTheme): void {
|
||||||
|
const { backgroundColor, overlay } = colorsForTheme(theme);
|
||||||
|
window.setBackgroundColor(backgroundColor);
|
||||||
|
|
||||||
|
// setTitleBarOverlay is only available on Windows (and some Linux WMs).
|
||||||
|
if (typeof window.setTitleBarOverlay === 'function') {
|
||||||
|
window.setTitleBarOverlay(overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user