(options: { readonly show: boolean })
| 485 | }; |
| 486 | |
| 487 | const createMainBrowserWindow = (options: { readonly show: boolean }): BrowserWindow => { |
| 488 | const windowState = windowStateKeeper({ |
| 489 | defaultWidth: 1280, |
| 490 | defaultHeight: 800, |
| 491 | }); |
| 492 | |
| 493 | const linuxIcon = resolveLinuxIcon(); |
| 494 | |
| 495 | const window = new BrowserWindow({ |
| 496 | x: windowState.x, |
| 497 | y: windowState.y, |
| 498 | width: windowState.width, |
| 499 | height: windowState.height, |
| 500 | // Keep the window at or above the responsive layout's mobile breakpoint |
| 501 | // (Tailwind `md` = 768px). Below it the web shell switches to the mobile |
| 502 | // header, whose far-left hamburger would render under the native macOS |
| 503 | // traffic lights (issue #1125). Staying >= 768 means the desktop always |
| 504 | // renders the sidebar layout, so the lights only ever sit over the sidebar |
| 505 | // header, which is offset to clear them (.desktop-macos-titlebar). |
| 506 | minWidth: 768, |
| 507 | minHeight: 480, |
| 508 | show: options.show, |
| 509 | backgroundColor: "#0a0a0a", |
| 510 | autoHideMenuBar: true, |
| 511 | ...(process.platform === "darwin" |
| 512 | ? { titleBarStyle: "hidden" as const, trafficLightPosition: { x: 16, y: 17 } } |
| 513 | : {}), |
| 514 | ...(linuxIcon ? { icon: linuxIcon } : {}), |
| 515 | webPreferences: { |
| 516 | preload: PRELOAD_PATH, |
| 517 | contextIsolation: true, |
| 518 | nodeIntegration: false, |
| 519 | sandbox: true, |
| 520 | }, |
| 521 | }); |
| 522 | mainWindow = window; |
| 523 | |
| 524 | windowState.manage(window); |
| 525 | |
| 526 | window.once("closed", () => { |
| 527 | if (mainWindow === window) mainWindow = null; |
| 528 | }); |
| 529 | |
| 530 | window.once("ready-to-show", () => { |
| 531 | if (!window.isDestroyed()) window.show(); |
| 532 | }); |
| 533 | |
| 534 | window.webContents.setWindowOpenHandler(({ url, disposition }) => { |
| 535 | // JS-initiated `window.open(url, name, "popup=1,...")` calls (OAuth |
| 536 | // sign-in flow in packages/react/src/api/oauth-popup.ts:73) come in |
| 537 | // with disposition "new-window" — allow them as Electron child |
| 538 | // windows so the renderer's popup tracking (closed polling + |
| 539 | // BroadcastChannel handoff) works. Plain `<a target="_blank">` |
| 540 | // link clicks come in as "foreground-tab" / "background-tab" / |
| 541 | // "other" and route to the user's default browser. |
| 542 | if (disposition === "new-window") { |
| 543 | return { |
| 544 | action: "allow", |
no test coverage detected