diff --git a/CHANGELOG.md b/CHANGELOG.md index ffbf81fc..519a5732 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -995,6 +995,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * On some PipeWire setups, play, pause, seek and volume changes only took effect after a long delay (10+ seconds). Root cause: the PipeWire ALSA bridge negotiated a multi-second audio buffer, so changes were only heard once it drained. Psysonic now caps that buffer, so the controls respond immediately. +### Linux — tray icon no longer duplicates on KDE + +**By [@Psychotoxical](https://github.com/Psychotoxical), reported by Asra on the Psysonic Discord, PR [#991](https://github.com/Psychotoxical/psysonic/pull/991)** + +* Toggling the system tray icon off and on no longer leaves duplicate Psysonic entries piling up in KDE's hidden-icons list. + + ## [1.46.0] - 2026-05-18 > **🙏 Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) — several of the polish fixes in this release landed directly off the back of his messages. diff --git a/src-tauri/src/lib_commands/sync/tray.rs b/src-tauri/src/lib_commands/sync/tray.rs index e97a124a..ec6154c1 100644 --- a/src-tauri/src/lib_commands/sync/tray.rs +++ b/src-tauri/src/lib_commands/sync/tray.rs @@ -64,6 +64,13 @@ fn flip_rgba_horizontal(rgba: &mut [u8], width: u32, height: u32) { } } +/// Stable tray-icon id. Without a fixed id, `TrayIconBuilder::new()` assigns a +/// fresh id on every rebuild; on KDE (StatusNotifierItem) each new id registers +/// a new item, and KDE keeps the stale ones in its "hidden icons" list — so +/// toggling the tray off/on piled up duplicate entries (Asra, 1.47-RC4). A +/// constant id makes every rebuild reuse the same item. +const TRAY_ICON_ID: &str = "psysonic-tray"; + pub(crate) fn build_tray_icon(app: &tauri::AppHandle) -> tauri::Result { let labels = app .try_state::() @@ -144,7 +151,7 @@ pub(crate) fn build_tray_icon(app: &tauri::AppHandle) -> tauri::Result } #[cfg(target_os = "windows")] - let tray_builder = TrayIconBuilder::new() + let tray_builder = TrayIconBuilder::with_id(TRAY_ICON_ID) .icon(app_tray_icon(app)) .menu(&menu) .tooltip(&tooltip_with_icon) @@ -154,7 +161,7 @@ pub(crate) fn build_tray_icon(app: &tauri::AppHandle) -> tauri::Result // (see on_tray_icon_event); keep the menu on right-click like typical Windows tray apps. .show_menu_on_left_click(false); #[cfg(not(target_os = "windows"))] - let tray_builder = TrayIconBuilder::new() + let tray_builder = TrayIconBuilder::with_id(TRAY_ICON_ID) .icon(app_tray_icon(app)) .menu(&menu) .tooltip(&cached_tooltip);