diff --git a/arduino-ide-extension/src/common/utils.ts b/arduino-ide-extension/src/common/utils.ts index 56ed366c1..8a392c770 100644 --- a/arduino-ide-extension/src/common/utils.ts +++ b/arduino-ide-extension/src/common/utils.ts @@ -38,3 +38,26 @@ export function uint8ArrayToString(uint8Array: Uint8Array): string { export function stringToUint8Array(text: string): Uint8Array { return Uint8Array.from(text, (char) => char.charCodeAt(0)); } + +export function poolWhile( + whileCondition: () => boolean, + intervalMs: number, + timeoutMs: number +): Promise { + return new Promise((resolve, reject) => { + if (!whileCondition) { + resolve(); + } + + const start = Date.now(); + const interval = setInterval(() => { + if (!whileCondition()) { + clearInterval(interval); + resolve(); + } else if (Date.now() - start > timeoutMs) { + clearInterval(interval); + reject(new Error('Timed out while polling.')); + } + }, intervalMs); + }); +} diff --git a/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts b/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts index ba1851ff4..b6d0ff294 100644 --- a/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts +++ b/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts @@ -30,6 +30,7 @@ import type { AddressInfo } from 'node:net'; import { isAbsolute, join, resolve } from 'node:path'; import type { Argv } from 'yargs'; import { Sketch } from '../../common/protocol'; +import { poolWhile } from '../../common/utils'; import { AppInfo, appInfoPropertyLiterals, @@ -292,6 +293,16 @@ export class ElectronMainApplication extends TheiaElectronMainApplication { ); if (sketchFolderPath) { this.openFilePromise.reject(new InterruptWorkspaceRestoreError()); + + // open-file event is triggered before the app is ready and initialWindow is created. + // Wait for initialWindow to be set before opening the sketch on the first instance. + // See https://github.com/arduino/arduino-ide/pull/2693 + try { + await app.whenReady(); + if (!this.firstWindowId) { + await poolWhile(() => !this.initialWindow, 100, 3000); + } + } catch {} await this.openSketch(sketchFolderPath); } } @@ -890,7 +901,10 @@ const fallbackFrontendAppConfig: FrontendApplicationConfig = { defaultIconTheme: 'none', validatePreferencesSchema: false, defaultLocale: '', - electron: { showWindowEarly: true, uriScheme: 'custom://arduino-ide' }, + electron: { + showWindowEarly: true, + uriScheme: 'arduino-ide', + }, reloadOnReconnect: true, }; diff --git a/electron-app/package.json b/electron-app/package.json index 5bf2b0f18..6a31d222a 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -67,7 +67,8 @@ "defaultIconTheme": "none", "validatePreferencesSchema": false, "electron": { - "showWindowEarly": true + "showWindowEarly": true, + "uriScheme": "arduino-ide" }, "reloadOnReconnect": true, "preferences": {