diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index bf1e852ca66d4eae293c3e5e130df1df4eb42d0d..bafc1188cc4cf58fbf5024b0f0ef332c3c6fee9f 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -337,15 +337,6 @@ pub fn patch_verge_config(
   let mut verge = verge_state.0.lock().unwrap();
   wrap_err!(verge.patch_config(payload))?;
 
-  // change system tray
-  if system_proxy.is_some() {
-    app_handle
-      .tray_handle()
-      .get_item("system_proxy")
-      .set_selected(system_proxy.unwrap())
-      .unwrap();
-  }
-
   // change tun mode
   if tun_mode.is_some() {
     #[cfg(target_os = "windows")]
@@ -363,6 +354,11 @@ pub fn patch_verge_config(
     wrap_err!(clash.activate_enhanced(&profiles, false, false))?;
   }
 
+  // change system tray
+  if system_proxy.is_some() || tun_mode.is_some() {
+    verge.update_systray(&app_handle).unwrap();
+  }
+
   Ok(())
 }
 
diff --git a/src-tauri/src/core/verge.rs b/src-tauri/src/core/verge.rs
index c2d3d52f2ca385506a6079ac77f9f04146d1b9a9..eaa789c42284e2fd26d1702717f1f7d77ae1f045 100644
--- a/src-tauri/src/core/verge.rs
+++ b/src-tauri/src/core/verge.rs
@@ -8,6 +8,7 @@ use auto_launch::{AutoLaunch, AutoLaunchBuilder};
 use serde::{Deserialize, Serialize};
 use std::sync::Arc;
 use tauri::{async_runtime::Mutex, utils::platform::current_exe};
+use tauri::{AppHandle, Manager};
 
 /// ### `verge.yaml` schema
 #[derive(Default, Debug, Clone, Deserialize, Serialize)]
@@ -291,6 +292,35 @@ impl Verge {
 
     self.config.save_file()
   }
+
+  /// update the system tray state
+  pub fn update_systray(&self, app_handle: &AppHandle) -> Result<()> {
+    // system proxy
+    let system_proxy = self.config.enable_system_proxy.as_ref();
+    system_proxy.map(|system_proxy| {
+      app_handle
+        .tray_handle()
+        .get_item("system_proxy")
+        .set_selected(*system_proxy)
+        .unwrap();
+    });
+
+    // tun mode
+    let tun_mode = self.config.enable_tun_mode.as_ref();
+    tun_mode.map(|tun_mode| {
+      app_handle
+        .tray_handle()
+        .get_item("tun_mode")
+        .set_selected(*tun_mode)
+        .unwrap();
+    });
+
+    // update verge config
+    let window = app_handle.get_window("main").unwrap();
+    window.emit("verge://refresh-verge-config", "yes").unwrap();
+
+    Ok(())
+  }
 }
 
 impl Verge {
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 62707b61eee255e010703e991b4f179edac04bcc..56e9fd9d788521f31fe1e61d9718bb2f5a68ec2c 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -30,6 +30,7 @@ fn main() -> std::io::Result<()> {
   let tray_menu = SystemTrayMenu::new()
     .add_item(CustomMenuItem::new("open_window", "Show"))
     .add_item(CustomMenuItem::new("system_proxy", "System Proxy"))
+    .add_item(CustomMenuItem::new("tun_mode", "Tun Mode"))
     .add_item(CustomMenuItem::new("restart_clash", "Restart Clash"))
     .add_native_item(SystemTrayMenuItem::Separator)
     .add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"));
@@ -60,17 +61,22 @@ fn main() -> std::io::Result<()> {
             enable_system_proxy: Some(new_value),
             ..VergeConfig::default()
           }) {
-            Ok(_) => {
-              app_handle
-                .tray_handle()
-                .get_item(id.as_str())
-                .set_selected(new_value)
-                .unwrap();
+            Ok(_) => verge.update_systray(app_handle).unwrap(),
+            Err(err) => log::error!("{err}"),
+          }
+        }
+        "tun_mode" => {
+          let verge_state = app_handle.state::<states::VergeState>();
+          let mut verge = verge_state.0.lock().unwrap();
 
-              // update verge config
-              let window = app_handle.get_window("main").unwrap();
-              window.emit("verge://refresh-verge-config", "yes").unwrap();
-            }
+          let old_value = verge.config.enable_tun_mode.clone().unwrap_or(false);
+          let new_value = !old_value;
+
+          match verge.patch_config(VergeConfig {
+            enable_tun_mode: Some(new_value),
+            ..VergeConfig::default()
+          }) {
+            Ok(_) => verge.update_systray(app_handle).unwrap(),
             Err(err) => log::error!("{err}"),
           }
         }