Add dual icons for TUN mode with on/off states

Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-01-15 15:13:34 +00:00
parent 861d6d0cd1
commit ffb024ebf5
4 changed files with 55 additions and 12 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -46,10 +46,26 @@ impl TrayState {
async fn get_tray_icon(verge: &IVerge) -> (bool, Vec<u8>) { async fn get_tray_icon(verge: &IVerge) -> (bool, Vec<u8>) {
let system_mode = 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 tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
let tray_event = verge.tray_event.as_deref().unwrap_or("main_window");
// Check if user has set tray to control a specific mode
match tray_event {
"tun_mode" => {
// Always show TUN icons when tray is set to control TUN mode
return Self::get_tun_tray_icon(verge, *tun_mode).await;
}
"system_proxy" => {
// Always show system proxy icons when tray is set to control system proxy
return Self::get_sysproxy_tray_icon(verge, *system_mode).await;
}
_ => {}
}
// Default behavior: prioritize TUN when enabled, then system proxy
match (*system_mode, *tun_mode) { match (*system_mode, *tun_mode) {
(true, true) => Self::get_tun_tray_icon(verge).await, (true, true) => Self::get_tun_tray_icon(verge, true).await,
(true, false) => Self::get_sysproxy_tray_icon(verge).await, (true, false) => Self::get_sysproxy_tray_icon(verge, true).await,
(false, true) => Self::get_tun_tray_icon(verge).await, (false, true) => Self::get_tun_tray_icon(verge, true).await,
(false, false) => Self::get_common_tray_icon(verge).await, (false, false) => Self::get_common_tray_icon(verge).await,
} }
} }
@ -78,7 +94,7 @@ impl TrayState {
} }
} }
async fn get_sysproxy_tray_icon(verge: &IVerge) -> (bool, Vec<u8>) { async fn get_sysproxy_tray_icon(verge: &IVerge, enabled: bool) -> (bool, Vec<u8>) {
let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.unwrap_or(false); let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.unwrap_or(false);
if is_sysproxy_tray_icon if is_sysproxy_tray_icon
&& let Ok(Some(sysproxy_icon_path)) = find_target_icons("sysproxy") && let Ok(Some(sysproxy_icon_path)) = find_target_icons("sysproxy")
@ -86,6 +102,12 @@ impl TrayState {
{ {
return (true, icon_data); return (true, icon_data);
} }
if !enabled {
// When system proxy is disabled, show the common icon
return Self::get_common_tray_icon(verge).await;
}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into());
@ -105,7 +127,7 @@ impl TrayState {
} }
} }
async fn get_tun_tray_icon(verge: &IVerge) -> (bool, Vec<u8>) { async fn get_tun_tray_icon(verge: &IVerge, enabled: bool) -> (bool, Vec<u8>) {
let is_tun_tray_icon = verge.tun_tray_icon.unwrap_or(false); let is_tun_tray_icon = verge.tun_tray_icon.unwrap_or(false);
if is_tun_tray_icon if is_tun_tray_icon
&& let Ok(Some(tun_icon_path)) = find_target_icons("tun") && let Ok(Some(tun_icon_path)) = find_target_icons("tun")
@ -113,21 +135,42 @@ impl TrayState {
{ {
return (true, icon_data); return (true, icon_data);
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into()); let tray_icon_colorful = verge.tray_icon.clone().unwrap_or_else(|| "monochrome".into());
if tray_icon_colorful == "monochrome" { if enabled {
( // TUN mode is enabled - show active icon
false, if tray_icon_colorful == "monochrome" {
include_bytes!("../../../icons/tray-icon-tun-mono-new.ico").to_vec(), (
) false,
include_bytes!("../../../icons/tray-icon-tun-mono-new.ico").to_vec(),
)
} else {
(false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec())
}
} else { } else {
(false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()) // TUN mode is disabled - show inactive/off icon
if tray_icon_colorful == "monochrome" {
(
false,
include_bytes!("../../../icons/tray-icon-tun-off-mono-new.ico").to_vec(),
)
} else {
(false, include_bytes!("../../../icons/tray-icon-tun-off.ico").to_vec())
}
} }
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
{ {
(false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec()) if enabled {
// TUN mode is enabled - show active icon
(false, include_bytes!("../../../icons/tray-icon-tun.ico").to_vec())
} else {
// TUN mode is disabled - show inactive/off icon
(false, include_bytes!("../../../icons/tray-icon-tun-off.ico").to_vec())
}
} }
} }
} }