Skip to content

Commit 69ae6f1

Browse files
authored
refactor(window): block main thread when creating a new window (#4298)
1 parent d703d27 commit 69ae6f1

8 files changed

Lines changed: 110 additions & 60 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
**Breaking change:** Revert the window creation to be blocking in the main thread. This ensures the window is created before using other methods, but has an issue on Windows where the program deadlocks when creating a window in a Tauri command if it is not `async`. The documentation now states that commands must be `async` in other to prevent it until the issue is fixed in Webview2.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,15 @@ impl<T: UserEvent> Context<T> {
225225

226226
self.prepare_window(window_id);
227227

228-
// we cannot use `send_user_message` here, see https://github.com/tauri-apps/wry/issues/583
229-
self
230-
.proxy
231-
.send_event(Message::CreateWebview(
228+
send_user_message(
229+
self,
230+
Message::CreateWebview(
232231
window_id,
233232
Box::new(move |event_loop, web_context| {
234233
create_webview(window_id, event_loop, web_context, context, pending)
235234
}),
236-
))
237-
.map_err(|_| Error::FailedToSendMessage)?;
235+
),
236+
)?;
238237

239238
let dispatcher = WryDispatcher {
240239
window_id,

core/tauri-runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl SystemTray {
8181
}
8282

8383
/// Type of user attention requested on a window.
84-
#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
84+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
8585
#[serde(tag = "type")]
8686
pub enum UserAttentionType {
8787
/// ## Platform-specific

core/tauri-utils/src/config.rs

Lines changed: 46 additions & 46 deletions
Large diffs are not rendered by default.

core/tauri/src/api/file/extract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl<R: Read + Seek> ArchiveReader<R> {
3838
}
3939

4040
/// The supported archive formats.
41-
#[derive(Debug, Clone, Copy, PartialEq)]
41+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4242
#[non_exhaustive]
4343
pub enum ArchiveFormat {
4444
/// Tar archive.
@@ -48,7 +48,7 @@ pub enum ArchiveFormat {
4848
}
4949

5050
/// The supported compression types.
51-
#[derive(Debug, Clone, Copy, PartialEq)]
51+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5252
#[non_exhaustive]
5353
pub enum Compression {
5454
/// Gz compression (e.g. `.tar.gz` archives)

core/tauri/src/api/process/command.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl Command {
275275
Ok(status) => {
276276
let _l = guard.write().unwrap();
277277
commands().lock().unwrap().remove(&child_.id());
278-
let _ = block_on_task(async move {
278+
block_on_task(async move {
279279
tx.send(CommandEvent::Terminated(TerminatedPayload {
280280
code: status.code(),
281281
#[cfg(windows)]
@@ -284,11 +284,11 @@ impl Command {
284284
signal: status.signal(),
285285
}))
286286
.await
287-
});
287+
})
288288
}
289289
Err(e) => {
290290
let _l = guard.write().unwrap();
291-
let _ = block_on_task(async move { tx.send(CommandEvent::Error(e.to_string())).await });
291+
block_on_task(async move { tx.send(CommandEvent::Error(e.to_string())).await })
292292
}
293293
};
294294
});

core/tauri/src/endpoints/dialog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ fn set_default_path(
269269
if parent.components().count() > 0 {
270270
dialog_builder = dialog_builder.set_directory(parent);
271271
}
272-
dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy().to_string());
272+
dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy());
273273
} else {
274274
dialog_builder = dialog_builder.set_directory(default_path);
275275
}

core/tauri/src/window.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,52 @@ impl<'a, R: Runtime> fmt::Debug for WindowBuilder<'a, R> {
120120

121121
impl<'a, R: Runtime> WindowBuilder<'a, R> {
122122
/// Initializes a webview window builder with the given window label and URL to load on the webview.
123+
///
124+
/// # Examples
125+
///
126+
/// - Create a window in the setup hook:
127+
///
128+
/// ```
129+
/// tauri::Builder::default()
130+
/// .setup(|app| {
131+
/// let window = tauri::WindowBuilder::new(app, "label", tauri::WindowUrl::App("index.html".into()))
132+
/// .build()?;
133+
/// Ok(())
134+
/// });
135+
/// ```
136+
///
137+
/// - Create a window in a separate thread:
138+
///
139+
/// ```
140+
/// tauri::Builder::default()
141+
/// .setup(|app| {
142+
/// let handle = app.handle();
143+
/// std::thread::spawn(move || {
144+
/// let window = tauri::WindowBuilder::new(&handle, "label", tauri::WindowUrl::App("index.html".into()))
145+
/// .build()
146+
/// .unwrap();
147+
/// });
148+
/// Ok(())
149+
/// });
150+
/// ```
151+
///
152+
/// - Create a window in a command:
153+
///
154+
/// ```
155+
/// #[tauri::command]
156+
/// async fn create_window(app: tauri::AppHandle) {
157+
/// let window = tauri::WindowBuilder::new(&app, "label", tauri::WindowUrl::External("https://tauri.studio/".parse().unwrap()))
158+
/// .build()
159+
/// .unwrap();
160+
/// }
161+
/// ```
162+
///
163+
/// # Known issues
164+
///
165+
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
166+
/// You should use `async` commands when creating windows.
167+
///
168+
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
123169
pub fn new<M: Manager<R>, L: Into<String>>(manager: &'a M, label: L, url: WindowUrl) -> Self {
124170
let runtime = manager.runtime();
125171
let app_handle = manager.app_handle();
@@ -600,7 +646,7 @@ impl Window<crate::Wry> {
600646
/// use webkit2gtk::traits::WebViewExt;
601647
/// webview.inner().set_zoom_level(4.);
602648
/// }
603-
///
649+
///
604650
/// #[cfg(windows)]
605651
/// unsafe {
606652
/// // see https://docs.rs/webview2-com/latest/webview2_com/Microsoft/Web/WebView2/Win32/struct.ICoreWebView2Controller.html

0 commit comments

Comments
 (0)