mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-05 05:33:45 +08:00
refactor: simplify tray icon handling and update return types for icon functions
fix: custom tray icon with speedrate display large gap
This commit is contained in:
parent
ce5c86c3b0
commit
70bd5ec03c
@ -6,7 +6,8 @@
|
|||||||
### 2.2.3-alpha 相对于 2.2.2
|
### 2.2.3-alpha 相对于 2.2.2
|
||||||
#### 修复了:
|
#### 修复了:
|
||||||
- 首页“当前代理”因为重复刷新导致的CPU占用过高的问题
|
- 首页“当前代理”因为重复刷新导致的CPU占用过高的问题
|
||||||
- 托盘图标无法自定义
|
- 自定义托盘图标未能应用更改
|
||||||
|
- MacOS 自定义托盘图标显示速率时图标和文本间隙过大
|
||||||
|
|
||||||
#### 新增了:
|
#### 新增了:
|
||||||
- ClashVergeRev 从现在开始不再强依赖系统服务和管理权限
|
- ClashVergeRev 从现在开始不再强依赖系统服务和管理权限
|
||||||
|
@ -20,12 +20,8 @@ use parking_lot::Mutex;
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub use speed_rate::{SpeedRate, Traffic};
|
pub use speed_rate::{SpeedRate, Traffic};
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
use std::collections::hash_map::DefaultHasher;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tauri::{
|
use tauri::{
|
||||||
menu::{CheckMenuItem, IsMenuItem, MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
|
menu::{CheckMenuItem, IsMenuItem, MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
|
||||||
@ -45,10 +41,7 @@ pub struct Tray {
|
|||||||
pub speed_rate: Arc<Mutex<Option<SpeedRate>>>,
|
pub speed_rate: Arc<Mutex<Option<SpeedRate>>>,
|
||||||
shutdown_tx: Arc<RwLock<Option<broadcast::Sender<()>>>>,
|
shutdown_tx: Arc<RwLock<Option<broadcast::Sender<()>>>>,
|
||||||
is_subscribed: Arc<RwLock<bool>>,
|
is_subscribed: Arc<RwLock<bool>>,
|
||||||
pub icon_hash: Arc<Mutex<Option<u64>>>,
|
|
||||||
pub icon_cache: Arc<Mutex<Option<Vec<u8>>>>,
|
|
||||||
pub rate_cache: Arc<Mutex<Option<Rate>>>,
|
pub rate_cache: Arc<Mutex<Option<Rate>>>,
|
||||||
// pub tray_state: Arc<Mutex<TrayState>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
@ -57,77 +50,104 @@ pub struct Tray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TrayState {
|
impl TrayState {
|
||||||
pub fn get_common_tray_icon() -> Vec<u8> {
|
pub fn get_common_tray_icon() -> (bool, Vec<u8>) {
|
||||||
let verge = Config::verge().latest().clone();
|
let verge = Config::verge().latest().clone();
|
||||||
let is_common_tray_icon = verge.common_tray_icon.clone().unwrap_or(false);
|
let is_common_tray_icon = verge.common_tray_icon.clone().unwrap_or(false);
|
||||||
if is_common_tray_icon {
|
if is_common_tray_icon {
|
||||||
if let Some(common_icon_path) = find_target_icons("common").unwrap() {
|
if let Some(common_icon_path) = find_target_icons("common").unwrap() {
|
||||||
let icon_data = fs::read(common_icon_path).unwrap();
|
let icon_data = fs::read(common_icon_path).unwrap();
|
||||||
return icon_data;
|
return (true, icon_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||||
if tray_icon_colorful == "monochrome" {
|
if tray_icon_colorful == "monochrome" {
|
||||||
include_bytes!("../../../icons/tray-icon.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-mono.ico").to_vec(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
include_bytes!("../../../icons/tray-icon-mono.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
include_bytes!("../../../icons/tray-icon.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sysproxy_tray_icon() -> Vec<u8> {
|
pub fn get_sysproxy_tray_icon() -> (bool, Vec<u8>) {
|
||||||
let verge = Config::verge().latest().clone();
|
let verge = Config::verge().latest().clone();
|
||||||
let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.clone().unwrap_or(false);
|
let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.clone().unwrap_or(false);
|
||||||
if is_sysproxy_tray_icon {
|
if is_sysproxy_tray_icon {
|
||||||
if let Some(sysproxy_icon_path) = find_target_icons("sysproxy").unwrap() {
|
if let Some(sysproxy_icon_path) = find_target_icons("sysproxy").unwrap() {
|
||||||
let icon_data = fs::read(sysproxy_icon_path).unwrap();
|
let icon_data = fs::read(sysproxy_icon_path).unwrap();
|
||||||
return icon_data;
|
return (true, icon_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||||
if tray_icon_colorful == "monochrome" {
|
if tray_icon_colorful == "monochrome" {
|
||||||
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-sys-mono.ico").to_vec(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
include_bytes!("../../../icons/tray-icon-sys-mono.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tun_tray_icon() -> Vec<u8> {
|
pub fn get_tun_tray_icon() -> (bool, Vec<u8>) {
|
||||||
let verge = Config::verge().latest().clone();
|
let verge = Config::verge().latest().clone();
|
||||||
let is_tun_tray_icon = verge.tun_tray_icon.clone().unwrap_or(false);
|
let is_tun_tray_icon = verge.tun_tray_icon.clone().unwrap_or(false);
|
||||||
if is_tun_tray_icon {
|
if is_tun_tray_icon {
|
||||||
if let Some(tun_icon_path) = find_target_icons("tun").unwrap() {
|
if let Some(tun_icon_path) = find_target_icons("tun").unwrap() {
|
||||||
let icon_data = fs::read(tun_icon_path).unwrap();
|
let icon_data = fs::read(tun_icon_path).unwrap();
|
||||||
return icon_data;
|
return (true, icon_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||||
if tray_icon_colorful == "monochrome" {
|
if tray_icon_colorful == "monochrome" {
|
||||||
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-tun-mono.ico").to_vec(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
include_bytes!("../../../icons/tray-icon-tun-mono.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()
|
(
|
||||||
|
false,
|
||||||
|
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,8 +161,6 @@ impl Tray {
|
|||||||
speed_rate: Arc::new(Mutex::new(None)),
|
speed_rate: Arc::new(Mutex::new(None)),
|
||||||
shutdown_tx: Arc::new(RwLock::new(None)),
|
shutdown_tx: Arc::new(RwLock::new(None)),
|
||||||
is_subscribed: Arc::new(RwLock::new(false)),
|
is_subscribed: Arc::new(RwLock::new(false)),
|
||||||
icon_hash: Arc::new(Mutex::new(None)),
|
|
||||||
icon_cache: Arc::new(Mutex::new(None)),
|
|
||||||
rate_cache: Arc::new(Mutex::new(None)),
|
rate_cache: Arc::new(Mutex::new(None)),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -251,13 +269,12 @@ impl Tray {
|
|||||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||||
let tray = app_handle.tray_by_id("main").unwrap();
|
let tray = app_handle.tray_by_id("main").unwrap();
|
||||||
|
|
||||||
let icon_bytes = match (*system_mode, *tun_mode) {
|
let (is_custom_icon, icon_bytes) = match (*system_mode, *tun_mode) {
|
||||||
(true, true) => TrayState::get_tun_tray_icon(),
|
(true, true) => TrayState::get_tun_tray_icon(),
|
||||||
(true, false) => TrayState::get_sysproxy_tray_icon(),
|
(true, false) => TrayState::get_sysproxy_tray_icon(),
|
||||||
(false, true) => TrayState::get_tun_tray_icon(),
|
(false, true) => TrayState::get_tun_tray_icon(),
|
||||||
(false, false) => TrayState::get_common_tray_icon(),
|
(false, false) => TrayState::get_common_tray_icon(),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
let enable_tray_speed = verge.enable_tray_speed.unwrap_or(true);
|
let enable_tray_speed = verge.enable_tray_speed.unwrap_or(true);
|
||||||
@ -265,23 +282,8 @@ impl Tray {
|
|||||||
let colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
let colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||||
let is_colorful = colorful == "colorful";
|
let is_colorful = colorful == "colorful";
|
||||||
|
|
||||||
let icon_hash = {
|
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
icon_bytes.clone().hash(&mut hasher);
|
|
||||||
hasher.finish()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut icon_hash_guard = self.icon_hash.lock();
|
|
||||||
let mut icon_bytes_guard = self.icon_cache.lock();
|
|
||||||
if *icon_hash_guard != Some(icon_hash) {
|
|
||||||
*icon_hash_guard = Some(icon_hash);
|
|
||||||
*icon_bytes_guard = Some(icon_bytes.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if !enable_tray_speed {
|
if !enable_tray_speed {
|
||||||
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(
|
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?));
|
||||||
&(*icon_bytes_guard).clone().unwrap(),
|
|
||||||
)?));
|
|
||||||
let _ = tray.set_icon_as_template(!is_colorful);
|
let _ = tray.set_icon_as_template(!is_colorful);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -302,16 +304,20 @@ impl Tray {
|
|||||||
*rate_guard = rate;
|
*rate_guard = rate;
|
||||||
|
|
||||||
let bytes = if enable_tray_icon {
|
let bytes = if enable_tray_icon {
|
||||||
Some(icon_bytes_guard.as_ref().unwrap())
|
Some(icon_bytes)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let rate = rate_guard.as_ref();
|
let rate = rate_guard.as_ref();
|
||||||
let rate_bytes = SpeedRate::add_speed_text(bytes, rate).unwrap();
|
let rate_bytes = SpeedRate::add_speed_text(is_custom_icon, bytes, rate).unwrap();
|
||||||
|
|
||||||
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&rate_bytes)?));
|
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&rate_bytes)?));
|
||||||
let _ = tray.set_icon_as_template(!is_colorful);
|
if !is_custom_icon {
|
||||||
|
let _ = tray.set_icon_as_template(!is_colorful);
|
||||||
|
} else {
|
||||||
|
let _ = tray.set_icon_as_template(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -77,14 +77,15 @@ impl SpeedRate {
|
|||||||
|
|
||||||
// 分离图标加载和速率渲染
|
// 分离图标加载和速率渲染
|
||||||
pub fn add_speed_text<'a>(
|
pub fn add_speed_text<'a>(
|
||||||
icon_bytes: Option<&'a Vec<u8>>,
|
is_custom_icon: bool,
|
||||||
|
icon_bytes: Option<Vec<u8>>,
|
||||||
rate: Option<&'a Rate>,
|
rate: Option<&'a Rate>,
|
||||||
) -> Result<Vec<u8>> {
|
) -> Result<Vec<u8>> {
|
||||||
let rate = rate.unwrap_or(&Rate { up: 0, down: 0 });
|
let rate = rate.unwrap_or(&Rate { up: 0, down: 0 });
|
||||||
|
|
||||||
let (mut icon_width, mut icon_height) = (0, 256);
|
let (mut icon_width, mut icon_height) = (0, 256);
|
||||||
let icon_image = if let Some(bytes) = icon_bytes {
|
let icon_image = if let Some(bytes) = icon_bytes.clone() {
|
||||||
let icon_image = image::load_from_memory(bytes)?;
|
let icon_image = image::load_from_memory(&bytes)?;
|
||||||
icon_width = icon_image.width();
|
icon_width = icon_image.width();
|
||||||
icon_height = icon_image.height();
|
icon_height = icon_image.height();
|
||||||
icon_image
|
icon_image
|
||||||
@ -94,19 +95,16 @@ impl SpeedRate {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 判断是否为彩色图标
|
// 判断是否为彩色图标
|
||||||
let is_colorful = if let Some(bytes) = icon_bytes {
|
let is_colorful = if let Some(bytes) = icon_bytes.clone() {
|
||||||
!crate::utils::help::is_monochrome_image_from_bytes(bytes).unwrap_or(false)
|
!crate::utils::help::is_monochrome_image_from_bytes(&bytes).unwrap_or(false)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
// 增加文本宽度和间距
|
let total_width = if is_custom_icon {
|
||||||
let total_width = if icon_bytes.is_some() {
|
450
|
||||||
if icon_width < 580 {
|
} else if icon_bytes.is_some() {
|
||||||
icon_width + 580
|
icon_width + 580
|
||||||
} else {
|
|
||||||
icon_width
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
580
|
580
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user