(options: CreateWindowOptions = {})
| 911 | } |
| 912 | |
| 913 | async function createWindow(options: CreateWindowOptions = {}): Promise<BrowserWindow> { |
| 914 | const createWindowStartedAt = performance.now() |
| 915 | const mac = isMac() |
| 916 | const cfg = await loadConfig() |
| 917 | const restoredState = sanitizeWindowState(cfg.windowState) |
| 918 | currentZoomFactor = normalizeZoomFactor(cfg.zoomFactor) |
| 919 | const win = new BrowserWindow({ |
| 920 | width: restoredState?.width ?? DEFAULT_WINDOW_WIDTH, |
| 921 | height: restoredState?.height ?? DEFAULT_WINDOW_HEIGHT, |
| 922 | ...(restoredState ? { x: restoredState.x, y: restoredState.y } : {}), |
| 923 | minWidth: MIN_WINDOW_WIDTH, |
| 924 | minHeight: MIN_WINDOW_HEIGHT, |
| 925 | show: false, |
| 926 | autoHideMenuBar: true, |
| 927 | titleBarStyle: mac ? 'hiddenInset' : 'hidden', |
| 928 | trafficLightPosition: { x: 16, y: 16 }, |
| 929 | ...(mac |
| 930 | ? { |
| 931 | // The renderer now runs fully opaque, so keeping the |
| 932 | // BrowserWindow transparent forces macOS into an unnecessary |
| 933 | // compositing path that makes typing feel mushy on large |
| 934 | // displays. Use a solid background instead. |
| 935 | backgroundColor: MAC_WINDOW_BACKGROUND_COLOR, |
| 936 | tabbingIdentifier: MAIN_WINDOW_TABBING_IDENTIFIER |
| 937 | } |
| 938 | : { |
| 939 | backgroundColor: '#faf7f0', |
| 940 | icon: windowIconPath() |
| 941 | }), |
| 942 | webPreferences: { |
| 943 | preload: path.join(__dirname, '../preload/index.js'), |
| 944 | // Keep the renderer isolated and node-free, but the current preload |
| 945 | // still relies on Node/Electron APIs that are not available inside a |
| 946 | // fully sandboxed preload context. |
| 947 | sandbox: false, |
| 948 | contextIsolation: true, |
| 949 | nodeIntegration: false |
| 950 | } |
| 951 | }) |
| 952 | |
| 953 | workspaceWindowIds.add(win.id) |
| 954 | |
| 955 | if (!mainWindow || mainWindow.isDestroyed()) { |
| 956 | mainWindow = win |
| 957 | mainWindowReadyForAppEvents = false |
| 958 | } |
| 959 | |
| 960 | let persistWindowStateTimer: ReturnType<typeof setTimeout> | null = null |
| 961 | const scheduleWindowStatePersist = () => { |
| 962 | if (persistWindowStateTimer) clearTimeout(persistWindowStateTimer) |
| 963 | persistWindowStateTimer = setTimeout(() => { |
| 964 | persistWindowStateTimer = null |
| 965 | void persistWindowState(win) |
| 966 | }, WINDOW_STATE_PERSIST_DELAY_MS) |
| 967 | } |
| 968 | const flushWindowStatePersist = () => { |
| 969 | if (persistWindowStateTimer) { |
| 970 | clearTimeout(persistWindowStateTimer) |
no test coverage detected