From 128f8066c3cd82520179a69beb5f1c1baadf5956 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 19 Dec 2023 09:22:43 +0000 Subject: [PATCH] fix(electron): main window should be opened first before destroying onboard window (#5319) The issue listed on the title will prevent main window from showing on windows. --- packages/common/env/src/constant.ts | 1 + packages/common/infra/src/preload/electron.ts | 3 +++ packages/frontend/core/src/index.tsx | 22 ++++++++++++------- packages/frontend/electron/src/main/index.ts | 6 ++--- .../frontend/electron/src/main/main-window.ts | 9 +------- .../frontend/electron/src/main/onboarding.ts | 12 ++-------- .../frontend/electron/src/main/ui/handlers.ts | 15 +++++++++---- .../src/main/windows-manager/launcher.ts | 9 ++++---- 8 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/common/env/src/constant.ts b/packages/common/env/src/constant.ts index 28938bfb3a..179ec41abb 100644 --- a/packages/common/env/src/constant.ts +++ b/packages/common/env/src/constant.ts @@ -6,6 +6,7 @@ declare global { appInfo: { electron: boolean; schema: string; + windowName: string; }; } } diff --git a/packages/common/infra/src/preload/electron.ts b/packages/common/infra/src/preload/electron.ts index 25e398c75c..087141aaa5 100644 --- a/packages/common/infra/src/preload/electron.ts +++ b/packages/common/infra/src/preload/electron.ts @@ -59,6 +59,9 @@ schema = isDev ? 'affine-dev' : schema; export const appInfo = { electron: true, + windowName: process.argv + .find(arg => arg.startsWith('--window-name=')) + ?.split('=')[1], schema, }; diff --git a/packages/frontend/core/src/index.tsx b/packages/frontend/core/src/index.tsx index f6397dcc61..c6e55e5cfc 100644 --- a/packages/frontend/core/src/index.tsx +++ b/packages/frontend/core/src/index.tsx @@ -16,19 +16,25 @@ const performanceMainLogger = performanceLogger.namespace('main'); function main() { performanceMainLogger.info('start'); - const rootStore = getCurrentStore(); - performanceMainLogger.info('setup start'); - setup(); - performanceMainLogger.info('setup done'); + // skip bootstrap setup for desktop onboarding + if (window.appInfo?.windowName !== 'onboarding') { + const rootStore = getCurrentStore(); + performanceMainLogger.info('setup start'); + setup(); + performanceMainLogger.info('setup done'); - bootstrapPluginSystem(rootStore).catch(err => { - console.error('Failed to bootstrap plugin system', err); - }); + bootstrapPluginSystem(rootStore).catch(err => { + console.error('Failed to bootstrap plugin system', err); + }); + } + mountApp(); +} + +function mountApp() { performanceMainLogger.info('import app'); const root = document.getElementById('app'); assertExists(root); - performanceMainLogger.info('render app'); createRoot(root).render( diff --git a/packages/frontend/electron/src/main/index.ts b/packages/frontend/electron/src/main/index.ts index 4002e0a3a7..3a47d268a9 100644 --- a/packages/frontend/electron/src/main/index.ts +++ b/packages/frontend/electron/src/main/index.ts @@ -10,7 +10,6 @@ import { persistentConfig } from './config-storage/persist'; import { setupDeepLink } from './deep-link'; import { registerEvents } from './events'; import { registerHandlers } from './handlers'; -import { ensureHelperProcess } from './helper-process'; import { logger } from './logger'; import { registerProtocol } from './protocol'; import { registerUpdater } from './updater'; @@ -59,7 +58,9 @@ app.on('window-all-closed', () => { /** * @see https://www.electronjs.org/docs/latest/api/app#event-activate-macos Event: 'activate' */ -app.on('activate', launch); +app.on('activate', () => { + launch().catch(e => console.error('Failed launch:', e)); +}); setupDeepLink(app); @@ -71,7 +72,6 @@ app .then(registerProtocol) .then(registerHandlers) .then(registerEvents) - .then(ensureHelperProcess) .then(launch) .then(createApplicationMenu) .then(registerUpdater) diff --git a/packages/frontend/electron/src/main/main-window.ts b/packages/frontend/electron/src/main/main-window.ts index 1bf82f90b9..9372b00831 100644 --- a/packages/frontend/electron/src/main/main-window.ts +++ b/packages/frontend/electron/src/main/main-window.ts @@ -14,8 +14,6 @@ import { parseCookie } from './utils'; const IS_DEV: boolean = process.env.NODE_ENV === 'development' && !process.env.CI; -const DEV_TOOL = process.env.DEV_TOOL === 'true'; - // todo: not all window need all of the exposed meta const getWindowAdditionalArguments = async () => { const { getExposedMeta } = await import('./exposed'); @@ -25,6 +23,7 @@ const getWindowAdditionalArguments = async () => { return [ `--main-exposed-meta=` + JSON.stringify(mainExposedMeta), `--helper-exposed-meta=` + JSON.stringify(helperExposedMeta), + `--window-name=main`, ]; }; @@ -92,12 +91,6 @@ async function createWindow(additionalArguments: string[]) { ); logger.info('main window is ready to show'); - - if (DEV_TOOL) { - browserWindow.webContents.openDevTools({ - mode: 'detach', - }); - } }); browserWindow.on('close', e => { diff --git a/packages/frontend/electron/src/main/onboarding.ts b/packages/frontend/electron/src/main/onboarding.ts index e0ef3692e7..caeeeb6b8c 100644 --- a/packages/frontend/electron/src/main/onboarding.ts +++ b/packages/frontend/electron/src/main/onboarding.ts @@ -1,32 +1,23 @@ -import { assert } from 'console'; import { BrowserWindow, screen } from 'electron'; import { join } from 'path'; import { mainWindowOrigin } from './constants'; // import { getExposedMeta } from './exposed'; -import { ensureHelperProcess } from './helper-process'; import { logger } from './logger'; // todo: not all window need all of the exposed meta const getWindowAdditionalArguments = async () => { const { getExposedMeta } = await import('./exposed'); const mainExposedMeta = getExposedMeta(); - const helperProcessManager = await ensureHelperProcess(); - const helperExposedMeta = await helperProcessManager.rpc?.getMeta(); return [ `--main-exposed-meta=` + JSON.stringify(mainExposedMeta), - `--helper-exposed-meta=` + JSON.stringify(helperExposedMeta), + `--window-name=onboarding`, ]; }; async function createOnboardingWindow(additionalArguments: string[]) { logger.info('creating onboarding window'); - const helperProcessManager = await ensureHelperProcess(); - const helperExposedMeta = await helperProcessManager.rpc?.getMeta(); - - assert(helperExposedMeta, 'helperExposedMeta should be defined'); - // get user's screen size const { width, height } = screen.getPrimaryDisplay().workAreaSize; @@ -35,6 +26,7 @@ async function createOnboardingWindow(additionalArguments: string[]) { height, frame: false, show: false, + resizable: false, closable: false, minimizable: false, maximizable: false, diff --git a/packages/frontend/electron/src/main/ui/handlers.ts b/packages/frontend/electron/src/main/ui/handlers.ts index 45f15f583a..6cfcdcc7f5 100644 --- a/packages/frontend/electron/src/main/ui/handlers.ts +++ b/packages/frontend/electron/src/main/ui/handlers.ts @@ -54,10 +54,17 @@ export const uiHandlers = { launchStage.value = 'main'; persistentConfig.patch('onBoarding', false); } - initMainWindow().catch(logger.error); - getOnboardingWindow() - .then(w => w?.destroy()) - .catch(logger.error); + + try { + const onboarding = await getOnboardingWindow(); + onboarding?.hide(); + await initMainWindow(); + // need to destroy onboarding window after main window is ready + // otherwise the main window will be closed as well + onboarding?.destroy(); + } catch (err) { + logger.error('handleOpenMainApp', err); + } }, getBookmarkDataByLink: async (_, link: string) => { if ( diff --git a/packages/frontend/electron/src/main/windows-manager/launcher.ts b/packages/frontend/electron/src/main/windows-manager/launcher.ts index cef7903e94..f47b99c646 100644 --- a/packages/frontend/electron/src/main/windows-manager/launcher.ts +++ b/packages/frontend/electron/src/main/windows-manager/launcher.ts @@ -1,3 +1,4 @@ +import { logger } from '../logger'; import { initMainWindow } from '../main-window'; import { getOnboardingWindow, @@ -8,19 +9,19 @@ import { launchStage } from './stage'; /** * Launch app depending on launch stage */ -export function launch() { +export async function launch() { const stage = launchStage.value; if (stage === 'main') { initMainWindow().catch(e => { - console.error('Failed to restore or create window:', e); + logger.error('Failed to restore or create window:', e); }); getOnboardingWindow() .then(w => w?.destroy()) - .catch(e => console.error('Failed to destroy onboarding window:', e)); + .catch(e => logger.error('Failed to destroy onboarding window:', e)); } if (stage === 'onboarding') getOrCreateOnboardingWindow().catch(e => { - console.error('Failed to restore or create onboarding window:', e); + logger.error('Failed to restore or create onboarding window:', e); }); }