From ee89ab8d92666a0d7be2d12bbc1bb9b53b8e1048 Mon Sep 17 00:00:00 2001 From: Tony Date: Sat, 31 Jan 2026 17:22:25 +0800 Subject: [PATCH 1/2] refactor(runtime-wry): remove RefCell hack --- Cargo.lock | 5 +- Cargo.toml | 1 + crates/tauri-runtime-wry/src/lib.rs | 111 +++++++++++++--------------- 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2df411247..961259a85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10916,9 +10916,8 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e456eeaf7f09413fdc16799782879b2b9f1d264dfdbce4cf7e924df0ef36afb9" +version = "0.54.1" +source = "git+https://github.com/Legend-Master/wry.git?branch=new-window-handler-no-send#d76ecad82587b52dd09ff2bf0b75e032f8d06895" dependencies = [ "base64 0.22.1", "block2 0.6.0", diff --git a/Cargo.toml b/Cargo.toml index 670a64767..b6b5d79b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,3 +72,4 @@ schemars_derive = { git = 'https://github.com/tauri-apps/schemars.git', branch = tauri = { path = "./crates/tauri" } tauri-plugin = { path = "./crates/tauri-plugin" } tauri-utils = { path = "./crates/tauri-utils" } +wry = { git = "https://github.com/Legend-Master/wry.git", branch = "new-window-handler-no-send" } diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 61799d039..3c948f0fe 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -3932,13 +3932,9 @@ fn handle_user_message( } } Message::CreateWindow(window_id, handler) => match handler(event_loop) { - // wait for borrow_mut to be available - on Windows we might poll for the window to be inserted - Ok(webview) => loop { - if let Ok(mut windows) = windows.0.try_borrow_mut() { - windows.insert(window_id, webview); - break; - } - }, + Ok(webview) => { + windows.0.borrow_mut().insert(window_id, webview); + } Err(e) => { log::error!("{e}"); } @@ -4716,63 +4712,56 @@ You may have it installed on another user account, but it is not available for t #[cfg(desktop)] let context = context.clone(); webview_builder = webview_builder.with_new_window_req_handler(move |url, features| { - url - .parse() - .map(|url| { - let response = new_window_handler( - url, - tauri_runtime::webview::NewWindowFeatures::new( - features.size, - features.position, - tauri_runtime::webview::NewWindowOpener { - #[cfg(desktop)] - webview: features.opener.webview, - #[cfg(windows)] - environment: features.opener.environment, - #[cfg(target_os = "macos")] - target_configuration: features.opener.target_configuration, - }, - ), - ); - match response { - tauri_runtime::webview::NewWindowResponse::Allow => wry::NewWindowResponse::Allow, + let Ok(url) = url.parse() else { + return wry::NewWindowResponse::Deny; + }; + let response = new_window_handler( + url, + tauri_runtime::webview::NewWindowFeatures::new( + features.size, + features.position, + tauri_runtime::webview::NewWindowOpener { #[cfg(desktop)] - tauri_runtime::webview::NewWindowResponse::Create { window_id } => { - let windows = &context.main_thread.windows.0; - let webview = loop { - if let Some(webview) = windows.try_borrow().ok().and_then(|windows| { - windows - .get(&window_id) - .map(|window| window.webviews.first().unwrap().clone()) - }) { - break webview; - } else { - // on Windows the window is created async so we should wait for it to be available - std::thread::sleep(std::time::Duration::from_millis(50)); - continue; - }; - }; + webview: features.opener.webview, + #[cfg(windows)] + environment: features.opener.environment, + #[cfg(target_os = "macos")] + target_configuration: features.opener.target_configuration, + }, + ), + ); + match response { + tauri_runtime::webview::NewWindowResponse::Allow => wry::NewWindowResponse::Allow, + #[cfg(desktop)] + tauri_runtime::webview::NewWindowResponse::Create { window_id } => { + let windows = &context.main_thread.windows.0; + let webview = windows + .borrow() + .get(&window_id) + .unwrap() + .webviews + .first() + .unwrap() + .clone(); - #[cfg(desktop)] - wry::NewWindowResponse::Create { - #[cfg(target_os = "macos")] - webview: wry::WebViewExtMacOS::webview(&*webview).as_super().into(), - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] - webview: webview.webview(), - #[cfg(windows)] - webview: webview.webview(), - } - } - tauri_runtime::webview::NewWindowResponse::Deny => wry::NewWindowResponse::Deny, + #[cfg(desktop)] + wry::NewWindowResponse::Create { + #[cfg(target_os = "macos")] + webview: wry::WebViewExtMacOS::webview(&*webview).as_super().into(), + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + webview: webview.webview(), + #[cfg(windows)] + webview: webview.webview(), } - }) - .unwrap_or(wry::NewWindowResponse::Deny) + } + tauri_runtime::webview::NewWindowResponse::Deny => wry::NewWindowResponse::Deny, + } }); } From c29c19cb956ec3f7ac28d7649c03b661a58dbbab Mon Sep 17 00:00:00 2001 From: Tony Date: Sat, 31 Jan 2026 17:28:40 +0800 Subject: [PATCH 2/2] Remove `Sync` requirement on `on_new_window` --- crates/tauri-runtime/src/webview.rs | 2 +- crates/tauri/src/webview/mod.rs | 9 ++------- crates/tauri/src/webview/webview_window.rs | 5 +---- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 80f7edf0e..ebe9276dd 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -33,7 +33,7 @@ type WebResourceRequestHandler = type NavigationHandler = dyn Fn(&Url) -> bool + Send; -type NewWindowHandler = dyn Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send + Sync; +type NewWindowHandler = dyn Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send; type OnPageLoadHandler = dyn Fn(Url, PageLoadEvent) + Send; diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index 8842382bf..7890f9705 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -58,8 +58,7 @@ use std::{ pub(crate) type WebResourceRequestHandler = dyn Fn(http::Request>, &mut http::Response>) + Send + Sync; pub(crate) type NavigationHandler = dyn Fn(&Url) -> bool + Send; -pub(crate) type NewWindowHandler = - dyn Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send + Sync; +pub(crate) type NewWindowHandler = dyn Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send; pub(crate) type UriSchemeProtocolHandler = Box>, UriSchemeResponder) + Send + Sync>; pub(crate) type OnPageLoad = dyn Fn(Webview, PageLoadPayload<'_>) + Send + Sync + 'static; @@ -581,12 +580,9 @@ tauri::Builder::default() /// # Platform-specific /// /// - **Android / iOS**: Not supported. - /// - **Windows**: The closure is executed on a separate thread to prevent a deadlock. /// /// [window.open]: https://developer.mozilla.org/en-US/docs/Web/API/Window/open - pub fn on_new_window< - F: Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send + Sync + 'static, - >( + pub fn on_new_window NewWindowResponse + Send + 'static>( mut self, f: F, ) -> Self { @@ -724,7 +720,6 @@ tauri::Builder::default() as Box< dyn Fn(Url, NewWindowFeatures) -> tauri_runtime::webview::NewWindowResponse + Send - + Sync + 'static, > }); diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 290730067..aaf0336ed 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -314,12 +314,9 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { /// # Platform-specific /// /// - **Android / iOS**: Not supported. - /// - **Windows**: The closure is executed on a separate thread to prevent a deadlock. /// /// [window.open]: https://developer.mozilla.org/en-US/docs/Web/API/Window/open - pub fn on_new_window< - F: Fn(Url, NewWindowFeatures) -> NewWindowResponse + Send + Sync + 'static, - >( + pub fn on_new_window NewWindowResponse + Send + 'static>( mut self, f: F, ) -> Self {