refactor(desktop): move title bar overlay logic to window-manager and add setTitleBarTheme IPC

This commit is contained in:
Mohamed Boudra
2026-03-29 09:26:18 +07:00
parent f287c7f972
commit 921ddf47a8
4 changed files with 75 additions and 22 deletions
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { readBadgeCount } from "./window-manager";
import { getTitleBarOverlayOptions, readBadgeCount, readWindowTheme } from "./window-manager";
describe("window-manager", () => {
describe("readBadgeCount", () => {
@@ -20,4 +20,35 @@ describe("window-manager", () => {
expect(readBadgeCount({ count: 2 })).toBe(0);
});
});
describe("readWindowTheme", () => {
it("accepts supported title bar themes", () => {
expect(readWindowTheme("light")).toBe("light");
expect(readWindowTheme("dark")).toBe("dark");
});
it("rejects invalid title bar themes", () => {
expect(readWindowTheme(undefined)).toBeNull();
expect(readWindowTheme("auto")).toBeNull();
expect(readWindowTheme("system")).toBeNull();
});
});
describe("getTitleBarOverlayOptions", () => {
it("returns light title bar overlay colors", () => {
expect(getTitleBarOverlayOptions("light")).toEqual({
color: "#ffffff",
symbolColor: "#09090b",
height: 48,
});
});
it("returns dark title bar overlay colors", () => {
expect(getTitleBarOverlayOptions("dark")).toEqual({
color: "#18181c",
symbolColor: "#e4e4e7",
height: 48,
});
});
});
});
+37 -1
View File
@@ -1,4 +1,4 @@
import { app, BrowserWindow, ipcMain } from "electron";
import { app, BrowserWindow, ipcMain, nativeTheme } from "electron";
import {
createWindowMoveState,
readWindowMovePayload,
@@ -14,6 +14,28 @@ export function readBadgeCount(input: unknown): number {
return input;
}
export type WindowTheme = "light" | "dark";
export function readWindowTheme(input: unknown): WindowTheme | null {
if (input === "light" || input === "dark") {
return input;
}
return null;
}
export function resolveSystemWindowTheme(): WindowTheme {
return nativeTheme.shouldUseDarkColors ? "dark" : "light";
}
export function getTitleBarOverlayOptions(theme: WindowTheme): Electron.TitleBarOverlayOptions {
if (theme === "dark") {
return { color: "#18181c", symbolColor: "#e4e4e7", height: 48 };
}
return { color: "#ffffff", symbolColor: "#09090b", height: 48 };
}
export function registerWindowManager(): void {
// ---------------------------------------------------------------------------
// Manual window dragging (replaces flaky CSS -webkit-app-region: drag).
@@ -101,6 +123,20 @@ export function registerWindowManager(): void {
}
}
});
ipcMain.handle("paseo:window:setTitleBarTheme", (event, theme?: unknown) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (!win || process.platform === "darwin") {
return;
}
const nextTheme = readWindowTheme(theme);
if (!nextTheme) {
return;
}
win.setTitleBarOverlay(getTitleBarOverlayOptions(nextTheme));
});
}
export function setupWindowResizeEvents(win: BrowserWindow): void {