Skip to content

Commit

Permalink
Fix/linux deep link (#5377)
Browse files Browse the repository at this point in the history
* generate .desktop file

* allow only one single instance

* fix formatting

* remove focus hack

* rename and clean up open-url listeners

* remove second open-url listener

* add debug logging and second instance event

* comments

* fix typo

Co-authored-by: Filipe Freire <livrofubia@gmail.com>
  • Loading branch information
jackkav and filfreire committed Nov 3, 2022
1 parent 68b6b6a commit 61e1a59
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 38 deletions.
5 changes: 5 additions & 0 deletions packages/insomnia/electron-builder.config.js
Expand Up @@ -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',
Expand Down
65 changes: 30 additions & 35 deletions 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';
Expand Down Expand Up @@ -30,7 +31,6 @@ if (checkIfRestartNeeded()) {
}

initializeLogging();
const commandLineArgs = process.argv.slice(1);
log.info(`Running version ${getAppVersion()}`);

// Override the Electron userData path
Expand Down Expand Up @@ -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()) {
Expand All @@ -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
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions 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';
Expand All @@ -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;
Expand Down

0 comments on commit 61e1a59

Please sign in to comment.