From 1a7c076e07bc839bebd89fb7dd0aa3c46dfb2cbb Mon Sep 17 00:00:00 2001 From: Tunglies Date: Sun, 23 Mar 2025 16:37:27 +0800 Subject: [PATCH] feat: add option to enable/disable tray icon display on MacOS --- UPDATELOG.md | 2 + src-tauri/src/config/verge.rs | 6 +++ src-tauri/src/core/tray/mod.rs | 11 ++++- src-tauri/src/core/tray/speed_rate.rs | 46 +++++++++++++------ src-tauri/src/feat/config.rs | 2 + src/components/setting/mods/layout-viewer.tsx | 20 ++++++++ src/locales/en.json | 1 + src/locales/zh.json | 2 + src/services/types.d.ts | 1 + 9 files changed, 75 insertions(+), 16 deletions(-) diff --git a/UPDATELOG.md b/UPDATELOG.md index ef27fc29..e1f27d75 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -30,6 +30,8 @@ 3. **系统** - 在 ClashVergeRev 对 Mihomo 进行操作时,总是尝试确保两者运行 - 服务器模式下启动mihomo内核的时候查找并停止其他已经存在的内核进程,防止内核假死等问题带来的通信失败 +4. **托盘** + - 新增 MacOS 启用托盘速率显示时,可选隐藏托盘图标显示 --- diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs index 26ad2368..c1010cc1 100644 --- a/src-tauri/src/config/verge.rs +++ b/src-tauri/src/config/verge.rs @@ -189,6 +189,8 @@ pub struct IVerge { pub enable_tray_speed: Option, + pub enable_tray_icon: Option, + /// 自动进入轻量模式 pub enable_auto_light_weight_mode: Option, @@ -295,6 +297,7 @@ impl IVerge { webdav_username: None, webdav_password: None, enable_tray_speed: Some(true), + enable_tray_icon: Some(true), enable_global_hotkey: Some(true), enable_auto_light_weight_mode: Some(false), auto_light_weight_minutes: Some(10), @@ -381,6 +384,7 @@ impl IVerge { patch!(webdav_username); patch!(webdav_password); patch!(enable_tray_speed); + patch!(enable_tray_icon); patch!(enable_auto_light_weight_mode); patch!(auto_light_weight_minutes); patch!(enable_dns_settings); @@ -473,6 +477,7 @@ pub struct IVergeResponse { pub webdav_username: Option, pub webdav_password: Option, pub enable_tray_speed: Option, + pub enable_tray_icon: Option, pub enable_auto_light_weight_mode: Option, pub auto_light_weight_minutes: Option, pub enable_dns_settings: Option, @@ -539,6 +544,7 @@ impl From for IVergeResponse { webdav_username: verge.webdav_username, webdav_password: verge.webdav_password, enable_tray_speed: verge.enable_tray_speed, + enable_tray_icon: verge.enable_tray_icon, enable_auto_light_weight_mode: verge.enable_auto_light_weight_mode, auto_light_weight_minutes: verge.auto_light_weight_minutes, enable_dns_settings: verge.enable_dns_settings, diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index 44486707..4df22b44 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -240,6 +240,7 @@ impl Tray { #[cfg(target_os = "macos")] { let enable_tray_speed = verge.enable_tray_speed.unwrap_or(true); + let enable_tray_icon = verge.enable_tray_icon.unwrap_or(true); let is_colorful = tray_icon == "colorful"; let icon_hash = { @@ -255,7 +256,7 @@ impl Tray { *icon_bytes_guard = Some(icon_bytes.clone()); } - if !enable_tray_speed { + if !enable_tray_speed || (!enable_tray_speed && !enable_tray_icon) { let _ = tray.set_icon(Some(tauri::image::Image::from_bytes( &(*icon_bytes_guard).clone().unwrap(), )?)); @@ -278,9 +279,15 @@ impl Tray { if *rate_guard != rate { *rate_guard = rate; - let bytes = icon_bytes_guard.as_ref().unwrap(); + let bytes = if enable_tray_icon { + Some(icon_bytes_guard.as_ref().unwrap()) + } else { + None + }; + let rate = rate_guard.as_ref(); let rate_bytes = SpeedRate::add_speed_text(bytes, rate).unwrap(); + let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&rate_bytes)?)); let _ = tray.set_icon_as_template(!is_colorful); } diff --git a/src-tauri/src/core/tray/speed_rate.rs b/src-tauri/src/core/tray/speed_rate.rs index c37bd7c5..089d8157 100644 --- a/src-tauri/src/core/tray/speed_rate.rs +++ b/src-tauri/src/core/tray/speed_rate.rs @@ -76,33 +76,51 @@ impl SpeedRate { } // 分离图标加载和速率渲染 - pub fn add_speed_text<'a>(icon_bytes: &'a Vec, rate: Option<&'a Rate>) -> Result> { + pub fn add_speed_text<'a>( + icon_bytes: Option<&'a Vec>, + rate: Option<&'a Rate>, + ) -> Result> { let rate = rate.unwrap_or(&Rate { up: 0, down: 0 }); - // 加载原始图标 - let icon_image = image::load_from_memory(icon_bytes)?; - let (icon_width, icon_height) = (icon_image.width(), icon_image.height()); + let (mut icon_width, mut icon_height) = (0, 256); + let icon_image = if let Some(bytes) = icon_bytes { + let icon_image = image::load_from_memory(bytes)?; + icon_width = icon_image.width(); + icon_height = icon_image.height(); + icon_image + } else { + // 返回一个空的 RGBA 图像 + image::DynamicImage::new_rgba8(0, 0) + }; // 判断是否为彩色图标 - let is_colorful = - !crate::utils::help::is_monochrome_image_from_bytes(icon_bytes).unwrap_or(false); + let is_colorful = if let Some(bytes) = icon_bytes { + !crate::utils::help::is_monochrome_image_from_bytes(bytes).unwrap_or(false) + } else { + false + }; // 增加文本宽度和间距 - let total_width = if icon_width < 580 { - let text_width = 580; // 文本区域宽度 - icon_width + text_width + let total_width = if icon_bytes.is_some() { + if icon_width < 580 { + icon_width + 580 + } else { + icon_width + } } else { - icon_width + 580 }; // 创建新的透明画布 let mut combined_image = RgbaImage::new(total_width, icon_height); // 将原始图标绘制到新画布的左侧 - for y in 0..icon_height { - for x in 0..icon_width { - let pixel = icon_image.get_pixel(x, y); - combined_image.put_pixel(x, y, pixel); + if icon_bytes.is_some() { + for y in 0..icon_height { + for x in 0..icon_width { + let pixel = icon_image.get_pixel(x, y); + combined_image.put_pixel(x, y, pixel); + } } } diff --git a/src-tauri/src/feat/config.rs b/src-tauri/src/feat/config.rs index 33d1e7e4..d0a8bea9 100644 --- a/src-tauri/src/feat/config.rs +++ b/src-tauri/src/feat/config.rs @@ -89,6 +89,7 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> { let http_enabled = patch.verge_http_enabled; let http_port = patch.verge_port; let enable_tray_speed = patch.enable_tray_speed; + let enable_tray_icon = patch.enable_tray_icon; let enable_global_hotkey = patch.enable_global_hotkey; let tray_event = patch.tray_event; let home_cards = patch.home_cards.clone(); @@ -145,6 +146,7 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> { || tun_tray_icon.is_some() || tray_icon.is_some() || enable_tray_speed.is_some() + || enable_tray_icon.is_some() { update_flags |= UpdateFlags::SystrayIcon as i32; } diff --git a/src/components/setting/mods/layout-viewer.tsx b/src/components/setting/mods/layout-viewer.tsx index e76706ee..b470b92e 100644 --- a/src/components/setting/mods/layout-viewer.tsx +++ b/src/components/setting/mods/layout-viewer.tsx @@ -198,6 +198,26 @@ export const LayoutViewer = forwardRef((props, ref) => { )} + {OS === "macos" && ( + + + onChangeData({ enable_tray_icon: e })} + onGuard={(e) => patchVerge({ enable_tray_icon: e })} + > + + + + )} diff --git a/src/locales/en.json b/src/locales/en.json index 9ddda072..3fe29177 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -454,6 +454,7 @@ "Global Mode": "Global Mode", "Direct Mode": "Direct Mode", "Enable Tray Speed": "Enable Tray Speed", + "Enable Tray Icon": "Enable Tray Icon", "LightWeight Mode": "Lightweight Mode", "LightWeight Mode Info": "Close the GUI and keep only the kernel running", "LightWeight Mode Settings": "LightWeight Mode Settings", diff --git a/src/locales/zh.json b/src/locales/zh.json index a6b3b586..67bfc65d 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -354,6 +354,7 @@ "toggle_system_proxy": "打开/关闭系统代理", "toggle_tun_mode": "打开/关闭 TUN 模式", "toggle_lightweight_mode": "进入轻量模式", + "entry_lightweight_mode": "进入轻量模式", "Backup Setting": "备份设置", "Backup Setting Info": "支持 WebDAV 备份配置文件", "Runtime Config": "当前配置", @@ -454,6 +455,7 @@ "Global Mode": "全局模式", "Direct Mode": "直连模式", "Enable Tray Speed": "启用托盘速率", + "Enable Tray Icon": "启用托盘图标", "LightWeight Mode": "轻量模式", "LightWeight Mode Info": "关闭GUI界面,仅保留内核运行", "LightWeight Mode Settings": "轻量模式设置", diff --git a/src/services/types.d.ts b/src/services/types.d.ts index 44cf600e..09ae045d 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -738,6 +738,7 @@ interface IVergeConfig { sysproxy_tray_icon?: boolean; tun_tray_icon?: boolean; enable_tray_speed?: boolean; + enable_tray_icon?: boolean; enable_tun_mode?: boolean; enable_auto_light_weight_mode?: boolean; auto_light_weight_minutes?: number;