mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 16:02:29 +00:00
* fix(startup): hold desktop activations until the startup window exists A second-instance, open-url, or open-file activation that landed after app ready but before the startup window was created opened its own main window. The startup open then built a second window, threw on the duplicate 'window:isMaximized' handler, and aborted runtime launch: no runtime RPC, no orca-runtime.json, an orphan hidden window holding the trusted-renderer id, and the visible window refused trusted IPC. The desktop activation gate now starts 'initializing' for every launch mode. The startup window opener releases it once that window exists, so queued activations focus it, and a desktop launch that fails first releases it so later activations can still open a window. Serve mode keeps settling the gate after its RPC is ready. * fix(startup): release desktop activation after failed ready prerequisites --------- Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
54 lines
2.0 KiB
TypeScript
54 lines
2.0 KiB
TypeScript
import { initializeMainProcessI18nAndMenu } from './main-process-i18n-menu'
|
|
import { mainProcessState as state } from './main-process-state'
|
|
import { initializeReadyFoundation } from './main-process-ready-foundation'
|
|
import { initializeReadyRuntimeServices } from './main-process-ready-runtime'
|
|
import { releaseDesktopActivationAfter } from './serve-desktop-activation'
|
|
import {
|
|
initializeMainProcessRuntimeLaunch,
|
|
type MainProcessRuntimeLaunchOptions
|
|
} from './main-process-runtime-launch'
|
|
|
|
/** Runs the ready-phase composition in the same dependency order as the legacy entry point. */
|
|
export async function initializeMainProcessReady(
|
|
launchOptions: MainProcessRuntimeLaunchOptions
|
|
): Promise<void> {
|
|
const options: MainProcessRuntimeLaunchOptions = {
|
|
...launchOptions,
|
|
openMainWindow: releaseDesktopActivationAfter(
|
|
state.desktopActivationGate,
|
|
launchOptions.openMainWindow
|
|
)
|
|
}
|
|
try {
|
|
await initializeReadyFoundation()
|
|
await initializeReadyRuntimeServices()
|
|
// Window creation can proceed while translations and the native menu initialize.
|
|
const i18nAndMenuReady = initializeMainProcessI18nAndMenu()
|
|
state.mainProcessI18nReady = i18nAndMenuReady.catch(() => {})
|
|
// Join both branches before cleanup can close the profile writer.
|
|
const results = await Promise.allSettled([
|
|
i18nAndMenuReady,
|
|
initializeMainProcessRuntimeLaunch(options)
|
|
])
|
|
for (const result of results) {
|
|
if (result.status === 'rejected') {
|
|
throw result.reason
|
|
}
|
|
}
|
|
} catch (error) {
|
|
// Startup now exits after failure; reopening would use a closing profile writer.
|
|
state.desktopActivationGate = null
|
|
try {
|
|
await state.store?.freezeWritesAsync()
|
|
state.profileStateAdmission?.release()
|
|
state.profileStateAdmission = undefined
|
|
} catch (closeError) {
|
|
console.error(
|
|
'[persistence] Failed to close profile persistence after startup failure:',
|
|
closeError
|
|
)
|
|
}
|
|
throw error
|
|
}
|
|
}
|