diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index a19bf1f2b..afa032432 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -586,6 +586,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.10.1" @@ -2214,7 +2220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" dependencies = [ "byteorder", - "png", + "png 0.17.16", ] [[package]] @@ -2330,6 +2336,19 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "image" +version = "0.25.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png 0.18.0", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -2759,6 +2778,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "moxcms" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbdd3d7436f8b5e892b8b7ea114271ff0fa00bc5acae845d53b07d498616ef6" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "muda" version = "0.17.1" @@ -2774,7 +2803,7 @@ dependencies = [ "objc2-core-foundation", "objc2-foundation 0.3.1", "once_cell", - "png", + "png 0.17.16", "serde", "thiserror 2.0.17", "windows-sys 0.60.2", @@ -3563,6 +3592,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.4", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polling" version = "3.11.0" @@ -3694,6 +3736,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pxfm" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" +dependencies = [ + "num-traits", +] + [[package]] name = "quick-xml" version = "0.37.5" @@ -4987,6 +5038,7 @@ dependencies = [ "heck 0.5.0", "http", "http-range", + "image", "jni", "libc", "log", @@ -5055,7 +5107,7 @@ dependencies = [ "ico", "json-patch", "plist", - "png", + "png 0.17.16", "proc-macro2", "quote", "semver", @@ -5810,7 +5862,7 @@ dependencies = [ "objc2-core-graphics", "objc2-foundation 0.3.1", "once_cell", - "png", + "png 0.17.16", "serde", "thiserror 2.0.17", "windows-sys 0.59.0", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 596f59f40..471996b19 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -26,7 +26,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } log = "0.4" chrono = { version = "0.4", features = ["serde"] } -tauri = { version = "2.8.2", features = ["tray-icon", "protocol-asset"] } +tauri = { version = "2.8.2", features = ["tray-icon", "protocol-asset", "image-png"] } tauri-plugin-log = "2" tauri-plugin-opener = "2" tauri-plugin-process = "2" diff --git a/src-tauri/icons/tray/macos/statusbar_template_3x.png b/src-tauri/icons/tray/macos/statusbar_template_3x.png new file mode 100644 index 000000000..d56a1da84 Binary files /dev/null and b/src-tauri/icons/tray/macos/statusbar_template_3x.png differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 3143eb2c8..df50fa0f9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -48,6 +48,8 @@ use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind}; use std::sync::Arc; +#[cfg(target_os = "macos")] +use tauri::image::Image; use tauri::tray::{TrayIconBuilder, TrayIconEvent}; use tauri::RunEvent; use tauri::{Emitter, Manager}; @@ -133,6 +135,19 @@ async fn update_tray_menu( } } +#[cfg(target_os = "macos")] +fn macos_tray_icon() -> Option> { + const ICON_BYTES: &[u8] = include_bytes!("../icons/tray/macos/statusbar_template_3x.png"); + + match Image::from_bytes(ICON_BYTES) { + Ok(icon) => Some(icon), + Err(err) => { + log::warn!("Failed to load macOS tray icon: {err}"); + None + } + } +} + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { let mut builder = tauri::Builder::default(); @@ -503,11 +518,26 @@ pub fn run() { }) .show_menu_on_left_click(true); - // 统一使用应用默认图标;待托盘模板图标就绪后再启用 - if let Some(icon) = app.default_window_icon() { - tray_builder = tray_builder.icon(icon.clone()); - } else { - log::warn!("Failed to get default window icon for tray"); + // 使用平台对应的托盘图标(macOS 使用模板图标适配深浅色) + #[cfg(target_os = "macos")] + { + if let Some(icon) = macos_tray_icon() { + tray_builder = tray_builder.icon(icon).icon_as_template(true); + } else if let Some(icon) = app.default_window_icon() { + log::warn!("Falling back to default window icon for tray"); + tray_builder = tray_builder.icon(icon.clone()); + } else { + log::warn!("Failed to load macOS tray icon for tray"); + } + } + + #[cfg(not(target_os = "macos"))] + { + if let Some(icon) = app.default_window_icon() { + tray_builder = tray_builder.icon(icon.clone()); + } else { + log::warn!("Failed to get default window icon for tray"); + } } let _tray = tray_builder.build(app)?;