mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Electron was showing the main BrowserWindow before renderer load completed, so macOS could paint a blank window surface behind the menu bar. Persisted y=0 window state could also restore the titlebar under the menu-bar work area on external displays. Delay the initial show until the renderer entry is loaded, clamp restored macOS bounds into the display workArea, skip the macOS status-bar tray, and unhide the app before focusing restored windows. Constraint: macOS external displays expose menu-bar and status-item chrome differently from Windows and Linux. Rejected: Remove the native application menu | it would break expected macOS menu behavior without fixing the pre-load window surface. Confidence: high Scope-risk: narrow Directive: Do not reintroduce pre-load main-window show without validating macOS external-display menu-bar rendering. Tested: cd desktop && bun test electron/services/windows.test.ts electron/services/tray.test.ts electron/services/singleInstance.test.ts electron/services/menu.test.ts Tested: bun run check:desktop Tested: bun run check:native Tested: git diff --check Not-tested: Live dual-external-monitor screenshot smoke.
56 lines
1.4 KiB
TypeScript
56 lines
1.4 KiB
TypeScript
import { existsSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
import type { App, Tray } from 'electron'
|
|
|
|
export type TrayController = {
|
|
tray: Tray
|
|
dispose(): void
|
|
}
|
|
|
|
export function resolveTrayIconPath(desktopRoot: string): string {
|
|
const candidates = [
|
|
path.join(desktopRoot, 'src-tauri', 'icons', 'icon.png'),
|
|
path.join(desktopRoot, 'public', 'app-icon.png'),
|
|
path.join(desktopRoot, 'dist', 'app-icon.png'),
|
|
]
|
|
const resolved = candidates.find(candidate => existsSync(candidate))
|
|
if (!resolved) {
|
|
throw new Error(`Electron tray icon not found under ${desktopRoot}`)
|
|
}
|
|
return resolved
|
|
}
|
|
|
|
export function shouldInstallTray(platform = process.platform): boolean {
|
|
return platform !== 'darwin'
|
|
}
|
|
|
|
export async function installTray({
|
|
app,
|
|
desktopRoot,
|
|
show,
|
|
quit,
|
|
}: {
|
|
app: App
|
|
desktopRoot: string
|
|
show: () => void
|
|
quit: () => void
|
|
}): Promise<TrayController> {
|
|
const { Menu, Tray, nativeImage } = await import('electron')
|
|
const icon = nativeImage.createFromPath(resolveTrayIconPath(desktopRoot))
|
|
const tray = new Tray(icon)
|
|
tray.setToolTip(app.name || 'Claude Code Haha')
|
|
tray.setContextMenu(Menu.buildFromTemplate([
|
|
{ label: 'Show Claude Code Haha', click: show },
|
|
{ type: 'separator' },
|
|
{ label: 'Quit Claude Code Haha', click: quit },
|
|
]))
|
|
tray.on('click', show)
|
|
|
|
return {
|
|
tray,
|
|
dispose() {
|
|
tray.destroy()
|
|
},
|
|
}
|
|
}
|