From f047960a338004100214aecff3ac11c8578e8625 Mon Sep 17 00:00:00 2001 From: TinsFox Date: Sun, 21 Dec 2025 21:10:00 +0800 Subject: [PATCH] Use macOS tray template icon (#434) --- src-tauri/Cargo.lock | 60 ++++++++++++++++-- src-tauri/Cargo.toml | 2 +- .../tray/macos/statusbar_template_3x.png | Bin 0 -> 2751 bytes src-tauri/src/lib.rs | 40 ++++++++++-- 4 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 src-tauri/icons/tray/macos/statusbar_template_3x.png 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 0000000000000000000000000000000000000000..d56a1da84ab02d85cd49260cf1d5700825b7b9ef GIT binary patch literal 2751 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 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)?;