Skip to content
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ yarn.lock
.env.development

.cursor
.claude

# Public directory (large media files)
public/
Expand Down
30 changes: 16 additions & 14 deletions electron/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2718,6 +2718,8 @@ let installationLock: Promise<PromiseReturnType> = 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();
Expand Down Expand Up @@ -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
Comment on lines +2755 to +2760
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes transparent false on Linux as well (previously it was enabled on non-Windows). The PR title/description focuses on macOS/Windows, so please confirm Linux is intentionally included and update the PR description accordingly (or gate this to macOS only if Linux should keep transparency).

Copilot uses AI. Check for mistakes.
? '#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)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says “Non-transparent platforms need a frame except macOS”, but the code sets frame to false on Linux (isMac false, isWindows false). If frameless Linux is intentional, please adjust the comment to match; otherwise set frame: true for Linux/non-mac platforms.

Suggested change
// Non-transparent platforms need a frame except macOS (which uses hidden titleBarStyle)
// Use frameless window on macOS and Linux; Windows uses a standard framed window

Copilot uses AI. Check for mistakes.
frame: isMac ? false : isWindows ? true : false,
// Windows-specific options
...(isWindows && {
autoHideMenuBar: true, // Hide menu bar on Windows for cleaner look
Expand All @@ -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 {
Expand All @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions electron/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
38 changes: 22 additions & 16 deletions src/pages/Setting/General.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Comment on lines 83 to +87
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This effect reads appearance and calls setAppearance, but the dependency array is empty. With the repo’s enabled react-hooks/exhaustive-deps rule, this will trigger a lint warning and can also lock in a stale appearance value if the store hydrates after mount. Consider either (a) including appearance and setAppearance in the deps (and structuring the logic to avoid unnecessary re-runs), or (b) reading the current appearance from the store inside the effect and documenting with an eslint-disable comment.

Copilot uses AI. Check for mistakes.
const baseThemes = [
{
img: dark,
Expand All @@ -96,7 +98,7 @@ export default function SettingGeneral() {
},
];

if (platform === 'darwin') {
if (isAppleSilicon) {
setThemeList([
...baseThemes,
{
Expand All @@ -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');
}
}
}, []);

Expand Down Expand Up @@ -236,8 +242,8 @@ export default function SettingGeneral() {
return (
<div className="m-auto h-auto w-full flex-1">
{/* Header Section */}
<div className="mx-auto flex w-full max-w-[900px] items-center justify-between px-6 pb-6 pt-8">
<div className="flex w-full flex-row items-center justify-between gap-4">
<div className="px-6 pb-6 pt-8 mx-auto flex w-full max-w-[900px] items-center justify-between">
<div className="gap-4 flex w-full flex-row items-center justify-between">
<div className="flex flex-col">
<div className="text-heading-sm font-bold text-text-heading">
{t('setting.general')}
Expand All @@ -246,10 +252,10 @@ export default function SettingGeneral() {
</div>
</div>
{/* Content Section */}
<div className="mb-xl flex flex-col gap-6">
<div className="mb-xl gap-6 flex flex-col">
{/* Profile Section */}
<div className="item-center flex flex-row justify-between rounded-2xl bg-surface-secondary px-6 py-4">
<div className="flex flex-col gap-2">
<div className="item-center rounded-2xl bg-surface-secondary px-6 py-4 flex flex-row justify-between">
<div className="gap-2 flex flex-col">
<div className="text-body-base font-bold text-text-heading">
{t('setting.profile')}
</div>
Expand All @@ -263,7 +269,7 @@ export default function SettingGeneral() {
/>
</div>
</div>
<div className="flex items-center gap-sm">
<div className="gap-sm flex items-center">
<Button
onClick={() => {
window.location.href = `https://www.eigent.ai/dashboard?email=${authStore.email}`;
Expand Down Expand Up @@ -294,7 +300,7 @@ export default function SettingGeneral() {
</div>

{/* Language Section */}
<div className="item-center flex flex-row justify-between rounded-2xl bg-surface-secondary px-6 py-4">
<div className="item-center rounded-2xl bg-surface-secondary px-6 py-4 flex flex-row justify-between">
<div className="flex flex-1 items-center">
<div className="text-body-base font-bold text-text-heading">
{t('setting.language')}
Expand All @@ -304,7 +310,7 @@ export default function SettingGeneral() {
<SelectTrigger className="w-48">
<SelectValue placeholder={t('setting.select-language')} />
</SelectTrigger>
<SelectContent className="border bg-input-bg-default">
<SelectContent className="bg-input-bg-default border">
<SelectGroup>
<SelectItem value="system">
{t('setting.system-default')}
Expand All @@ -320,20 +326,20 @@ export default function SettingGeneral() {
</div>

{/* Appearance Section */}
<div className="item-center flex flex-col justify-between gap-4 rounded-2xl bg-surface-secondary px-6 py-4">
<div className="item-center gap-4 rounded-2xl bg-surface-secondary px-6 py-4 flex flex-col justify-between">
<div className="text-body-base font-bold text-text-heading">
{t('setting.appearance')}
</div>
<div className="flex w-full flex-row items-center gap-md">
<div className="gap-md flex w-full flex-row items-center">
{themeList.map((item: any) => (
<div
key={item.label}
className="group flex w-full flex-col items-center gap-sm hover:cursor-pointer"
className="group gap-sm flex w-full flex-col items-center hover:cursor-pointer"
onClick={() => setAppearance(item.value)}
>
<img
src={item.img}
className={`group-hover:border-bg-fill-info-primary aspect-[183/91.67] w-full rounded-lg border border-solid border-transparent transition-all ${
className={`group-hover:border-bg-fill-info-primary rounded-lg aspect-[183/91.67] w-full border border-solid border-transparent transition-all ${
item.value == appearance
? 'border-bg-fill-info-primary'
: ''
Expand All @@ -353,8 +359,8 @@ export default function SettingGeneral() {
</div>

{/* Network Proxy Section */}
<div className="flex flex-col gap-4 rounded-2xl bg-surface-secondary px-6 py-4">
<div className="flex flex-col gap-1">
<div className="gap-4 rounded-2xl bg-surface-secondary px-6 py-4 flex flex-col">
<div className="gap-1 flex flex-col">
<div className="text-body-base font-bold text-text-heading">
{t('setting.network-proxy')}
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/types/electron.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

interface IpcRenderer {
getPlatform: () => string;
getArch: () => string;
minimizeWindow: () => void;
toggleMaximizeWindow: () => void;
closeWindow: () => void;
Expand Down Expand Up @@ -50,6 +51,7 @@ interface ElectronAPI {
triggerMenuAction: (action: string) => void;
onExecuteAction: (callback: (action: string) => void) => void;
getPlatform: () => string;
getArch: () => string;
getHomeDir: () => Promise<string>;
createWebView: (id: string, url: string) => Promise<any>;
hideWebView: (id: string) => Promise<any>;
Expand Down
Loading