Port the Tauri desktop-notification path to a frontend-agnostic crate so the Slint app (and any future TUI/CLI) fires it from native Rust instead of a webview invoke. New qbz-media-controls::notify module: - Linux: XDG notification portal via ashpd (D-Bus); album art passed as Icon::Bytes after center-crop + downscale to <=512px + PNG re-encode (<=4 MiB). - macOS: notify_rust with image_path (cover cached to disk). - Windows: no-op (parity with Tauri). - Self-contained artwork download + md5 cache + resize, matching the Tauri helpers, with no dependency on the frontend (ADR-006). Wired in playback::refresh_now_playing_meta (the same point that pushes the tray tooltip + OS media controls): - De-dupe by track id so only an actual track change fires (the refresh also runs on resume/seek). - Skip while a remote QConnect renderer drives playback (matches the Svelte skipIfRemote). Fire-and-forget on a tokio task. Enabled by default, matching the Tauri default; a settings toggle is a follow-up. cc
48 lines
2.0 KiB
TOML
48 lines
2.0 KiB
TOML
[package]
|
|
name = "qbz-media-controls"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
description = "Frontend-agnostic system media controls: MPRIS (mpris-server) on Linux with a DesktopEntry so GNOME shows the app icon; SMTC/MediaRemote (souvlaki) on Windows/macOS"
|
|
|
|
[dependencies]
|
|
log = { workspace = true }
|
|
# Notifications (all platforms): the async entry point spawns the HTTP download
|
|
# + image resize on `spawn_blocking`, so a tokio runtime must be present.
|
|
tokio = { workspace = true }
|
|
# Artwork download + cache + (Linux) resize for the notification icon. Matches
|
|
# the Tauri notification helpers so output is identical.
|
|
reqwest = { workspace = true, features = ["blocking"] }
|
|
image = { version = "0.25", default-features = false, features = [
|
|
"png",
|
|
"jpeg",
|
|
"webp",
|
|
] }
|
|
dirs = "6"
|
|
md-5 = { workspace = true }
|
|
urlencoding = "2"
|
|
|
|
# Linux: mpris-server publishes the full MPRIS interface INCLUDING the
|
|
# org.mpris.MediaPlayer2.DesktopEntry property (RootInterface::desktop_entry),
|
|
# which is the only way GNOME Shell resolves the app icon. souvlaki never sets
|
|
# it. tokio feature so the server shares the app's tokio runtime.
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
mpris-server = "0.8"
|
|
async-channel = "2"
|
|
# XDG notification portal (goes over D-Bus). Same crate + tokio runtime the
|
|
# secret portal already pulls in (qbz-credentials uses ashpd 0.13/tokio).
|
|
ashpd = { version = "0.13", default-features = false, features = [
|
|
"tokio",
|
|
"notification",
|
|
] }
|
|
|
|
# macOS (MediaRemote / MPNowPlayingInfoCenter) + Windows (SMTC) via souvlaki —
|
|
# there is no DesktopEntry concept there (macOS keys the icon off the app
|
|
# bundle), so souvlaki stays the right tool off-Linux.
|
|
[target.'cfg(any(target_os = "macos", target_os = "windows"))'.dependencies]
|
|
souvlaki = "0.8"
|
|
# macOS desktop notifications (NSUserNotification / UserNotifications). Windows
|
|
# is a no-op for now (parity with Tauri, which never implemented it).
|
|
notify-rust = "4"
|