From cb816e9653b71a5cade2193da489fa973dc2d511 Mon Sep 17 00:00:00 2001 From: GyDi Date: Fri, 31 Dec 2021 18:24:50 +0800 Subject: [PATCH] feat: support restart sidecar tray event --- src-tauri/src/cmds/some.rs | 22 +++++++++++++++++----- src-tauri/src/events/state.rs | 7 +++++-- src-tauri/src/main.rs | 22 +++++++++++++++++++++- src-tauri/src/utils/clash.rs | 26 ++++++++++++++++++++------ src-tauri/src/utils/resolve.rs | 9 +-------- 5 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src-tauri/src/cmds/some.rs b/src-tauri/src/cmds/some.rs index 291be68..44a89dc 100644 --- a/src-tauri/src/cmds/some.rs +++ b/src-tauri/src/cmds/some.rs @@ -2,7 +2,7 @@ use crate::{ config::VergeConfig, events::{ emit::ClashInfoPayload, - state::{ClashInfoState, VergeConfLock}, + state::{ClashInfoState, ClashSidecarState, VergeConfLock}, }, utils::{ clash::run_clash_bin, @@ -11,13 +11,25 @@ use crate::{ }, }; use serde_yaml::Mapping; -use tauri::{api::process::kill_children, AppHandle, State}; +use tauri::{AppHandle, State}; /// restart the sidecar #[tauri::command] -pub fn restart_sidecar(app_handle: AppHandle, clash_info: State<'_, ClashInfoState>) { - kill_children(); - let payload = run_clash_bin(&app_handle, |_| {}); +pub fn restart_sidecar( + app_handle: AppHandle, + clash_info: State<'_, ClashInfoState>, + clash_sidecar: State<'_, ClashSidecarState>, +) { + { + let mut guard = clash_sidecar.0.lock().unwrap(); + let sidecar = guard.take(); + if sidecar.is_some() { + if let Err(err) = sidecar.unwrap().kill() { + log::error!("failed to restart clash for \"{}\"", err); + } + } + } + let payload = run_clash_bin(&app_handle); if let Ok(mut arc) = clash_info.0.lock() { *arc = payload; diff --git a/src-tauri/src/events/state.rs b/src-tauri/src/events/state.rs index bcdd54e..01b1b30 100644 --- a/src-tauri/src/events/state.rs +++ b/src-tauri/src/events/state.rs @@ -1,7 +1,7 @@ -use std::sync::{Arc, Mutex}; - use super::emit::ClashInfoPayload; use crate::{config::VergeConfig, utils::sysopt::SysProxyConfig}; +use std::sync::{Arc, Mutex}; +use tauri::api::process::CommandChild; #[derive(Default)] pub struct ClashInfoState(pub Arc>); @@ -14,3 +14,6 @@ pub struct VergeConfLock(pub Arc>); #[derive(Default)] pub struct SomthingState(pub Arc>>); + +#[derive(Default)] +pub struct ClashSidecarState(pub Arc>>); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index ef465ad..c425403 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -12,7 +12,7 @@ mod utils; use crate::{ events::state, - utils::{resolve, server}, + utils::{clash, resolve, server}, }; use tauri::{ api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, @@ -26,10 +26,12 @@ fn main() -> std::io::Result<()> { let menu = SystemTrayMenu::new() .add_item(CustomMenuItem::new("open_window", "显示应用")) + .add_item(CustomMenuItem::new("restart_clash", "重启clash")) .add_native_item(SystemTrayMenuItem::Separator) .add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q")); tauri::Builder::default() + .manage(state::ClashSidecarState::default()) .manage(state::VergeConfLock::default()) .manage(state::ClashInfoState::default()) .manage(state::SomthingState::default()) @@ -43,6 +45,24 @@ fn main() -> std::io::Result<()> { window.show().unwrap(); window.set_focus().unwrap(); } + "restart_clash" => { + { + let state = app_handle.state::(); + let mut guard = state.0.lock().unwrap(); + let sidecar = guard.take(); + if sidecar.is_some() { + if let Err(err) = sidecar.unwrap().kill() { + log::error!("failed to restart clash for \"{}\"", err); + } + } + } + + let payload = clash::run_clash_bin(&app_handle); + let state = app_handle.state::(); + if let Ok(mut arc) = state.0.lock() { + *arc = payload; + }; + } "quit" => { api::process::kill_children(); resolve::resolve_reset(app_handle); diff --git a/src-tauri/src/utils/clash.rs b/src-tauri/src/utils/clash.rs index 010882e..77252ac 100644 --- a/src-tauri/src/utils/clash.rs +++ b/src-tauri/src/utils/clash.rs @@ -1,9 +1,12 @@ extern crate log; use crate::{ - events::emit::{clash_start, ClashInfoPayload}, + events::{ + emit::{clash_start, ClashInfoPayload}, + state, + }, utils::{ - app_home_dir, + app_home_dir, clash, config::{read_clash_controller, read_profiles, read_yaml, save_yaml}, }, }; @@ -12,11 +15,11 @@ use serde_yaml::{Mapping, Value}; use std::{collections::HashMap, env::temp_dir}; use tauri::{ api::process::{Command, CommandEvent}, - AppHandle, + AppHandle, Manager, }; /// Run the clash bin -pub fn run_clash_bin(app_handle: &AppHandle, cb: fn(info: ClashInfoPayload)) -> ClashInfoPayload { +pub fn run_clash_bin(app_handle: &AppHandle) -> ClashInfoPayload { let app_dir = app_home_dir(); let app_dir = app_dir.as_os_str().to_str().unwrap(); @@ -35,10 +38,21 @@ pub fn run_clash_bin(app_handle: &AppHandle, cb: fn(info: ClashInfoPayload)) -> }; match result { - Ok((mut rx, _)) => { + Ok((mut rx, cmd_child)) => { log::info!("Successfully execute clash sidecar"); payload.controller = Some(read_clash_controller()); - cb(payload.clone()); // callback when run sidecar successfully + + // update the profile + let payload_ = payload.clone(); + tauri::async_runtime::spawn(async move { + if let Err(err) = clash::put_clash_profile(&payload_).await { + log::error!("failed to put config for `{}`", err); + }; + }); + + if let Ok(mut state) = app_handle.state::().0.lock() { + *state = Some(cmd_child); + }; tauri::async_runtime::spawn(async move { while let Some(event) = rx.recv().await { diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index 5cd1606..8c85853 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -11,14 +11,7 @@ pub fn resolve_setup(app: &App) { init::init_app(app.package_info()); // run clash sidecar - let info = clash::run_clash_bin(&app.handle(), |info_| { - // update the profile - tauri::async_runtime::spawn(async move { - if let Err(err) = clash::put_clash_profile(&info_).await { - log::error!("failed to put config for `{}`", err); - }; - }); - }); + let info = clash::run_clash_bin(&app.handle()); // resolve the verge config - enable system proxy let mut original: Option = None;