fix(widget): raise the window via a dedicated deep-link route

Tapping a desktop-widget background activates a tray-only host through
LaunchServices, which never fires the macOS reopen event, so the app
appeared in the Dock without a window. Point the widget tap URL at the
dedicated clash-verge://show route and handle it in the scheme resolver
by raising the main window (including leaving lightweight mode). Bare
and subscription deep links keep their previous behavior.

Signed-off-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
Tunglies
2026-09-14 15:03:41 +08:00
parent e35a239a06
commit a544990f9f
2 changed files with 16 additions and 0 deletions
@@ -195,5 +195,6 @@ struct RoutingView: View {
.environment(\.layoutDirection, rtl ? .rightToLeft : .leftToRight)
.transaction { $0.animation = nil }
.buttonStyle(.plain)
.widgetURL(URL(string: "clash-verge://show"))
}
}
+15
View File
@@ -8,6 +8,8 @@ use crate::{
core::{CoreManager, handle, timer::Timer},
utils::help,
};
#[cfg(target_os = "macos")]
use crate::{module::lightweight, utils::window_manager::WindowManager};
use clash_verge_logging::{Type, logging, logging_error};
pub(super) async fn resolve_scheme(param: &str) -> Result<()> {
@@ -25,6 +27,19 @@ pub(super) async fn resolve_scheme(param: &str) -> Result<()> {
let link_parsed = Url::parse(param_str)
.map_err(|e| anyhow::anyhow!("failed to parse deep link: {e:?}, param: {masked_deep_link}"))?;
// Dedicated "raise the window" route (clash-verge://show) for surfaces that
// activate a tray-only host without firing the macOS reopen event.
#[cfg(target_os = "macos")]
if link_parsed.host_str() == Some("show") {
if lightweight::is_in_lightweight_mode() {
lightweight::exit_lightweight_mode().await;
} else {
handle::Handle::global().set_activation_policy_regular();
WindowManager::show_main_window().await;
}
return Ok(());
}
let Some((url, name)) = extract_subscription_info(&link_parsed) else {
logging!(
warn,