diff --git a/packages/insomnia/electron-builder.config.js b/packages/insomnia/electron-builder.config.js index a626cf41d73..25b5a24fc75 100644 --- a/packages/insomnia/electron-builder.config.js +++ b/packages/insomnia/electron-builder.config.js @@ -102,6 +102,11 @@ const config = { executableName: 'insomnia', synopsis: 'The Collaborative API Client and Design Tool', category: 'Development', + desktop: { + Name: 'Insomnia', + Comment: 'Insomnia is a cross-platform REST client, built on top of Electron.', + Categories: 'Development', + }, target: [ { target: 'AppImage', diff --git a/packages/insomnia/src/main.development.ts b/packages/insomnia/src/main.development.ts index 31a7d0d0f5d..287f30d8c0e 100644 --- a/packages/insomnia/src/main.development.ts +++ b/packages/insomnia/src/main.development.ts @@ -1,4 +1,5 @@ import electron, { app, ipcMain, session } from 'electron'; +import { BrowserWindow } from 'electron/main'; import contextMenu from 'electron-context-menu'; import installExtension, { REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } from 'electron-devtools-installer'; import path from 'path'; @@ -30,7 +31,6 @@ if (checkIfRestartNeeded()) { } initializeLogging(); -const commandLineArgs = process.argv.slice(1); log.info(`Running version ${getAppVersion()}`); // Override the Electron userData path @@ -121,12 +121,6 @@ if (defaultProtocolSuccessful) { } } -function _addUrlToOpen(event: Electron.Event, url: string) { - event.preventDefault(); - commandLineArgs.push(url); -} - -app.on('open-url', _addUrlToOpen); // Quit when all windows are closed (except on Mac). app.on('window-all-closed', () => { if (!isMac()) { @@ -138,6 +132,7 @@ app.on('activate', (_error, hasVisibleWindows) => { // Create a new window when clicking the doc icon if there isn't one open if (!hasVisibleWindows) { try { + console.log('[main] creating new window for MacOS activate event'); windowUtils.createWindow(); } catch (error) { // This might happen if 'ready' hasn't fired yet. So we're just going @@ -149,44 +144,44 @@ app.on('activate', (_error, hasVisibleWindows) => { const _launchApp = async () => { await _trackStats(); - - app.removeListener('open-url', _addUrlToOpen); - const window = windowUtils.createWindow(); - + let window: BrowserWindow; // Handle URLs sent via command line args ipcMain.once('window-ready', () => { - // @ts-expect-error -- TSCONVERSION - commandLineArgs.length && window.send('run-command', commandLineArgs[0]); + console.log('[main] Window ready, handling command line arguments', process.argv); + window.webContents.send('shell:open', process.argv.slice(1)); }); - // Called when second instance launched with args (Windows) - // @TODO: Investigate why this closes electron when using playwright (tested on macOS) - // and find a better solution. + // Disable deep linking in playwright e2e tests in order to run multiple tests in parallel if (!process.env.PLAYWRIGHT) { + // Deep linking logic - https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) { console.error('[app] Failed to get instance lock'); - return; + app.quit(); + } else { + // Called when second instance launched with args (Windows/Linux) + app.on('second-instance', (_1, args) => { + console.log('Second instance listener received:', args.join('||')); + if (window) { + if (window.isMinimized()) { + window.restore(); + } + window.focus(); + } + const lastArg = args.slice(-1).join(); + console.log('[main] Open Deep Link URL sent from second instance', lastArg); + window.webContents.send('shell:open', lastArg); + }); + window = windowUtils.createWindow(); + + app.on('open-url', (_event, url) => { + console.log('[main] Open Deep Link URL', url); + window.webContents.send('shell:open', url); + }); } + } else { + window = windowUtils.createWindow(); } - app.on('second-instance', () => { - // Someone tried to run a second instance, we should focus our window. - if (window) { - if (window.isMinimized()) { - window.restore(); - } - window.focus(); - } - }); - // Handle URLs when app already open - app.addListener('open-url', (_event, url) => { - window.webContents.send('run-command', url); - // Apparently a timeout is needed because Chrome steals back focus immediately - // after opening the URL. - setTimeout(() => { - window.focus(); - }, 100); - }); // Don't send origin header from Insomnia because we're not technically using CORS session.defaultSession.webRequest.onBeforeSendHeaders((details, fn) => { delete details.requestHeaders.Origin; diff --git a/packages/insomnia/src/ui/hooks/use-app-commands.ts b/packages/insomnia/src/ui/hooks/use-app-commands.ts index b707b12c021..1e8675532c1 100644 --- a/packages/insomnia/src/ui/hooks/use-app-commands.ts +++ b/packages/insomnia/src/ui/hooks/use-app-commands.ts @@ -1,4 +1,4 @@ -import { ipcRenderer } from 'electron'; +import { IpcRendererEvent } from 'electron/renderer'; import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { parse } from 'url'; @@ -12,8 +12,8 @@ export const useAppCommands = () => { // Handle Application Commands useEffect(() => { - ipcRenderer.on('run-command', (_, commandUri) => { - const parsed = parse(commandUri, true); + return window.main.on('shell:open', (_: IpcRendererEvent, url: string) => { + const parsed = parse(url, true); const command = `${parsed.hostname}${parsed.pathname}`; const args = JSON.parse(JSON.stringify(parsed.query)); args.workspaceId = args.workspaceId || activeWorkspace?._id;