diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index 86b8fdf21..bc8d8df03 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -37,97 +37,74 @@ const TRAY_CLICK_DEBOUNCE_MS: u64 = 300; #[derive(Clone)] struct TrayState {} +enum IconKind { + Common, + SysProxy, + Tun, +} + pub struct Tray { limiter: SystemLimiter, } impl TrayState { async fn get_tray_icon(verge: &IVerge) -> (bool, Vec) { - let system_mode = verge.enable_system_proxy.as_ref().unwrap_or(&false); - let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false); - match (*system_mode, *tun_mode) { - (true, true) => Self::get_tun_tray_icon(verge).await, - (true, false) => Self::get_sysproxy_tray_icon(verge).await, - (false, true) => Self::get_tun_tray_icon(verge).await, - (false, false) => Self::get_common_tray_icon(verge).await, - } + let tun_mode = verge.enable_tun_mode.unwrap_or(false); + let system_mode = verge.enable_system_proxy.unwrap_or(false); + let kind = if tun_mode { + IconKind::Tun + } else if system_mode { + IconKind::SysProxy + } else { + IconKind::Common + }; + Self::load_icon(verge, kind).await } - async fn get_common_tray_icon(verge: &IVerge) -> (bool, Vec) { - let is_common_tray_icon = verge.common_tray_icon.unwrap_or(false); - if is_common_tray_icon - && let Ok(Some(common_icon_path)) = find_target_icons("common") - && let Ok(icon_data) = fs::read(common_icon_path).await + async fn load_icon(verge: &IVerge, kind: IconKind) -> (bool, Vec) { + let (custom_enabled, icon_name) = match kind { + IconKind::Common => (verge.common_tray_icon.unwrap_or(false), "common"), + IconKind::SysProxy => (verge.sysproxy_tray_icon.unwrap_or(false), "sysproxy"), + IconKind::Tun => (verge.tun_tray_icon.unwrap_or(false), "tun"), + }; + + if custom_enabled + && let Ok(Some(path)) = find_target_icons(icon_name) + && let Ok(data) = fs::read(path).await { - return (true, icon_data); - } - #[cfg(target_os = "macos")] - { - let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); - if tray_icon_colorful == "monochrome" { - (false, include_bytes!("../../../icons/tray-icon-mono.ico").to_vec()) - } else { - (false, include_bytes!("../../../icons/tray-icon.ico").to_vec()) - } + return (true, data); } - #[cfg(not(target_os = "macos"))] - { - (false, include_bytes!("../../../icons/tray-icon.ico").to_vec()) - } + Self::default_icon(verge, kind) } - async fn get_sysproxy_tray_icon(verge: &IVerge) -> (bool, Vec) { - let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.unwrap_or(false); - if is_sysproxy_tray_icon - && let Ok(Some(sysproxy_icon_path)) = find_target_icons("sysproxy") - && let Ok(icon_data) = fs::read(sysproxy_icon_path).await - { - return (true, icon_data); - } + fn default_icon(verge: &IVerge, kind: IconKind) -> (bool, Vec) { #[cfg(target_os = "macos")] { - let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); - if tray_icon_colorful == "monochrome" { - ( + let is_mono = verge.tray_icon.as_deref().unwrap_or("monochrome") == "monochrome"; + if is_mono { + return ( false, - include_bytes!("../../../icons/tray-icon-sys-mono-new.ico").to_vec(), - ) - } else { - (false, include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()) + match kind { + IconKind::Common => include_bytes!("../../../icons/tray-icon-mono.ico").to_vec(), + IconKind::SysProxy => include_bytes!("../../../icons/tray-icon-sys-mono-new.ico").to_vec(), + IconKind::Tun => include_bytes!("../../../icons/tray-icon-tun-mono-new.ico").to_vec(), + }, + ); } } #[cfg(not(target_os = "macos"))] - { - (false, include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()) - } - } + let _ = verge; - async fn get_tun_tray_icon(verge: &IVerge) -> (bool, Vec) { - let is_tun_tray_icon = verge.tun_tray_icon.unwrap_or(false); - if is_tun_tray_icon - && let Ok(Some(tun_icon_path)) = find_target_icons("tun") - && let Ok(icon_data) = fs::read(tun_icon_path).await - { - return (true, icon_data); - } - #[cfg(target_os = "macos")] - { - let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); - if tray_icon_colorful == "monochrome" { - ( - false, - include_bytes!("../../../icons/tray-icon-tun-mono-new.ico").to_vec(), - ) - } else { - (false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()) - } - } - #[cfg(not(target_os = "macos"))] - { - (false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()) - } + ( + false, + match kind { + IconKind::Common => include_bytes!("../../../icons/tray-icon.ico").to_vec(), + IconKind::SysProxy => include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(), + IconKind::Tun => include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(), + }, + ) } } @@ -248,34 +225,6 @@ impl Tray { } /// 更新托盘图标 - #[cfg(target_os = "macos")] - pub async fn update_icon(&self, verge: &IVerge) -> Result<()> { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Tray, "应用正在退出,跳过托盘图标更新"); - return Ok(()); - } - - let app_handle = handle::Handle::app_handle(); - - let Some(tray) = app_handle.tray_by_id("main") else { - logging!(warn, Type::Tray, "Failed to update tray icon: tray not found"); - return Ok(()); - }; - - let (_is_custom_icon, icon_bytes) = TrayState::get_tray_icon(verge).await; - - let colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); - let is_colorful = colorful == "colorful"; - - logging_error!( - Type::Tray, - tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?)) - ); - logging_error!(Type::Tray, tray.set_icon_as_template(!is_colorful)); - Ok(()) - } - - #[cfg(not(target_os = "macos"))] pub async fn update_icon(&self, verge: &IVerge) -> Result<()> { if handle::Handle::global().is_exiting() { logging!(debug, Type::Tray, "应用正在退出,跳过托盘图标更新"); @@ -295,6 +244,13 @@ impl Tray { Type::Tray, tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?)) ); + + #[cfg(target_os = "macos")] + { + let is_colorful = verge.tray_icon.as_deref().unwrap_or("monochrome") == "colorful"; + logging_error!(Type::Tray, tray.set_icon_as_template(!is_colorful)); + } + Ok(()) } @@ -373,6 +329,12 @@ impl Tray { Ok(()) } + pub async fn update_menu_and_icon(&self) { + logging_error!(Type::Tray, self.update_menu().await); + let verge = Config::verge().await.data_arc(); + logging_error!(Type::Tray, self.update_icon(&verge).await); + } + async fn create_tray_from_handle(&self, app_handle: &AppHandle) -> Result<()> { if handle::Handle::global().is_exiting() { logging!(debug, Type::Tray, "应用正在退出,跳过托盘创建"); diff --git a/src-tauri/src/feat/clash.rs b/src-tauri/src/feat/clash.rs index 909cfbb04..fe2de5c9b 100644 --- a/src-tauri/src/feat/clash.rs +++ b/src-tauri/src/feat/clash.rs @@ -5,7 +5,7 @@ use crate::{ process::AsyncHandler, utils::{self, resolve::reset_resolve_done}, }; -use clash_verge_logging::{Type, logging, logging_error}; +use clash_verge_logging::{Type, logging}; use serde_yaml_ng::{Mapping, Value}; use smartstring::alias::String; @@ -86,13 +86,7 @@ pub async fn change_clash_mode(mode: String) { let clash_data = clash.data_arc(); if clash_data.save_config().await.is_ok() { handle::Handle::refresh_clash(); - logging_error!(Type::Tray, tray::Tray::global().update_menu().await); - logging_error!( - Type::Tray, - tray::Tray::global() - .update_icon(&Config::verge().await.data_arc()) - .await - ); + tray::Tray::global().update_menu_and_icon().await; } let is_auto_close_connection = Config::verge().await.data_arc().auto_close_connection.unwrap_or(false); diff --git a/src-tauri/src/feat/config.rs b/src-tauri/src/feat/config.rs index aee64e427..4f21743d9 100644 --- a/src-tauri/src/feat/config.rs +++ b/src-tauri/src/feat/config.rs @@ -20,13 +20,7 @@ pub async fn patch_clash(patch: &Mapping) -> Result<()> { CoreManager::global().restart_core().await?; } else { if patch.get("mode").is_some() { - logging_error!(Type::Tray, tray::Tray::global().update_menu().await); - logging_error!( - Type::Tray, - tray::Tray::global() - .update_icon(&Config::verge().await.data_arc()) - .await - ); + tray::Tray::global().update_menu_and_icon().await; } Config::runtime().await.edit_draft(|d| d.patch_config(patch)); CoreManager::global().update_config().await?;