@@ -7,7 +7,7 @@ use std::borrow::Cow;
77use std:: collections:: HashMap ;
88use tauri:: {
99 utils:: config:: { Csp , CspDirectiveSources } ,
10- Manager , UriSchemeContext ,
10+ Manager , UriSchemeContext , UriSchemeResponder ,
1111} ;
1212use log:: { error, trace} ;
1313use nostr_sdk:: prelude:: ToBech32 ;
@@ -196,11 +196,13 @@ const PERMISSIONS_POLICY_DENY_ALL: &str = concat!(
196196 "window-placement=()" ,
197197) ;
198198
199- /// Handle requests to the webxdc:// protocol (synchronous version for Tauri 2)
199+ /// Handle requests to the webxdc:// protocol (async version for Tauri 2)
200+ /// Uses UriSchemeResponder to avoid blocking the WebView thread on Windows
200201pub fn miniapp_protocol < R : tauri:: Runtime > (
201202 ctx : UriSchemeContext < ' _ , R > ,
202203 request : http:: Request < Vec < u8 > > ,
203- ) -> http:: Response < Cow < ' static , [ u8 ] > > {
204+ responder : UriSchemeResponder ,
205+ ) {
204206 trace ! (
205207 "webxdc_protocol: {} {}" ,
206208 request. uri( ) ,
@@ -218,28 +220,18 @@ pub fn miniapp_protocol<R: tauri::Runtime>(
218220 error ! (
219221 "Prevented non-miniapp window from accessing webxdc:// scheme (webview label: {webview_label})"
220222 ) ;
221- return make_error_response ( http:: StatusCode :: FORBIDDEN , "Access denied" ) ;
223+ responder. respond ( make_error_response ( http:: StatusCode :: FORBIDDEN , "Access denied" ) ) ;
224+ return ;
222225 }
223226
224227 let app_handle = ctx. app_handle ( ) . clone ( ) ;
225228
226- // On Windows, using block_on directly can cause a deadlock because the WebView2
227- // runs on the main thread. We spawn a new thread to run the async code and
228- // use a channel to get the result back.
229- // See: https://github.com/nicholasrice/tauri-v2-webview-deadlock
230- let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
231-
232- std:: thread:: spawn ( move || {
233- let result = tauri:: async_runtime:: block_on ( async move {
234- handle_miniapp_request ( & app_handle, & webview_label, & request) . await
235- } ) ;
236- let _ = tx. send ( result) ;
229+ // Spawn an async task to handle the request without blocking
230+ // This is the pattern used by DeltaChat to avoid deadlocks on Windows
231+ tauri:: async_runtime:: spawn ( async move {
232+ let response = handle_miniapp_request ( & app_handle, & webview_label, & request) . await ;
233+ responder. respond ( response) ;
237234 } ) ;
238-
239- // Wait for the result from the spawned thread
240- rx. recv ( ) . unwrap_or_else ( |_| {
241- make_error_response ( http:: StatusCode :: INTERNAL_SERVER_ERROR , "Failed to handle request" )
242- } )
243235}
244236
245237async fn handle_miniapp_request < R : tauri:: Runtime > (
0 commit comments