From acc6e05bdccda78752e8c10e003047410db5e939 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Sun, 20 Mar 2022 01:36:43 +0800
Subject: [PATCH] feat: system tray supports system proxy setting

---
 src-tauri/src/cmds.rs          | 11 +++++++++
 src-tauri/src/main.rs          | 42 ++++++++++++++++++++++++++++------
 src-tauri/src/utils/resolve.rs |  7 ++++++
 src/pages/_layout.tsx          |  3 +++
 4 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index 774ebd5..88f250f 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -280,11 +280,13 @@ pub fn get_verge_config(verge_state: State<'_, VergeState>) -> Result<VergeConfi
 #[tauri::command]
 pub fn patch_verge_config(
   payload: VergeConfig,
+  app_handle: tauri::AppHandle,
   clash_state: State<'_, ClashState>,
   verge_state: State<'_, VergeState>,
   profiles_state: State<'_, ProfilesState>,
 ) -> Result<(), String> {
   let tun_mode = payload.enable_tun_mode.clone();
+  let system_proxy = payload.enable_system_proxy.clone();
 
   // change tun mode
   if tun_mode.is_some() {
@@ -299,6 +301,15 @@ 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();
+  }
+
   Ok(())
 }
 
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index de62bfa..fb09191 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -8,7 +8,10 @@ mod core;
 mod states;
 mod utils;
 
-use crate::utils::{resolve, server};
+use crate::{
+  core::VergeConfig,
+  utils::{resolve, server},
+};
 use tauri::{
   api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
 };
@@ -21,6 +24,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("restart_clash", "Restart Clash"))
     .add_native_item(SystemTrayMenuItem::Separator)
     .add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"));
@@ -40,6 +44,31 @@ fn main() -> std::io::Result<()> {
           window.show().unwrap();
           window.set_focus().unwrap();
         }
+        "system_proxy" => {
+          let verge_state = app_handle.state::<states::VergeState>();
+          let mut verge = verge_state.0.lock().unwrap();
+
+          let old_value = verge.config.enable_system_proxy.clone().unwrap_or(false);
+          let new_value = !old_value;
+
+          match verge.patch_config(VergeConfig {
+            enable_system_proxy: Some(new_value),
+            ..VergeConfig::default()
+          }) {
+            Ok(_) => {
+              app_handle
+                .tray_handle()
+                .get_item(id.as_str())
+                .set_selected(new_value)
+                .unwrap();
+
+              // update verge config
+              let window = app_handle.get_window("main").unwrap();
+              window.emit("verge://refresh-verge-config", "yes").unwrap();
+            }
+            Err(err) => log::error!("{err}"),
+          }
+        }
         "restart_clash" => {
           let clash_state = app_handle.state::<states::ClashState>();
           let profiles_state = app_handle.state::<states::ProfilesState>();
@@ -55,13 +84,12 @@ fn main() -> std::io::Result<()> {
         }
         _ => {}
       },
+      #[cfg(target_os = "windows")]
       SystemTrayEvent::LeftClick { .. } => {
-        if cfg![target_os = "windows"] {
-          let window = app_handle.get_window("main").unwrap();
-          window.unminimize().unwrap();
-          window.show().unwrap();
-          window.set_focus().unwrap();
-        }
+        let window = app_handle.get_window("main").unwrap();
+        window.unminimize().unwrap();
+        window.show().unwrap();
+        window.set_focus().unwrap();
       }
       _ => {}
     })
diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs
index 601c43d..16a7129 100644
--- a/src-tauri/src/utils/resolve.rs
+++ b/src-tauri/src/utils/resolve.rs
@@ -39,6 +39,13 @@ pub fn resolve_setup(app: &App) {
   }
 
   log_if_err!(verge.init_launch());
+
+  verge.config.enable_system_proxy.map(|enable| {
+    log_if_err!(app
+      .tray_handle()
+      .get_item("system_proxy")
+      .set_selected(enable));
+  });
 }
 
 /// reset system proxy
diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx
index e32a7c1..d22a41d 100644
--- a/src/pages/_layout.tsx
+++ b/src/pages/_layout.tsx
@@ -41,6 +41,9 @@ const Layout = () => {
       mutate("getProxies");
       mutate("getClashConfig");
     });
+
+    // update the verge config
+    listen("verge://refresh-verge-config", () => mutate("getVergeConfig"));
   }, []);
 
   useEffect(() => {
-- 
GitLab