fix: resolve issue with tray operations after system resume (#6216)

* feat(limiter): add Limiter struct with clock interface and tests

* feat(limiter): integrate Limiter into tray and window management for rate limiting

* fix(tray, window_manager): update debounce timing for tray click and window operations

* refactor(limiter): change time representation from u64 to u128 for improved precision

* fix: resolve issue with tray operations after system resume

* Revert "refactor(limiter): change time representation from u64 to u128 for improved precision"

This reverts commit 2198f40f7f.
This commit is contained in:
Tunglies
2026-01-31 09:23:20 +00:00
committed by GitHub
parent 654152391b
commit ae5d3c478a
8 changed files with 199 additions and 94 deletions
+7 -12
View File
@@ -9,7 +9,7 @@ use crate::{
Type, cmd, config::Config, feat, logging, module::lightweight::is_in_lightweight_mode,
utils::dirs::find_target_icons,
};
use governor::{DefaultDirectRateLimiter, Quota, RateLimiter};
use clash_verge_limiter::{Limiter, SystemClock, SystemLimiter};
use tauri::tray::TrayIconBuilder;
use tauri_plugin_clash_verge_sysinfo::is_current_app_handle_admin;
use tauri_plugin_mihomo::models::Proxies;
@@ -19,7 +19,6 @@ use super::handle;
use anyhow::Result;
use smartstring::alias::String;
use std::collections::HashMap;
use std::num::NonZeroU32;
use std::time::Duration;
use tauri::{
AppHandle, Wry,
@@ -33,13 +32,13 @@ use menu_def::{MenuIds, MenuTexts};
type ProxyMenuItem = (Option<Submenu<Wry>>, Vec<Box<dyn IsMenuItem<Wry>>>);
const TRAY_CLICK_DEBOUNCE_MS: u64 = 1_275;
const TRAY_CLICK_DEBOUNCE_MS: u64 = 300;
#[derive(Clone)]
struct TrayState {}
pub struct Tray {
limiter: DefaultDirectRateLimiter,
limiter: SystemLimiter,
}
impl TrayState {
@@ -136,11 +135,7 @@ impl Default for Tray {
#[allow(clippy::unwrap_used)]
fn default() -> Self {
Self {
limiter: RateLimiter::direct(
Quota::with_period(Duration::from_millis(TRAY_CLICK_DEBOUNCE_MS))
.unwrap()
.allow_burst(NonZeroU32::new(1).unwrap()),
),
limiter: Limiter::new(Duration::from_millis(TRAY_CLICK_DEBOUNCE_MS), SystemClock),
}
}
}
@@ -462,11 +457,11 @@ impl Tray {
}
fn should_handle_tray_click(&self) -> bool {
let res = self.limiter.check().is_ok();
if !res {
let allow = self.limiter.check();
if !allow {
logging!(debug, Type::Tray, "tray click rate limited");
}
res
allow
}
}
+9 -12
View File
@@ -1,8 +1,7 @@
use crate::{core::handle, utils::resolve::window::build_new_window};
use clash_verge_limiter::Limiter;
use clash_verge_logging::{Type, logging};
use governor::{DefaultDirectRateLimiter, Quota, RateLimiter};
use once_cell::sync::Lazy;
use std::num::NonZeroU32;
use std::pin::Pin;
use std::time::Duration;
use tauri::{Manager as _, WebviewWindow, Wry};
@@ -40,22 +39,20 @@ pub enum WindowState {
}
// 窗口操作防抖机制
const WINDOW_OPERATION_DEBOUNCE_MS: u64 = 1_275;
static WINDOW_OPERATION_LIMITER: Lazy<DefaultDirectRateLimiter> = Lazy::new(|| {
#[allow(clippy::unwrap_used)]
RateLimiter::direct(
Quota::with_period(Duration::from_millis(WINDOW_OPERATION_DEBOUNCE_MS))
.unwrap()
.allow_burst(NonZeroU32::new(1).unwrap()),
const WINDOW_OPERATION_DEBOUNCE_MS: u64 = 625;
static WINDOW_OPERATION_LIMITER: Lazy<Limiter> = Lazy::new(|| {
Limiter::new(
Duration::from_millis(WINDOW_OPERATION_DEBOUNCE_MS),
clash_verge_limiter::SystemClock,
)
});
fn should_handle_window_operation() -> bool {
let res = WINDOW_OPERATION_LIMITER.check().is_ok();
if !res {
let allow = WINDOW_OPERATION_LIMITER.check();
if !allow {
logging!(debug, Type::Window, "window operation rate limited");
}
res
allow
}
/// 统一的窗口管理器