Skip to content

Commit 32accb5

Browse files
committed
fix: more Windows shite
1 parent 60c7e66 commit 32accb5

3 files changed

Lines changed: 17 additions & 23 deletions

File tree

src-tauri/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4911,8 +4911,8 @@ pub fn run() {
49114911
.plugin(tauri_plugin_opener::init())
49124912
.plugin(tauri_plugin_notification::init())
49134913
.plugin(tauri_plugin_deep_link::init())
4914-
// Register the webxdc:// custom protocol for Mini Apps
4915-
.register_uri_scheme_protocol("webxdc", miniapps::scheme::miniapp_protocol)
4914+
// Register the webxdc:// custom protocol for Mini Apps (async to avoid deadlocks on Windows)
4915+
.register_asynchronous_uri_scheme_protocol("webxdc", miniapps::scheme::miniapp_protocol)
49164916
// Register Mini Apps state
49174917
.manage(miniapps::state::MiniAppsState::new());
49184918

src-tauri/src/miniapps/commands.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ fn get_chromium_hardening_browser_args(dummy_proxy_url: &url::Url) -> String {
163163
// These are default parameters from Tauri's wry
164164
let default_tauri_browser_args = "--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection --enable-features=RemoveRedirectionBitmap";
165165

166-
// The `~NOTFOUND` string blocks DNS resolution
166+
// The `~NOTFOUND` string blocks DNS resolution.
167+
// Note: webxdc.localhost requests are intercepted by Tauri's custom protocol
168+
// handler BEFORE the Chromium network stack, so no EXCLUDE is needed.
167169
let host_rules = "MAP * ~NOTFOUND";
168170

169171
// `host-resolver-rules` and `host-rules` primarily block DNS prefetching

src-tauri/src/miniapps/scheme.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::borrow::Cow;
77
use std::collections::HashMap;
88
use tauri::{
99
utils::config::{Csp, CspDirectiveSources},
10-
Manager, UriSchemeContext,
10+
Manager, UriSchemeContext, UriSchemeResponder,
1111
};
1212
use log::{error, trace};
1313
use 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
200201
pub 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

245237
async fn handle_miniapp_request<R: tauri::Runtime>(

0 commit comments

Comments
 (0)