focus existing window on port conflict, closes #3036

This commit is contained in:
zadam 2022-08-02 22:53:06 +02:00
parent 563808144e
commit f161488c13
3 changed files with 29 additions and 2 deletions

View file

@ -29,7 +29,7 @@ app.on('ready', async () => {
if (await sqlInit.isDbInitialized()) {
await sqlInit.dbReady;
await windowService.createMainWindow();
await windowService.createMainWindow(app);
tray.createTray();
}

View file

@ -44,7 +44,7 @@ ipcMain.on('create-extra-window', (event, arg) => {
createExtraWindow(arg.notePath, arg.hoistedNoteId);
});
async function createMainWindow() {
async function createMainWindow(app) {
const windowStateKeeper = require('electron-window-state'); // should not be statically imported
const mainWindowState = windowStateKeeper({
@ -81,6 +81,18 @@ async function createMainWindow() {
mainWindow.on('closed', () => mainWindow = null);
configureWebContents(mainWindow.webContents, spellcheckEnabled);
app.on('second-instance', () => {
// Someone tried to run a second instance, we should focus our window.
// see www.js "requestSingleInstanceLock" for the rest of this logic with explanation
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.focus();
}
});
}
function configureWebContents(webContents, spellcheckEnabled) {

15
src/www
View file

@ -38,6 +38,21 @@ if (!semver.satisfies(process.version, ">=10.5.0")) {
let httpServer;
async function startTrilium() {
/**
* The intended behavior is to detect when a second instance is running, in that case open the old instance
* instead of the new one. This is complicated by the fact that it is possible to run multiple instances of Trilium
* if port and data dir is configured separately. This complication is the source of the following weird usage.
*
* The line below makes sure that the "second-instance" (process in window.js) is fired. Normally it returns a boolean
* indicating whether another instance is running or not, but we ignore that and kill the app only based on the port conflict.
*
* A bit weird is that "second-instance" is triggered also on the valid usecases (different port/data dir) and
* focuses the existing window. But the new process is start as well and will steal the focus too, it will win, because
* its startup is slower than focusing the existing process/window. So in the end it works out without having
* to do complex evaluation.
*/
require("electron").app.requestSingleInstanceLock();
const usedPort = await port;
const usedHost = await host;