diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 673595830..bb44b93e8 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -25,7 +25,7 @@ async function main() { // needed for excalidraw export https://github.com/zadam/trilium/issues/4271 electron.app.commandLine.appendSwitch("enable-experimental-web-platform-features"); electron.app.commandLine.appendSwitch("lang", options.getOptionOrNull("formattingLocale") ?? "en"); - + // Disable smooth scroll if the option is set const smoothScrollEnabled = options.getOptionOrNull("smoothScrollEnabled"); if (smoothScrollEnabled === "false") { @@ -58,6 +58,27 @@ async function main() { electron.globalShortcut.unregisterAll(); }); + electron.app.on("second-instance", (event, commandLine) => { + const lastFocusedWindow = windowService.getLastFocusedWindow(); + if (commandLine.includes("--new-window")) { + windowService.createExtraWindow(""); + } else if (lastFocusedWindow) { + // Someone tried to run a second instance, we should focus our window. + // see www.ts "requestSingleInstanceLock" for the rest of this logic with explanation + if (lastFocusedWindow.isMinimized()) { + lastFocusedWindow.restore(); + } + lastFocusedWindow.show(); + lastFocusedWindow.focus(); + } + }); + + const isPrimaryInstance = (await import("electron")).app.requestSingleInstanceLock(); + if (!isPrimaryInstance) { + console.info("There's already an instance running, focusing that instance instead."); + process.exit(0); + } + // this is to disable electron warning spam in the dev console (local development only) process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true"; diff --git a/apps/server/src/services/window.ts b/apps/server/src/services/window.ts index 5420a5b43..b26b000af 100644 --- a/apps/server/src/services/window.ts +++ b/apps/server/src/services/window.ts @@ -173,22 +173,6 @@ async function createMainWindow(app: App) { mainWindow.on("closed", () => (mainWindow = null)); configureWebContents(mainWindow.webContents, spellcheckEnabled); - - app.on("second-instance", (event, commandLine) => { - const lastFocusedWindow = getLastFocusedWindow(); - if (commandLine.includes("--new-window")) { - createExtraWindow(""); - } else if (lastFocusedWindow) { - // Someone tried to run a second instance, we should focus our window. - // see www.ts "requestSingleInstanceLock" for the rest of this logic with explanation - if (lastFocusedWindow.isMinimized()) { - lastFocusedWindow.restore(); - } - lastFocusedWindow.show(); - lastFocusedWindow.focus(); - } - }); - trackWindowFocus(mainWindow); } @@ -345,6 +329,7 @@ function getAllWindows() { export default { createMainWindow, + createExtraWindow, createSetupWindow, closeSetupWindow, registerGlobalShortcuts, diff --git a/apps/server/src/www.ts b/apps/server/src/www.ts index 1bef980b2..7f3445312 100644 --- a/apps/server/src/www.ts +++ b/apps/server/src/www.ts @@ -55,24 +55,6 @@ export default async function startTriliumServer() { tmp.setGracefulCleanup(); const app = await buildApp(); - - /** - * 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 are configured separately. This complication is the source of the following weird usage. - * - * The line below makes sure that the "second-instance" (process in window.ts) 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 a complex evaluation. - */ - if (utils.isElectron) { - (await import("electron")).app.requestSingleInstanceLock(); - } - const httpServer = startHttpServer(app); const sessionParser = (await import("./routes/session_parser.js")).default;