From aa22180b8a2e4cd48b5bbf65e759fb5ae238bc74 Mon Sep 17 00:00:00 2001 From: Douglas Date: Fri, 20 Mar 2026 15:10:56 +0000 Subject: [PATCH] refactor electron style setting for mac only Made-with: Cursor --- .gitignore | 1 + electron/main/index.ts | 30 ++++++++++++++------------- electron/preload/index.ts | 1 + src/pages/Setting/General.tsx | 38 ++++++++++++++++++++--------------- src/types/electron.d.ts | 2 ++ 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 371f8962..dee34d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ yarn.lock .env.development .cursor +.claude # Public directory (large media files) public/ diff --git a/electron/main/index.ts b/electron/main/index.ts index 8e495468..70202e7e 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -2718,6 +2718,8 @@ let installationLock: Promise = Promise.resolve({ // ==================== window create ==================== async function createWindow() { const isMac = process.platform === 'darwin'; + const isAppleSilicon = isMac && process.arch === 'arm64'; + const supportsTransparency = isAppleSilicon; // Ensure .eigent directories exist before anything else ensureEigentDirectories(); @@ -2749,23 +2751,23 @@ async function createWindow() { height: 800, minWidth: 1050, minHeight: 650, - // Use native frame on Windows for better native integration - frame: isWindows ? true : false, show: false, // Don't show until content is ready to avoid white screen - // Only use transparency on macOS and Linux (not supported well on Windows) - transparent: !isWindows, - // Solid background on Windows (respect dark/light mode), fully transparent on macOS for native vibrancy - backgroundColor: isWindows - ? nativeTheme.shouldUseDarkColors + // Only use transparency on Apple Silicon Macs (older Macs/Windows/Linux have rendering issues) + transparent: supportsTransparency, + // Solid background for non-transparent mode, fully transparent on Apple Silicon for native vibrancy + backgroundColor: supportsTransparency + ? '#00000000' + : nativeTheme.shouldUseDarkColors ? '#1e1e1e' - : '#ffffff' - : '#00000000', + : '#ffffff', // macOS-specific title bar styling titleBarStyle: isMac ? 'hidden' : undefined, trafficLightPosition: isMac ? { x: 10, y: 10 } : undefined, icon: path.join(VITE_PUBLIC, 'favicon.ico'), - // Rounded corners on macOS and Linux (as original) - roundedCorners: !isWindows, + // Rounded corners on Apple Silicon Macs (transparent mode) + roundedCorners: supportsTransparency, + // Non-transparent platforms need a frame except macOS (which uses hidden titleBarStyle) + frame: isMac ? false : isWindows ? true : false, // Windows-specific options ...(isWindows && { autoHideMenuBar: true, // Hide menu bar on Windows for cleaner look @@ -2783,8 +2785,8 @@ async function createWindow() { }, }); - // Apply native macOS effects - if (process.platform === 'darwin') { + // Apply native macOS visual effects only on Apple Silicon (transparent mode support) + if (supportsTransparency) { win.once('ready-to-show', () => { if (win && !win.isDestroyed()) { try { @@ -2797,7 +2799,7 @@ async function createWindow() { // Make titlebar transparent setTransparentTitlebar(win); - log.info('[MacOS] Applied native visual effects'); + log.info('[MacOS] Applied native visual effects (Apple Silicon)'); } catch (error) { log.error('[MacOS] Failed to apply native visual effects:', error); } diff --git a/electron/preload/index.ts b/electron/preload/index.ts index 910a670d..a289a1dd 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -53,6 +53,7 @@ contextBridge.exposeInMainWorld('electronAPI', { onExecuteAction: (callback: (action: string) => void) => ipcRenderer.on('execute-action', (event, action) => callback(action)), getPlatform: () => process.platform, + getArch: () => process.arch, getHomeDir: () => ipcRenderer.invoke('get-home-dir'), createWebView: (id: string, url: string) => ipcRenderer.invoke('create-webview', id, url), diff --git a/src/pages/Setting/General.tsx b/src/pages/Setting/General.tsx index 8ab1c96b..336e8b7a 100644 --- a/src/pages/Setting/General.tsx +++ b/src/pages/Setting/General.tsx @@ -82,7 +82,9 @@ export default function SettingGeneral() { useEffect(() => { const platform = window.electronAPI.getPlatform(); - console.log(platform); + const arch = window.electronAPI.getArch(); + const isAppleSilicon = platform === 'darwin' && arch === 'arm64'; + const baseThemes = [ { img: dark, @@ -96,7 +98,7 @@ export default function SettingGeneral() { }, ]; - if (platform === 'darwin') { + if (isAppleSilicon) { setThemeList([ ...baseThemes, { @@ -107,6 +109,10 @@ export default function SettingGeneral() { ]); } else { setThemeList(baseThemes); + // If user previously had transparent mode on an unsupported device, fall back to dark + if (appearance === 'transparent') { + setAppearance('dark'); + } } }, []); @@ -236,8 +242,8 @@ export default function SettingGeneral() { return (
{/* Header Section */} -
-
+
+
{t('setting.general')} @@ -246,10 +252,10 @@ export default function SettingGeneral() {
{/* Content Section */} -
+
{/* Profile Section */} -
-
+
+
{t('setting.profile')}
@@ -263,7 +269,7 @@ export default function SettingGeneral() { />
-
+
{/* Language Section */} -
+
{t('setting.language')} @@ -304,7 +310,7 @@ export default function SettingGeneral() { - + {t('setting.system-default')} @@ -320,20 +326,20 @@ export default function SettingGeneral() {
{/* Appearance Section */} -
+
{t('setting.appearance')}
-
+
{themeList.map((item: any) => (
setAppearance(item.value)} > {/* Network Proxy Section */} -
-
+
+
{t('setting.network-proxy')}
diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index 778f4a51..28854a84 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -14,6 +14,7 @@ interface IpcRenderer { getPlatform: () => string; + getArch: () => string; minimizeWindow: () => void; toggleMaximizeWindow: () => void; closeWindow: () => void; @@ -50,6 +51,7 @@ interface ElectronAPI { triggerMenuAction: (action: string) => void; onExecuteAction: (callback: (action: string) => void) => void; getPlatform: () => string; + getArch: () => string; getHomeDir: () => Promise; createWebView: (id: string, url: string) => Promise; hideWebView: (id: string) => Promise;