From 68fe6a928bdf4ce9fc778ca54742a0adec3f3d09 Mon Sep 17 00:00:00 2001 From: firtoz <108406948+firtoz@users.noreply.github.com> Date: Sun, 15 Mar 2026 19:54:26 +0000 Subject: [PATCH] fix(tray): single-click opens window and brings it to front; Linux/Wayland focus workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add tray.on('click') to call focusOrCreateMainWindow() so left-click on the systray icon opens/focuses the app on all platforms (was previously only possible via right-click → Open). - On Linux/Wayland, compositors often ignore focus() for security; Electron's tray does not yet handle ProvideXdgActivationToken like Qt apps (e.g. Telegram). Workaround: when the HUD exists but is not focused, destroy and recreate it so the new window receives focus (creation path works). Applied only for the HUD overlay, not the editor. - Reorder: show() before restore(), then moveTop(), focus() for more reliable raise-on-restore. Made-with: Cursor --- electron/main.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/electron/main.ts b/electron/main.ts index adc010ea..163a6507 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -84,10 +84,25 @@ function focusOrCreateMainWindow() { } if (mainWindow && !mainWindow.isDestroyed()) { - if (mainWindow.isMinimized()) mainWindow.restore() + // On Linux/Wayland, focus() often doesn't take effect (compositor ignores it). Apps like Telegram + // work because they receive an XDG activation token via StatusNotifierItem.ProvideXdgActivationToken; + // Electron's tray doesn't handle that yet. Workaround: destroy and recreate the HUD so the new + // window gets focus (creation path works). Only for HUD, not editor. + if ( + process.platform === 'linux' && + !mainWindow.isFocused() && + !isEditorWindow(mainWindow) + ) { + const win = mainWindow + mainWindow = null + win.once('closed', () => createWindow()) + win.destroy() + return + } mainWindow.show() - mainWindow.focus() + if (mainWindow.isMinimized()) mainWindow.restore() mainWindow.moveTop() + mainWindow.focus() } } @@ -204,6 +219,7 @@ function setupApplicationMenu() { function createTray() { tray = new Tray(defaultTrayIcon); + tray.on('click', () => focusOrCreateMainWindow()) } function getPublicAssetPath(filename: string) {