mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 16:30:52 +08:00
fix: load custom tray icon failed due to #2886
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
use super::CmdResult;
|
||||
use crate::{feat, utils::dirs, wrap_err};
|
||||
use crate::{
|
||||
feat, logging,
|
||||
utils::{dirs, logging::Type},
|
||||
wrap_err,
|
||||
};
|
||||
use tauri::Manager;
|
||||
|
||||
/// 打开应用程序所在目录
|
||||
@@ -194,7 +198,14 @@ pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
|
||||
)
|
||||
.unwrap_or_default();
|
||||
}
|
||||
|
||||
logging!(
|
||||
info,
|
||||
Type::CMD,
|
||||
true,
|
||||
"Copying icon file path: {:?} -> file dist: {:?}",
|
||||
path,
|
||||
dest_path
|
||||
);
|
||||
match fs::copy(file_path, &dest_path) {
|
||||
Ok(_) => Ok(dest_path.to_string_lossy().to_string()),
|
||||
Err(err) => Err(err.to_string()),
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
config::*,
|
||||
core::{
|
||||
handle,
|
||||
service::{self, is_service_available},
|
||||
service::{self},
|
||||
},
|
||||
log_err, logging, logging_error,
|
||||
module::mihomo::MihomoManager,
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
feat,
|
||||
module::{lightweight::entry_lightweight_mode, mihomo::Rate},
|
||||
resolve,
|
||||
utils::{dirs, i18n::t, resolve::VERSION},
|
||||
utils::{dirs::find_target_icons, i18n::t, resolve::VERSION},
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -22,6 +22,7 @@ use parking_lot::RwLock;
|
||||
pub use speed_rate::{SpeedRate, Traffic};
|
||||
#[cfg(target_os = "macos")]
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::fs;
|
||||
#[cfg(target_os = "macos")]
|
||||
use std::hash::{Hash, Hasher};
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -35,6 +36,10 @@ use tauri::{
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use super::handle;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TrayState {}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub struct Tray {
|
||||
pub speed_rate: Arc<Mutex<Option<SpeedRate>>>,
|
||||
@@ -43,10 +48,89 @@ pub struct Tray {
|
||||
pub icon_hash: Arc<Mutex<Option<u64>>>,
|
||||
pub icon_cache: Arc<Mutex<Option<Vec<u8>>>>,
|
||||
pub rate_cache: Arc<Mutex<Option<Rate>>>,
|
||||
// pub tray_state: Arc<Mutex<TrayState>>,
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub struct Tray {}
|
||||
pub struct Tray {
|
||||
pub tray_state: Arc<Mutex<TrayState>>,
|
||||
}
|
||||
|
||||
impl TrayState {
|
||||
pub fn get_common_tray_icon() -> Vec<u8> {
|
||||
let verge = Config::verge().latest().clone();
|
||||
let is_common_tray_icon = verge.common_tray_icon.clone().unwrap_or(false);
|
||||
if is_common_tray_icon {
|
||||
if let Some(common_icon_path) = find_target_icons("common").unwrap() {
|
||||
let icon_data = fs::read(common_icon_path).unwrap();
|
||||
return icon_data;
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||
if tray_icon_colorful == "monochrome" {
|
||||
include_bytes!("../../../icons/tray-icon.ico").to_vec()
|
||||
} else {
|
||||
include_bytes!("../../../icons/tray-icon-mono.ico").to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
include_bytes!("../../../icons/tray-icon.ico").to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_sysproxy_tray_icon() -> Vec<u8> {
|
||||
let verge = Config::verge().latest().clone();
|
||||
let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.clone().unwrap_or(false);
|
||||
if is_sysproxy_tray_icon {
|
||||
if let Some(sysproxy_icon_path) = find_target_icons("sysproxy").unwrap() {
|
||||
let icon_data = fs::read(sysproxy_icon_path).unwrap();
|
||||
return icon_data;
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||
if tray_icon_colorful == "monochrome" {
|
||||
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()
|
||||
} else {
|
||||
include_bytes!("../../../icons/tray-icon-sys-mono.ico").to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_tun_tray_icon() -> Vec<u8> {
|
||||
let verge = Config::verge().latest().clone();
|
||||
let is_tun_tray_icon = verge.tun_tray_icon.clone().unwrap_or(false);
|
||||
if is_tun_tray_icon {
|
||||
if let Some(tun_icon_path) = find_target_icons("tun").unwrap() {
|
||||
let icon_data = fs::read(tun_icon_path).unwrap();
|
||||
return icon_data;
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||
if tray_icon_colorful == "monochrome" {
|
||||
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()
|
||||
} else {
|
||||
include_bytes!("../../../icons/tray-icon-tun-mono.ico").to_vec()
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tray {
|
||||
pub fn global() -> &'static Tray {
|
||||
@@ -159,89 +243,27 @@ impl Tray {
|
||||
}
|
||||
|
||||
/// 更新托盘图标
|
||||
#[allow(unused_variables)]
|
||||
pub fn update_icon(&self, rate: Option<Rate>) -> Result<()> {
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
let verge = Config::verge().latest().clone();
|
||||
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||
let system_mode = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
||||
|
||||
let common_tray_icon = verge.common_tray_icon.as_ref().unwrap_or(&false);
|
||||
let sysproxy_tray_icon = verge.sysproxy_tray_icon.as_ref().unwrap_or(&false);
|
||||
let tun_tray_icon = verge.tun_tray_icon.as_ref().unwrap_or(&false);
|
||||
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
let tray = app_handle.tray_by_id("main").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let tray_icon = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||
|
||||
let icon_bytes = if *system_proxy && !*tun_mode {
|
||||
#[cfg(target_os = "macos")]
|
||||
let mut icon = match tray_icon.as_str() {
|
||||
"colorful" => include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
|
||||
_ => include_bytes!("../../../icons/tray-icon-sys-mono.ico").to_vec(),
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let mut icon = include_bytes!("../../../icons/tray-icon-sys.ico").to_vec();
|
||||
if *sysproxy_tray_icon {
|
||||
let icon_dir_path = dirs::app_home_dir()?.join("icons");
|
||||
let png_path = icon_dir_path.join("sysproxy.png");
|
||||
let ico_path = icon_dir_path.join("sysproxy.ico");
|
||||
if ico_path.exists() {
|
||||
icon = std::fs::read(ico_path).unwrap();
|
||||
} else if png_path.exists() {
|
||||
icon = std::fs::read(png_path).unwrap();
|
||||
}
|
||||
}
|
||||
icon
|
||||
} else if *tun_mode {
|
||||
#[cfg(target_os = "macos")]
|
||||
let mut icon = match tray_icon.as_str() {
|
||||
"colorful" => include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(),
|
||||
_ => include_bytes!("../../../icons/tray-icon-tun-mono.ico").to_vec(),
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let mut icon = include_bytes!("../../../icons/tray-icon-tun.ico").to_vec();
|
||||
if *tun_tray_icon {
|
||||
let icon_dir_path = dirs::app_home_dir()?.join("icons");
|
||||
let png_path = icon_dir_path.join("tun.png");
|
||||
let ico_path = icon_dir_path.join("tun.ico");
|
||||
if ico_path.exists() {
|
||||
icon = std::fs::read(ico_path).unwrap();
|
||||
} else if png_path.exists() {
|
||||
icon = std::fs::read(png_path).unwrap();
|
||||
}
|
||||
}
|
||||
icon
|
||||
} else {
|
||||
#[cfg(target_os = "macos")]
|
||||
let mut icon = match tray_icon.as_str() {
|
||||
"colorful" => include_bytes!("../../../icons/tray-icon.ico").to_vec(),
|
||||
_ => include_bytes!("../../../icons/tray-icon-mono.ico").to_vec(),
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let mut icon = include_bytes!("../../../icons/tray-icon.ico").to_vec();
|
||||
if *common_tray_icon {
|
||||
let icon_dir_path = dirs::app_home_dir()?.join("icons");
|
||||
let png_path = icon_dir_path.join("common.png");
|
||||
let ico_path = icon_dir_path.join("common.ico");
|
||||
if ico_path.exists() {
|
||||
icon = std::fs::read(ico_path).unwrap();
|
||||
} else if png_path.exists() {
|
||||
icon = std::fs::read(png_path).unwrap();
|
||||
}
|
||||
}
|
||||
icon
|
||||
let icon_bytes = match (*system_mode, *tun_mode) {
|
||||
(true, true) => TrayState::get_tun_tray_icon(),
|
||||
(true, false) => TrayState::get_sysproxy_tray_icon(),
|
||||
(false, true) => TrayState::get_tun_tray_icon(),
|
||||
(false, false) => TrayState::get_common_tray_icon(),
|
||||
};
|
||||
|
||||
#[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 colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
|
||||
let is_colorful = colorful == "colorful";
|
||||
|
||||
let icon_hash = {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
|
||||
@@ -77,9 +77,39 @@ pub fn app_profiles_dir() -> Result<PathBuf> {
|
||||
Ok(app_home_dir()?.join("profiles"))
|
||||
}
|
||||
|
||||
/// icons dir
|
||||
pub fn app_icons_dir() -> Result<PathBuf> {
|
||||
Ok(app_home_dir()?.join("icons"))
|
||||
}
|
||||
|
||||
pub fn find_target_icons(target: &str) -> Result<Option<String>> {
|
||||
let icons_dir = app_icons_dir()?;
|
||||
let mut matching_files = Vec::new();
|
||||
|
||||
for entry in fs::read_dir(icons_dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
|
||||
if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) {
|
||||
if file_name.starts_with(target)
|
||||
&& (file_name.ends_with(".ico") || file_name.ends_with(".png"))
|
||||
{
|
||||
matching_files.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matching_files.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
let first = path_to_str(matching_files.first().unwrap())?;
|
||||
Ok(Some(first.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// logs dir
|
||||
pub fn app_logs_dir() -> Result<PathBuf> {
|
||||
Ok(app_home_dir()?.join("logs"))
|
||||
Ok(app_home_dir()?.join("icons"))
|
||||
}
|
||||
|
||||
pub fn clash_path() -> Result<PathBuf> {
|
||||
|
||||
@@ -7,6 +7,7 @@ pub enum Type {
|
||||
Hotkey,
|
||||
Window,
|
||||
Config,
|
||||
CMD,
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
@@ -17,6 +18,7 @@ impl fmt::Display for Type {
|
||||
Type::Hotkey => write!(f, "[Hotkey]"),
|
||||
Type::Window => write!(f, "[Window]"),
|
||||
Type::Config => write!(f, "[Config]"),
|
||||
Type::CMD => write!(f, "[CMD]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user