about tray and silent startup + automatic startup light repair and optimization (#3814)

* fixed the issue that the tray does not display in light mode

* add show main window after exiting light mode

* fix: the issue where other selections could not respond in real time

* Refactored the original silent + self-starting lightweight #3708

* update logs

* fix formatting issues

* fix

* fix nesting

* repair previous formatting issues

* fix: resolve issue with tray not restoring from lightweight mode

* remove the tray display that should not exist

* fix translation field issue

---------

Co-authored-by: Ahao <108321411+xuanyuan0408@users.noreply.github.com>
Co-authored-by: Tunglies <selenvow+github@gmail.com>
This commit is contained in:
Just want to protect you
2025-06-18 20:00:33 +08:00
committed by GitHub
Unverified
parent 1f9ba4de5c
commit 623461b649
5 changed files with 117 additions and 48 deletions

View File

@@ -6,11 +6,18 @@
- 修复扩展脚本转义错误
- 修复 macOS Intel X86 架构构建错误导致无法运行
- 修复 Linux 下界面边框白边问题
- 修复 托盘 无响应问题
- 修复 托盘 无法从轻量模式退出并恢复窗口
### ✨ 新增功能
- 新增 window-state 窗口状态管理和恢复
### 🚀 优化改进
- 优化 托盘 统一响应
- 优化 静默启动+自启动轻量模式 运行方式
## v2.3.0
**发行代号:御**

View File

@@ -6,10 +6,7 @@ use crate::{
cmd,
config::Config,
feat, logging,
module::{
lightweight::{entry_lightweight_mode, is_in_lightweight_mode},
mihomo::Rate,
},
module::{lightweight::is_in_lightweight_mode, mihomo::Rate},
utils::{dirs::find_target_icons, i18n::t, resolve::VERSION},
Type,
};
@@ -204,33 +201,38 @@ impl Tray {
Ok(())
}
/// 更新托盘菜单(带频率限制)
/// 更新托盘菜单
pub fn update_menu(&self) -> Result<()> {
// 检查是否正在更新或距离上次更新太近
const MIN_UPDATE_INTERVAL: Duration = Duration::from_millis(500);
// 调整最小更新间隔,确保状态及时刷新
const MIN_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
// 检查是否已有更新任务在执行
// 检查是否正在更新
if self.menu_updating.load(Ordering::Acquire) {
log::debug!(target: "app", "托盘菜单正在更新中,跳过本次更新");
return Ok(());
}
// 检查更新频率
{
let last_update = self.last_menu_update.lock();
if let Some(last_time) = *last_update {
if last_time.elapsed() < MIN_UPDATE_INTERVAL {
log::debug!(target: "app", "托盘菜单更新频率过高,跳过本次更新");
return Ok(());
// 检查更新频率,但允许重要事件跳过频率限制
let should_force_update = match std::thread::current().name() {
Some("main") => true,
_ => {
let last_update = self.last_menu_update.lock();
if let Some(last_time) = *last_update {
last_time.elapsed() >= MIN_UPDATE_INTERVAL
} else {
true
}
}
};
if !should_force_update {
return Ok(());
}
let app_handle = match handle::Handle::global().app_handle() {
Some(handle) => handle,
None => {
log::warn!(target: "app", "更新托盘菜单失败: app_handle不存在");
return Ok(()); // 早期返回避免panic
return Ok(());
}
};
@@ -247,6 +249,7 @@ impl Tray {
result
}
fn update_menu_internal(&self, app_handle: &AppHandle) -> Result<()> {
let verge = Config::verge().latest().clone();
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
@@ -394,6 +397,17 @@ impl Tray {
Ok(())
}
/// 更新托盘显示状态的函数
pub fn update_tray_display(&self) -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let _tray = app_handle.tray_by_id("main").unwrap();
// 更新菜单
self.update_menu()?;
Ok(())
}
/// 更新托盘提示
pub fn update_tooltip(&self) -> Result<()> {
let app_handle = match handle::Handle::global().app_handle() {
@@ -456,6 +470,8 @@ impl Tray {
self.update_menu()?;
self.update_icon(None)?;
self.update_tooltip()?;
// 更新轻量模式显示状态
self.update_tray_display()?;
Ok(())
}
@@ -669,6 +685,17 @@ impl Tray {
log::info!(target: "app", "系统托盘创建成功");
Ok(())
}
// 托盘统一的状态更新函数
pub fn update_all_states(&self) -> Result<()> {
// 确保所有状态更新完成
self.update_menu()?;
self.update_icon(None)?;
self.update_tooltip()?;
self.update_tray_display()?;
Ok(())
}
}
fn create_tray_menu(
@@ -931,8 +958,12 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
let result = WindowManager::show_main_window();
log::info!(target: "app", "窗口显示结果: {:?}", result);
}
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(None),
"system_proxy" => {
feat::toggle_system_proxy();
}
"tun_mode" => {
feat::toggle_tun_mode(None);
}
"copy_env" => feat::copy_clash_env(),
"open_app_dir" => {
let _ = cmd::open_app_dir();
@@ -945,7 +976,22 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
}
"restart_clash" => feat::restart_clash_core(),
"restart_app" => feat::restart_app(),
"entry_lightweight_mode" => entry_lightweight_mode(),
"entry_lightweight_mode" => {
// 处理轻量模式的切换
let was_lightweight = crate::module::lightweight::is_in_lightweight_mode();
if was_lightweight {
crate::module::lightweight::exit_lightweight_mode();
} else {
crate::module::lightweight::entry_lightweight_mode();
}
// 退出轻量模式后显示主窗口
if was_lightweight {
use crate::utils::window_manager::WindowManager;
let result = WindowManager::show_main_window();
log::info!(target: "app", "退出轻量模式后显示主窗口: {:?}", result);
}
}
"quit" => {
feat::quit();
}
@@ -955,4 +1001,9 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
}
_ => {}
}
// 统一调用状态更新
if let Err(e) = Tray::global().update_all_states() {
log::warn!(target: "app", "更新托盘状态失败: {}", e);
}
}

View File

@@ -1,6 +1,6 @@
use crate::{
config::Config,
core::{handle, timer::Timer},
core::{handle, timer::Timer, tray::Tray},
log_err, logging,
state::lightweight::LightWeightState,
utils::logging::Type,
@@ -30,39 +30,44 @@ where
pub fn run_once_auto_lightweight() {
LightWeightState::default().run_once_time(|| {
let is_silent_start = Config::verge().data().enable_silent_start.unwrap_or(false);
let is_silent_start = Config::verge().data().enable_silent_start.unwrap_or(true);
let enable_auto = Config::verge()
.data()
.enable_auto_light_weight_mode
.unwrap_or(false);
.unwrap_or(true);
if enable_auto && is_silent_start {
logging!(
info,
Type::Lightweight,
true,
"Add timer listener when creating window in silent start mode"
"正常创建窗口和添加定时器监听器"
);
set_lightweight_mode(true);
enable_auto_light_weight_mode();
set_lightweight_mode(false);
disable_auto_light_weight_mode();
// 触发托盘更新
if let Err(e) = Tray::global().update_part() {
log::warn!("Failed to update tray: {}", e);
}
}
});
}
pub fn auto_lightweight_mode_init() {
if let Some(app_handle) = handle::Handle::global().app_handle() {
// 通过 app_handle.state 保证同步
let _ = app_handle.state::<Mutex<LightWeightState>>();
let is_silent_start = { Config::verge().data().enable_silent_start }.unwrap_or(false);
let enable_auto = { Config::verge().data().enable_auto_light_weight_mode }.unwrap_or(false);
if enable_auto && !is_silent_start {
logging!(
info,
Type::Lightweight,
true,
"Add timer listener when creating window normally"
);
if enable_auto && is_silent_start {
logging!(info, Type::Lightweight, true, "自动轻量模式静默启动");
set_lightweight_mode(true);
enable_auto_light_weight_mode();
// 确保托盘状态更新
if let Err(e) = Tray::global().update_part() {
log::warn!("Failed to update tray: {}", e);
}
}
}
}
@@ -77,6 +82,11 @@ fn set_lightweight_mode(value: bool) {
with_lightweight_status(|state| {
state.set_lightweight_mode(value);
});
// 触发托盘更新
if let Err(e) = Tray::global().update_part() {
log::warn!("Failed to update tray: {}", e);
}
}
pub fn enable_auto_light_weight_mode() {
@@ -114,6 +124,9 @@ pub fn entry_lightweight_mode() {
}
set_lightweight_mode(true);
let _ = cancel_light_weight_timer();
// 更新托盘显示
let _tray = crate::core::tray::Tray::global();
}
// 添加从轻量模式恢复的函数
@@ -133,6 +146,9 @@ pub fn exit_lightweight_mode() {
// 重置UI就绪状态
crate::utils::resolve::reset_ui_ready();
// 更新托盘显示
let _tray = crate::core::tray::Tray::global();
}
#[cfg(target_os = "macos")]

View File

@@ -293,12 +293,7 @@ pub fn create_window(is_show: bool) -> bool {
);
if !is_show {
logging!(
info,
Type::Window,
true,
"Not to create window when starting in silent mode"
);
logging!(info, Type::Window, true, "静默模式启动时不创建窗口");
handle::Handle::notify_startup_completed();
return false;
}
@@ -364,7 +359,7 @@ pub fn create_window(is_show: bool) -> bool {
console.log('[Tauri] 加载指示器已存在');
return;
}
console.log('[Tauri] 创建加载指示器');
const loadingDiv = document.createElement('div');
loadingDiv.id = 'initial-loading-overlay';
@@ -372,15 +367,15 @@ pub fn create_window(is_show: bool) -> bool {
<div style="
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: var(--bg-color, #f5f5f5); color: var(--text-color, #333);
display: flex; flex-direction: column; align-items: center;
justify-content: center; z-index: 9999;
display: flex; flex-direction: column; align-items: center;
justify-content: center; z-index: 9999;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
transition: opacity 0.3s ease;
">
<div style="margin-bottom: 20px;">
<div style="
width: 40px; height: 40px; border: 3px solid #e3e3e3;
border-top: 3px solid #3498db; border-radius: 50%;
width: 40px; height: 40px; border: 3px solid #e3e3e3;
border-top: 3px solid #3498db; border-radius: 50%;
animation: spin 1s linear infinite;
"></div>
</div>
@@ -415,7 +410,7 @@ pub fn create_window(is_show: bool) -> bool {
} else {
createLoadingOverlay();
}
console.log('[Tauri] 窗口初始化脚本执行完成');
"#,
)

View File

@@ -603,8 +603,8 @@
"Proxy Mode": "代理模式",
"Group": "代理组",
"Proxy": "节点",
"IP Information Card": "IP信息卡",
"IP Information": "IP信息",
"IP Information Card": "IP 信息卡",
"IP Information": "IP 信息",
"Failed to get IP info": "获取IP信息失败",
"ISP": "服务商",
"ASN": "自治域",