feat: add option to enable/disable tray icon display on MacOS

This commit is contained in:
Tunglies 2025-03-23 16:37:27 +08:00
parent da4fddf150
commit 1a7c076e07
9 changed files with 75 additions and 16 deletions

View File

@ -30,6 +30,8 @@
3. **系统**
- 在 ClashVergeRev 对 Mihomo 进行操作时,总是尝试确保两者运行
- 服务器模式下启动mihomo内核的时候查找并停止其他已经存在的内核进程防止内核假死等问题带来的通信失败
4. **托盘**
- 新增 MacOS 启用托盘速率显示时,可选隐藏托盘图标显示
---

View File

@ -189,6 +189,8 @@ pub struct IVerge {
pub enable_tray_speed: Option<bool>,
pub enable_tray_icon: Option<bool>,
/// 自动进入轻量模式
pub enable_auto_light_weight_mode: Option<bool>,
@ -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<String>,
pub webdav_password: Option<String>,
pub enable_tray_speed: Option<bool>,
pub enable_tray_icon: Option<bool>,
pub enable_auto_light_weight_mode: Option<bool>,
pub auto_light_weight_minutes: Option<u64>,
pub enable_dns_settings: Option<bool>,
@ -539,6 +544,7 @@ impl From<IVerge> 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,

View File

@ -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);
}

View File

@ -76,33 +76,51 @@ impl SpeedRate {
}
// 分离图标加载和速率渲染
pub fn add_speed_text<'a>(icon_bytes: &'a Vec<u8>, rate: Option<&'a Rate>) -> Result<Vec<u8>> {
pub fn add_speed_text<'a>(
icon_bytes: Option<&'a Vec<u8>>,
rate: Option<&'a Rate>,
) -> Result<Vec<u8>> {
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);
}
}
}

View File

@ -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;
}

View File

@ -198,6 +198,26 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
</GuardState>
</Item>
)}
{OS === "macos" && (
<Item>
<ListItemText primary={t("Enable Tray Icon")} />
<GuardState
value={
verge?.enable_tray_icon === false &&
verge?.enable_tray_speed === false
? true
: (verge?.enable_tray_icon ?? true)
}
valueProps="checked"
onCatch={onError}
onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_tray_icon: e })}
onGuard={(e) => patchVerge({ enable_tray_icon: e })}
>
<Switch edge="end" />
</GuardState>
</Item>
)}
<Item>
<ListItemText primary={t("Common Tray Icon")} />

View File

@ -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",

View File

@ -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": "轻量模式设置",

View File

@ -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;