Skip to content

Commit 1e542f9

Browse files
Revert "Electron style - MacOs (eigent-ai#1110)" (eigent-ai#1512)
Co-authored-by: Douglas <douglas.ym.lai@gmail.com>
1 parent cafb1ae commit 1e542f9

5 files changed

Lines changed: 99 additions & 252 deletions

File tree

‎electron/main/index.ts‎

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,7 @@ import {
5050
getInstallationStatus,
5151
PromiseReturnType,
5252
} from './install-deps';
53-
import {
54-
setRoundedCorners,
55-
setTransparentTitlebar,
56-
setVibrancy,
57-
} from './native/macos-window';
53+
import { setRoundedCorners } from './native/macos-window';
5854
import { registerUpdateIpcHandlers, update } from './update';
5955
import {
6056
getEmailFolderPath,
@@ -2741,8 +2737,7 @@ async function createWindow() {
27412737
);
27422738

27432739
// Platform-specific window configuration
2744-
// Windows: Use native frame for better native feel, solid background
2745-
// macOS: Use frameless with transparency and vibrancy effects
2740+
// Windows: native frame and solid background. macOS/Linux: frameless; macOS corner radius via native hook.
27462741
win = new BrowserWindow({
27472742
title: 'Eigent',
27482743
width: 1200,
@@ -2754,12 +2749,16 @@ async function createWindow() {
27542749
show: false, // Don't show until content is ready to avoid white screen
27552750
// Only use transparency on macOS and Linux (not supported well on Windows)
27562751
transparent: !isWindows,
2757-
// Solid background on Windows (respect dark/light mode), fully transparent on macOS for native vibrancy
2752+
// Solid on Windows; macOS solid without vibrancy; Linux unchanged semi-transparent tint
27582753
backgroundColor: isWindows
27592754
? nativeTheme.shouldUseDarkColors
27602755
? '#1e1e1e'
27612756
: '#ffffff'
2762-
: '#00000000',
2757+
: isMac
2758+
? nativeTheme.shouldUseDarkColors
2759+
? '#1e1e1e'
2760+
: '#f5f5f5'
2761+
: '#f5f5f580',
27632762
// macOS-specific title bar styling
27642763
titleBarStyle: isMac ? 'hidden' : undefined,
27652764
trafficLightPosition: isMac ? { x: 10, y: 10 } : undefined,
@@ -2783,23 +2782,13 @@ async function createWindow() {
27832782
},
27842783
});
27852784

2786-
// Apply native macOS effects
27872785
if (process.platform === 'darwin') {
27882786
win.once('ready-to-show', () => {
27892787
if (win && !win.isDestroyed()) {
27902788
try {
2791-
// Apply vibrancy with HUDWindow material (or others like 'Sidebar', 'UnderWindowBackground')
2792-
setVibrancy(win, 'HUDWindow');
2793-
2794-
// Apply rounded corners
27952789
setRoundedCorners(win, 20);
2796-
2797-
// Make titlebar transparent
2798-
setTransparentTitlebar(win);
2799-
2800-
log.info('[MacOS] Applied native visual effects');
28012790
} catch (error) {
2802-
log.error('[MacOS] Failed to apply native visual effects:', error);
2791+
log.error('[MacOS] Failed to apply rounded corners:', error);
28032792
}
28042793
}
28052794
});

‎electron/main/native/macos-window.ts‎

Lines changed: 30 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -13,233 +13,66 @@
1313
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
1414

1515
import { BrowserWindow } from 'electron';
16+
import log from 'electron-log';
1617
import koffi from 'koffi';
1718
import os from 'os';
1819

19-
// NSVisualEffectView material constants (enum values)
20-
export const NSVisualEffectMaterial = {
21-
Titlebar: 3,
22-
Selection: 4,
23-
Menu: 5,
24-
Popover: 6,
25-
Sidebar: 7,
26-
HeaderView: 10,
27-
Sheet: 11,
28-
WindowBackground: 12,
29-
HUDWindow: 13,
30-
FullScreenUI: 15,
31-
ToolTip: 17,
32-
ContentBackground: 18,
33-
UnderWindowBackground: 21,
34-
UnderPageBackground: 22,
35-
} as const;
20+
type SetRoundedCorners = (window: BrowserWindow, radius?: number) => void;
3621

37-
export type MaterialType = keyof typeof NSVisualEffectMaterial;
38-
39-
// Interface for our module functions
40-
interface MacWindowUtils {
41-
setVibrancy: (window: BrowserWindow, material?: MaterialType) => void;
42-
setRoundedCorners: (window: BrowserWindow, radius?: number) => void;
43-
setTransparentTitlebar: (window: BrowserWindow) => void;
44-
}
45-
46-
let utils: MacWindowUtils;
22+
let setRoundedCorners: SetRoundedCorners = () => {};
4723

4824
if (os.platform() === 'darwin') {
4925
try {
5026
const objc = koffi.load('libobjc.A.dylib');
5127

52-
// Types
5328
const Ptr = 'size_t';
5429

55-
const objc_getClass = objc.func('objc_getClass', Ptr, ['string']);
5630
const sel_registerName = objc.func('sel_registerName', Ptr, ['string']);
5731
const objc_msgSend = objc.func('objc_msgSend', Ptr, [Ptr, Ptr]);
58-
const objc_msgSend_long = objc.func('objc_msgSend', Ptr, [
32+
const objc_msgSend_bool = objc.func('objc_msgSend', Ptr, [
5933
Ptr,
6034
Ptr,
61-
'long',
35+
'bool',
6236
]);
6337
const objc_msgSend_double = objc.func('objc_msgSend', Ptr, [
6438
Ptr,
6539
Ptr,
6640
'double',
6741
]);
68-
const objc_msgSend_bool = objc.func('objc_msgSend', Ptr, [
69-
Ptr,
70-
Ptr,
71-
'bool',
72-
]);
73-
74-
const NSRect = koffi.struct('NSRect', {
75-
x: 'double',
76-
y: 'double',
77-
width: 'double',
78-
height: 'double',
79-
});
80-
81-
const NSVisualEffectBlendingMode = {
82-
BehindWindow: 0,
83-
WithinWindow: 1,
84-
};
85-
86-
utils = {
87-
setVibrancy: (
88-
window: BrowserWindow,
89-
material: MaterialType = 'HUDWindow'
90-
) => {
91-
try {
92-
const windowHandle = window.getNativeWindowHandle();
93-
if (windowHandle.length === 0) return;
94-
95-
// Electron calls valid native handle returns the NSView (BridgedContentView) on macOS
96-
const nsViewPtr = windowHandle.readBigUInt64LE();
97-
if (!nsViewPtr) return;
98-
99-
// Selectors
100-
const selAlloc = sel_registerName('alloc');
101-
const selInit = sel_registerName('init');
102-
const selSetMaterial = sel_registerName('setMaterial:');
103-
const selSetBlendingMode = sel_registerName('setBlendingMode:');
104-
const selSetState = sel_registerName('setState:');
105-
const selSetAutoresizingMask = sel_registerName(
106-
'setAutoresizingMask:'
107-
);
108-
const selSetFrame = sel_registerName('setFrame:');
109-
const selAddSubview = sel_registerName(
110-
'addSubview:positioned:relativeTo:'
111-
);
11242

113-
const NSVisualEffectViewClass = objc_getClass('NSVisualEffectView');
114-
if (!NSVisualEffectViewClass) return;
43+
setRoundedCorners = (window: BrowserWindow, radius = 20) => {
44+
try {
45+
const windowHandle = window.getNativeWindowHandle();
46+
if (!windowHandle?.length) return;
11547

116-
// Allocation
117-
const visualEffectView = objc_msgSend(
118-
NSVisualEffectViewClass,
119-
selAlloc
120-
);
121-
objc_msgSend(visualEffectView, selInit);
48+
const nsViewPtr = windowHandle.readBigUInt64LE();
49+
if (!nsViewPtr) return;
12250

123-
const materialValue =
124-
NSVisualEffectMaterial[material] ||
125-
NSVisualEffectMaterial.HUDWindow;
51+
const selLayer = sel_registerName('layer');
52+
const selSetWantsLayer = sel_registerName('setWantsLayer:');
53+
const selSetCornerRadius = sel_registerName('setCornerRadius:');
54+
const selSetMasksToBounds = sel_registerName('setMasksToBounds:');
12655

127-
// Configuration
128-
objc_msgSend_long(visualEffectView, selSetMaterial, materialValue);
129-
objc_msgSend_long(
130-
visualEffectView,
131-
selSetBlendingMode,
132-
NSVisualEffectBlendingMode.WithinWindow
133-
);
134-
objc_msgSend_long(visualEffectView, selSetState, 1);
135-
objc_msgSend_long(visualEffectView, selSetAutoresizingMask, 18);
56+
objc_msgSend_bool(nsViewPtr, selSetWantsLayer, true);
13657

137-
// Frame
138-
const bounds = window.getBounds();
139-
const viewFrame = {
140-
x: 0,
141-
y: 0,
142-
width: bounds.width,
143-
height: bounds.height,
144-
};
145-
146-
const objc_msgSend_frame = objc.func('objc_msgSend', 'void', [
147-
Ptr,
148-
Ptr,
149-
NSRect,
150-
]);
151-
objc_msgSend_frame(visualEffectView, selSetFrame, viewFrame);
152-
153-
// Add Subview to the CONTENT VIEW (which we already have as nsViewPtr)
154-
const objc_msgSend_positioned = objc.func('objc_msgSend', 'void', [
155-
Ptr,
156-
Ptr,
157-
Ptr,
158-
'long',
159-
Ptr,
160-
]);
161-
objc_msgSend_positioned(
162-
nsViewPtr,
163-
selAddSubview,
164-
visualEffectView,
165-
-1,
166-
0
167-
); // -1 = NSWindowBelow
168-
169-
console.log(`[MacOS] Vibrancy applied successfully`);
170-
} catch (error) {
171-
console.error('[MacOS] Error applying vibrancy:', error);
172-
}
173-
},
174-
175-
setRoundedCorners: (window: BrowserWindow, radius = 20) => {
176-
try {
177-
const windowHandle = window.getNativeWindowHandle();
178-
const nsViewPtr = windowHandle.readBigUInt64LE();
179-
180-
const selLayer = sel_registerName('layer');
181-
const selSetWantsLayer = sel_registerName('setWantsLayer:');
182-
const selSetCornerRadius = sel_registerName('setCornerRadius:');
183-
const selSetMasksToBounds = sel_registerName('setMasksToBounds:');
184-
185-
// Ensure layer-backing
186-
objc_msgSend_bool(nsViewPtr, selSetWantsLayer, true);
187-
188-
// Get layer
189-
const nsLayer = objc_msgSend(nsViewPtr, selLayer);
190-
if (!nsLayer) return console.error('[MacOS] Failed to get layer');
191-
192-
// Apply Corner Radius
193-
objc_msgSend_double(nsLayer, selSetCornerRadius, radius);
194-
objc_msgSend_bool(nsLayer, selSetMasksToBounds, true);
195-
196-
console.log(`[MacOS] Rounded corners applied: ${radius}`);
197-
} catch (error) {
198-
console.error('[MacOS] Error applying rounded corners:', error);
58+
const nsLayer = objc_msgSend(nsViewPtr, selLayer);
59+
if (!nsLayer) {
60+
log.error('[MacOS] Failed to get layer for rounded corners');
61+
return;
19962
}
200-
},
201-
202-
setTransparentTitlebar: (window: BrowserWindow) => {
203-
try {
204-
const windowHandle = window.getNativeWindowHandle();
205-
const nsViewPtr = windowHandle.readBigUInt64LE();
206-
207-
// We have the View, we need the Window
208-
const selWindow = sel_registerName('window');
209-
const nsWindowPtr = objc_msgSend(nsViewPtr, selWindow);
21063

211-
if (!nsWindowPtr)
212-
return console.error('[MacOS] Failed to get NSWindow from NSView');
213-
214-
const selSetTitlebarAppearsTransparent = sel_registerName(
215-
'setTitlebarAppearsTransparent:'
216-
);
217-
objc_msgSend_bool(
218-
nsWindowPtr,
219-
selSetTitlebarAppearsTransparent,
220-
true
221-
);
222-
223-
console.log('[MacOS] Transparent titlebar applied');
224-
} catch (error) {
225-
console.error('[MacOS] Error setting transparent titlebar:', error);
226-
}
227-
},
64+
objc_msgSend_double(nsLayer, selSetCornerRadius, radius);
65+
objc_msgSend_bool(nsLayer, selSetMasksToBounds, true);
66+
} catch (error) {
67+
log.error('[MacOS] Error applying rounded corners:', error);
68+
}
22869
};
22970
} catch (e) {
230-
console.error('[MacOS] Failed to load native libraries:', e);
231-
utils = {
232-
setVibrancy: () => {},
233-
setRoundedCorners: () => {},
234-
setTransparentTitlebar: () => {},
235-
};
71+
log.error(
72+
'[MacOS] Failed to load native libraries for rounded corners:',
73+
e
74+
);
23675
}
237-
} else {
238-
utils = {
239-
setVibrancy: () => {},
240-
setRoundedCorners: () => {},
241-
setTransparentTitlebar: () => {},
242-
};
24376
}
24477

245-
export const { setVibrancy, setRoundedCorners, setTransparentTitlebar } = utils;
78+
export { setRoundedCorners };

0 commit comments

Comments
 (0)