diff --git a/src-tauri/src/cmd/lighteweight.rs b/src-tauri/src/cmd/lighteweight.rs index 7afbe0ef..9a2c2755 100644 --- a/src-tauri/src/cmd/lighteweight.rs +++ b/src-tauri/src/cmd/lighteweight.rs @@ -6,10 +6,4 @@ use super::CmdResult; pub async fn entry_lightweight_mode() -> CmdResult { lightweight::entry_lightweight_mode(); Ok(()) -} - -#[tauri::command] -pub async fn exit_lightweight_mode() -> CmdResult { - lightweight::exit_lightweight_mode(); - Ok(()) -} +} \ No newline at end of file diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs index e22ca960..26ad2368 100644 --- a/src-tauri/src/config/verge.rs +++ b/src-tauri/src/config/verge.rs @@ -190,10 +190,10 @@ pub struct IVerge { pub enable_tray_speed: Option, /// 自动进入轻量模式 - pub auto_enter_lite_mode: Option, + pub enable_auto_light_weight_mode: Option, /// 自动进入轻量模式的延迟(分钟) - pub auto_enter_lite_mode_delay: Option, + pub auto_light_weight_minutes: Option, } #[derive(Default, Debug, Clone, Deserialize, Serialize)] @@ -296,8 +296,8 @@ impl IVerge { webdav_password: None, enable_tray_speed: Some(true), enable_global_hotkey: Some(true), - auto_enter_lite_mode: Some(false), - auto_enter_lite_mode_delay: Some(10), + enable_auto_light_weight_mode: Some(false), + auto_light_weight_minutes: Some(10), enable_dns_settings: Some(true), home_cards: None, ..Self::default() @@ -381,8 +381,8 @@ impl IVerge { patch!(webdav_username); patch!(webdav_password); patch!(enable_tray_speed); - patch!(auto_enter_lite_mode); - patch!(auto_enter_lite_mode_delay); + patch!(enable_auto_light_weight_mode); + patch!(auto_light_weight_minutes); patch!(enable_dns_settings); patch!(home_cards); } @@ -473,8 +473,8 @@ pub struct IVergeResponse { pub webdav_username: Option, pub webdav_password: Option, pub enable_tray_speed: Option, - pub auto_enter_lite_mode: Option, - pub auto_enter_lite_mode_delay: Option, + pub enable_auto_light_weight_mode: Option, + pub auto_light_weight_minutes: Option, pub enable_dns_settings: Option, pub home_cards: Option, } @@ -539,8 +539,8 @@ impl From for IVergeResponse { webdav_username: verge.webdav_username, webdav_password: verge.webdav_password, enable_tray_speed: verge.enable_tray_speed, - auto_enter_lite_mode: verge.auto_enter_lite_mode, - auto_enter_lite_mode_delay: verge.auto_enter_lite_mode_delay, + 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, home_cards: verge.home_cards, } diff --git a/src-tauri/src/core/timer.rs b/src-tauri/src/core/timer.rs index 080fdf42..9a38c698 100644 --- a/src-tauri/src/core/timer.rs +++ b/src-tauri/src/core/timer.rs @@ -8,24 +8,25 @@ use std::{collections::HashMap, sync::Arc}; type TaskID = u64; #[derive(Debug, Clone)] -struct TimerTask { - task_id: TaskID, - interval_minutes: u64, - __last_run: i64, // Timestamp of last execution +pub struct TimerTask { + pub task_id: TaskID, + pub interval_minutes: u64, + #[allow(unused)] + pub last_run: i64, // Timestamp of last execution } pub struct Timer { /// cron manager - delay_timer: Arc>, + pub delay_timer: Arc>, /// save the current state - using RwLock for better read concurrency - timer_map: Arc>>, + pub timer_map: Arc>>, /// increment id - kept as mutex since it's just a counter - timer_count: Arc>, + pub timer_count: Arc>, /// Flag to mark if timer is initialized - atomic for better performance - initialized: Arc, + pub initialized: Arc, } impl Timer { @@ -139,7 +140,7 @@ impl Timer { let task = TimerTask { task_id: tid, interval_minutes: interval, - __last_run: chrono::Local::now().timestamp(), + last_run: chrono::Local::now().timestamp(), }; timer_map.insert(uid.clone(), task); @@ -161,7 +162,7 @@ impl Timer { let task = TimerTask { task_id: tid, interval_minutes: interval, - __last_run: chrono::Local::now().timestamp(), + last_run: chrono::Local::now().timestamp(), }; timer_map.insert(uid.clone(), task); diff --git a/src-tauri/src/feat/config.rs b/src-tauri/src/feat/config.rs index 6dd10789..3c01387c 100644 --- a/src-tauri/src/feat/config.rs +++ b/src-tauri/src/feat/config.rs @@ -2,6 +2,7 @@ use crate::{ config::{Config, IVerge}, core::{handle, hotkey, sysopt, tray, CoreManager}, log_err, + module::lightweight, }; use anyhow::Result; use serde_yaml::Mapping; @@ -53,6 +54,7 @@ enum UpdateFlags { SystrayMenu = 1 << 7, SystrayTooltip = 1 << 8, SystrayClickBehavior = 1 << 9, + LighteWeight = 1 << 10, } /// Patch Verge configuration @@ -90,7 +92,7 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> { let enable_global_hotkey = patch.enable_global_hotkey; let tray_event = patch.tray_event; let home_cards = patch.home_cards.clone(); - + let enable_auto_light_weight = patch.enable_auto_light_weight_mode; let res: std::result::Result<(), anyhow::Error> = { // Initialize with no flags set let mut update_flags: i32 = UpdateFlags::None as i32; @@ -156,6 +158,10 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> { update_flags |= UpdateFlags::SystrayClickBehavior as i32; } + if enable_auto_light_weight.is_some() { + update_flags |= UpdateFlags::LighteWeight as i32; + } + // Process updates based on flags if (update_flags & (UpdateFlags::RestartCore as i32)) != 0 { CoreManager::global().restart_core().await?; @@ -189,6 +195,13 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> { if (update_flags & (UpdateFlags::SystrayClickBehavior as i32)) != 0 { tray::Tray::global().update_click_behavior()?; } + if (update_flags & (UpdateFlags::LighteWeight as i32)) != 0 { + if enable_auto_light_weight.unwrap() { + lightweight::enable_auto_light_weight_mode(); + } else { + lightweight::disable_auto_light_weight_mode(); + } + } >::Ok(()) }; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6124f0b7..628089b2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -217,7 +217,6 @@ pub fn run() { cmd::check_media_unlock, // light-weight model cmd::entry_lightweight_mode, - cmd::exit_lightweight_mode, ]); #[cfg(debug_assertions)] diff --git a/src-tauri/src/module/lightweight.rs b/src-tauri/src/module/lightweight.rs index 3c768acd..0f5bca5e 100644 --- a/src-tauri/src/module/lightweight.rs +++ b/src-tauri/src/module/lightweight.rs @@ -1,12 +1,31 @@ -use tauri::Manager; +use anyhow::{Context, Result}; +use delay_timer::prelude::TaskBuilder; +use tauri::{Listener, Manager}; -use crate::{core::handle, log_err, utils::resolve}; +use crate::{ + config::Config, + core::{handle, timer::Timer}, + log_err, +}; +const LIGHT_WEIGHT_TASK_UID: &str = "light_weight_task"; +pub fn enable_auto_light_weight_mode() { + println!("[lightweight_mode] 开启自动轻量模式"); + log::info!(target: "app", "[lightweight_mode] 开启自动轻量模式"); + setup_window_close_listener(); + setup_webview_focus_listener(); +} + +pub fn disable_auto_light_weight_mode() { + println!("[lightweight_mode] 关闭自动轻量模式"); + log::info!(target: "app", "[lightweight_mode] 关闭自动轻量模式"); + let _ = cancel_light_weight_timer(); + cancel_window_close_listener(); +} pub fn entry_lightweight_mode() { - println!("entry_lightweight_mode"); - log::debug!(target: "app", "entry_lightweight_mode"); + println!("尝试进入轻量模式。motherfucker"); if let Some(window) = handle::Handle::global().get_window() { log_err!(window.close()); } @@ -14,12 +33,109 @@ pub fn entry_lightweight_mode() { if let Some(window) = handle::Handle::global().get_window() { if let Some(webview) = window.get_webview_window("main") { log_err!(webview.destroy()); + println!("[lightweight_mode] 轻量模式已开启"); + log::info!(target: "app", "[lightweight_mode] 轻量模式已开启"); } } } -pub fn exit_lightweight_mode() { - println!("exit_lightweight_mode"); - log::debug!(target: "app", "exit_lightweight_mode"); - resolve::create_window(); +fn setup_window_close_listener() -> u32 { + if let Some(window) = handle::Handle::global().get_window() { + let handler = window.listen("tauri://close-requested", move |_event| { + let _ = setup_light_weight_timer(); + println!("[lightweight_mode] 监听到关闭请求,开始轻量模式计时"); + log::info!(target: "app", "[lightweight_mode] 监听到关闭请求,开始轻量模式计时"); + }); + return handler; + } + 0 +} + +fn setup_webview_focus_listener() -> u32 { + if let Some(window) = handle::Handle::global().get_window() { + let handler = window.listen("tauri://focus", move |_event| { + log_err!(cancel_light_weight_timer()); + println!("[lightweight_mode] 监听到窗口获得焦点,取消轻量模式计时"); + log::info!(target: "app", "[lightweight_mode] 监听到窗口获得焦点,取消轻量模式计时"); + }); + return handler; + } + 0 +} + +fn cancel_window_close_listener() { + if let Some(window) = handle::Handle::global().get_window() { + window.unlisten(setup_window_close_listener()); + println!("[lightweight_mode] 取消了窗口关闭监听"); + log::info!(target: "app", "[lightweight_mode] 取消了窗口关闭监听"); + } +} + +fn setup_light_weight_timer() -> Result<()> { + Timer::global().init()?; + + let mut timer_map = Timer::global().timer_map.write(); + let delay_timer = Timer::global().delay_timer.write(); + let mut timer_count = Timer::global().timer_count.lock(); + + let task_id = *timer_count; + *timer_count += 1; + + let once_by_minutes = Config::verge() + .latest() + .auto_light_weight_minutes + .clone() + .unwrap_or(10); + + let task = TaskBuilder::default() + .set_task_id(task_id) + .set_maximum_parallel_runnable_num(1) + .set_frequency_once_by_minutes(once_by_minutes) + .spawn_async_routine(move || async move { + println!("[lightweight_mode] 计时器到期,开始进入轻量模式"); + log::info!(target: "app", + "[lightweight_mode] 计时器到期,开始进入轻量模式" + ); + entry_lightweight_mode(); + }) + .context("failed to create light weight timer task")?; + + delay_timer + .add_task(task) + .context("failed to add light weight timer task")?; + + let timer_task = crate::core::timer::TimerTask { + task_id, + interval_minutes: once_by_minutes, + last_run: chrono::Local::now().timestamp(), + }; + + timer_map.insert(LIGHT_WEIGHT_TASK_UID.to_string(), timer_task); + + println!( + "[lightweight_mode] 轻量模式计时器已设置,{} 分钟后将自动进入轻量模式", + once_by_minutes + ); + log::info!(target: "app", + "[lightweight_mode] 轻量模式计时器已设置,{} 分钟后将自动进入轻量模式", + once_by_minutes + ); + + Ok(()) +} + +fn cancel_light_weight_timer() -> Result<()> { + let mut timer_map = Timer::global().timer_map.write(); + let delay_timer = Timer::global().delay_timer.write(); + + if let Some(task) = timer_map.remove(LIGHT_WEIGHT_TASK_UID) { + delay_timer + .remove_task(task.task_id) + .context("failed to remove light weight timer task")?; + } + + println!("[lightweight_mode] 轻量模式计时器已取消"); + log::info!(target: "app", "[lightweight_mode] 轻量模式计时器已取消"); + + Ok(()) } diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index 97124f0a..80edfaa5 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -1,11 +1,7 @@ #[cfg(target_os = "macos")] use crate::AppHandleManager; use crate::{ - config::{Config, IVerge, PrfItem}, - core::*, - log_err, - utils::{error, init, server}, - wrap_err, + config::{Config, IVerge, PrfItem}, core::*, log_err, module::lightweight, utils::{error, init, server}, wrap_err }; use anyhow::{bail, Result}; use once_cell::sync::OnceCell; @@ -115,6 +111,11 @@ pub async fn resolve_setup(app: &mut App) { log_err!(tray::Tray::global().update_part()); log_err!(timer::Timer::global().init()); + + let enable_auto_light_weight_mode = { Config::verge().data().enable_auto_light_weight_mode }; + if enable_auto_light_weight_mode.unwrap_or(false) { + lightweight::enable_auto_light_weight_mode(); + } } /// reset system proxy diff --git a/src/components/setting/mods/lite-mode-viewer.tsx b/src/components/setting/mods/lite-mode-viewer.tsx index d39bc990..4241425b 100644 --- a/src/components/setting/mods/lite-mode-viewer.tsx +++ b/src/components/setting/mods/lite-mode-viewer.tsx @@ -28,8 +28,8 @@ export const LiteModeViewer = forwardRef((props, ref) => { open: () => { setOpen(true); setValues({ - autoEnterLiteMode: verge?.auto_enter_lite_mode ?? false, - autoEnterLiteModeDelay: verge?.auto_enter_lite_mode_delay ?? 10, + autoEnterLiteMode: verge?.enable_auto_light_weight_mode ?? false, + autoEnterLiteModeDelay: verge?.auto_light_weight_minutes ?? 10, }); }, close: () => setOpen(false), @@ -38,8 +38,8 @@ export const LiteModeViewer = forwardRef((props, ref) => { const onSave = useLockFn(async () => { try { await patchVerge({ - auto_enter_lite_mode: values.autoEnterLiteMode, - auto_enter_lite_mode_delay: values.autoEnterLiteModeDelay, + enable_auto_light_weight_mode: values.autoEnterLiteMode, + auto_light_weight_minutes: values.autoEnterLiteModeDelay, }); setOpen(false); } catch (err: any) { diff --git a/src/services/types.d.ts b/src/services/types.d.ts index fbcecf1b..44cf600e 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -739,8 +739,8 @@ interface IVergeConfig { tun_tray_icon?: boolean; enable_tray_speed?: boolean; enable_tun_mode?: boolean; - auto_enter_lite_mode?: boolean; - auto_enter_lite_mode_delay?: number; + enable_auto_light_weight_mode?: boolean; + auto_light_weight_minutes?: number; enable_auto_launch?: boolean; enable_silent_start?: boolean; enable_system_proxy?: boolean;