refactor(lib): extract tray state types into own module

Move tray-related state holders out of lib.rs into a new
src-tauri/src/tray_runtime.rs:
- TrayState / TrayTooltip type aliases
- TrayPlaybackState newtype
- TrayMenuItems / TrayMenuItemsState
- TrayMenuLabels (+ Default impl) / TrayMenuLabelsState
- tray_state_icon helper

The actual tray builder + Tauri commands (try_build_tray_icon,
set_tray_tooltip, set_tray_menu_labels, toggle_tray_icon) already
lived in lib_commands/sync/tray.rs and continue to reach the types
through the existing super::* re-export chain.

lib.rs goes from 549 → 486 LOC. Behaviour-preserving — same managed
state, same Tauri State<T> registrations in run().
This commit is contained in:
Psychotoxical
2026-05-08 12:24:04 +02:00
parent fd69cb4988
commit 06f5c3e328
2 changed files with 70 additions and 65 deletions
+2 -65
View File
@@ -10,8 +10,10 @@ pub(crate) mod logging;
mod lib_commands;
#[cfg(target_os = "windows")]
mod taskbar_win;
mod tray_runtime;
pub(crate) use analysis_runtime::*;
pub(crate) use tray_runtime::*;
use std::collections::HashMap;
use std::sync::{Arc, Mutex, OnceLock, RwLock};
@@ -65,71 +67,6 @@ fn sync_cancel_flags() -> &'static Mutex<HashMap<String, Arc<AtomicBool>>> {
FLAGS.get_or_init(|| Mutex::new(HashMap::new()))
}
/// Holds the live system-tray icon handle. `None` means the tray is currently hidden/removed.
/// Dropping the inner `TrayIcon` fully removes it from the OS notification area on all platforms.
type TrayState = Mutex<Option<TrayIcon>>;
/// Cached tray tooltip text. Updated by `set_tray_tooltip` and re-applied when the
/// icon is rebuilt (e.g. after the user toggles the tray off and on again).
/// Empty string means "use the default `Psysonic` tooltip".
type TrayTooltip = Mutex<String>;
#[derive(Default)]
struct TrayPlaybackState(Mutex<String>);
fn tray_state_icon(state: &str) -> &'static str {
match state {
"play" => "",
"pause" => "",
_ => "",
}
}
/// Handles to all updatable tray menu items, kept around so `set_tray_menu_labels`
/// (i18n refresh) and `set_tray_tooltip` (track change) can re-text them without
/// rebuilding the whole tray icon. The `now_playing` slot is `Some` on Linux
/// only — it surfaces the current track as a disabled menu entry because
/// AppIndicator has no hover tooltip API.
struct TrayMenuItems {
play_pause: tauri::menu::MenuItem<tauri::Wry>,
next: tauri::menu::MenuItem<tauri::Wry>,
previous: tauri::menu::MenuItem<tauri::Wry>,
show_hide: tauri::menu::MenuItem<tauri::Wry>,
quit: tauri::menu::MenuItem<tauri::Wry>,
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
now_playing: Option<tauri::menu::MenuItem<tauri::Wry>>,
}
type TrayMenuItemsState = Mutex<Option<TrayMenuItems>>;
/// Cached translations for the tray menu. Defaults to English so the menu has
/// readable labels before the frontend has had a chance to run `set_tray_menu_labels`.
#[derive(Clone)]
struct TrayMenuLabels {
play_pause: String,
next: String,
previous: String,
show_hide: String,
quit: String,
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
nothing_playing: String,
}
impl Default for TrayMenuLabels {
fn default() -> Self {
Self {
play_pause: "Play / Pause".into(),
next: "Next Track".into(),
previous: "Previous Track".into(),
show_hide: "Show / Hide".into(),
quit: "Exit Psysonic".into(),
nothing_playing: "Nothing playing".into(),
}
}
}
type TrayMenuLabelsState = Mutex<TrayMenuLabels>;
/// Shared handle to OS media controls (MPRIS2 on Linux, Now Playing on macOS, SMTC on Windows).
/// `None` if souvlaki failed to initialize (e.g. no D-Bus session on Linux).
type MprisControls = Mutex<Option<souvlaki::MediaControls>>;