On X11/XWayland (Electron's default on Wayland sessions) the window had no
icon, so KDE Plasma showed the generic placeholder. Point BrowserWindow at
the packaged icon.png so the compositor has an icon to render.
When the app is hidden in the tray, closing then relaunching it triggered
the single-instance second-instance handler, which only called focus() — a
hidden window stays hidden on focus(), so the app appeared not to start
(notably on KDE Plasma Wayland where the tray icon may also be unreachable).
Call show() to surface it, and recreate the window if it no longer exists.
The desktop app ignored termination signals because the tray and embedded
express server keep the Electron event loop alive, forcing users to kill -9
on logout/shutdown. Add SIGINT/SIGTERM handlers that set isQuitting before
app.quit() so the hide-to-tray close handler doesn't swallow the quit.
The tray icon was loaded from desktop/build/icon.png, but build/ is
electron-builder's default buildResources directory, whose contents are
not packaged into the app. The icon therefore existed when running from
source but was missing in every released build, leaving an empty tray
icon.
Load the icon from the packaged app root instead and add icon.png there,
rendered from the circular logo.svg so it has transparent corners rather
than the square full-bleed source artwork.
Fixes#2668
Chromium already caps zoom levels internally, so the manual [-7, +7]
clamp was redundant. Removes the constants and clamping logic while
keeping the before-input-event approach intact for persistence support.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Electron does not register zoom shortcuts by default, so the desktop app
had no way to scale the UI. Register Ctrl+Plus, Ctrl+Minus and Ctrl+0
via webContents.before-input-event, and Ctrl+scroll via the zoom-changed
event.
The zoom level is clamped to [-7, +7] (Chromium's range, roughly 28% to
358%) and persisted to zoom.json in app.getPath('userData'), so the
chosen level survives restarts. Restored zoom is re-applied on every
did-finish-load, since Electron resets zoom across page reloads.
Fixes#2623
The old setupTray() called tray.destroy() before creating a new Tray. On
Linux with KDE Plasma 6 Wayland, tray.destroy() does not actually remove
the icon from plasmashell (electron/electron#49517), so the new Tray
registers a fresh dbusmenu while plasmashell keeps talking to the
orphaned one. Menu items still render (cached layout) but every
com.canonical.dbusmenu.Event("clicked", ...) method call from plasmashell
hits the destroyed handler and is dropped, so menu-item click callbacks
stop firing after the frontend triggers a rebuild on login.
Move the one-time Tray construction (icon, tooltip, click handler)
behind a !tray guard and keep setContextMenu in the always-run path. The
desktop:update-quick-entry-shortcut IPC handler keeps calling setupTray()
and the accelerator label updates without touching the native Tray.
Add shortcut management: register/unregister shortcuts dynamically
via IPC from the frontend settings. Add --quick-entry CLI argument
to show quick entry on launch or toggle it when a second instance
is started. Add show-main-window IPC handler for Ctrl+Enter task
open flow.
Add a complete OAuth 2.0 PKCE flow for the Electron desktop app:
- Implement PKCE code generation and token exchange in Electron
- Register custom protocol handler (vikunja-desktop://) for deep links
- Handle deep link race conditions (buffered URLs, process.argv fallback)
- Prevent duplicate IPC listener accumulation on re-mount
- Preserve sub-paths in OAuth authorize URL for non-root deployments
- Add token refresh support using Electron's net module