Browse Source

refactor(window): block main thread when creating a new window (#4298)

Lucas Fernandes Nogueira 3 years ago
parent
commit
69ae6f1494

+ 5 - 0
.changes/refactor-window-creation.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch
+---
+
+**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.

+ 5 - 6
core/tauri-runtime-wry/src/lib.rs

@@ -225,16 +225,15 @@ impl<T: UserEvent> Context<T> {
 
 
     self.prepare_window(window_id);
     self.prepare_window(window_id);
 
 
-    // we cannot use `send_user_message` here, see https://github.com/tauri-apps/wry/issues/583
-    self
-      .proxy
-      .send_event(Message::CreateWebview(
+    send_user_message(
+      self,
+      Message::CreateWebview(
         window_id,
         window_id,
         Box::new(move |event_loop, web_context| {
         Box::new(move |event_loop, web_context| {
           create_webview(window_id, event_loop, web_context, context, pending)
           create_webview(window_id, event_loop, web_context, context, pending)
         }),
         }),
-      ))
-      .map_err(|_| Error::FailedToSendMessage)?;
+      ),
+    )?;
 
 
     let dispatcher = WryDispatcher {
     let dispatcher = WryDispatcher {
       window_id,
       window_id,

+ 1 - 1
core/tauri-runtime/src/lib.rs

@@ -81,7 +81,7 @@ impl SystemTray {
 }
 }
 
 
 /// Type of user attention requested on a window.
 /// Type of user attention requested on a window.
-#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
 #[serde(tag = "type")]
 #[serde(tag = "type")]
 pub enum UserAttentionType {
 pub enum UserAttentionType {
   /// ## Platform-specific
   /// ## Platform-specific

+ 46 - 46
core/tauri-utils/src/config.rs

@@ -37,7 +37,7 @@ pub mod parse;
 pub use self::parse::parse;
 pub use self::parse::parse;
 
 
 /// An URL to open on a Tauri webview window.
 /// An URL to open on a Tauri webview window.
-#[derive(PartialEq, Debug, Clone, Deserialize, Serialize)]
+#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged)]
 #[serde(untagged)]
 #[non_exhaustive]
 #[non_exhaustive]
@@ -66,7 +66,7 @@ impl Default for WindowUrl {
 }
 }
 
 
 /// Targets to bundle.
 /// Targets to bundle.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged)]
 #[serde(untagged)]
 pub enum BundleTarget {
 pub enum BundleTarget {
@@ -89,7 +89,7 @@ impl BundleTarget {
 
 
 /// Configuration for Debian (.deb) bundles.
 /// Configuration for Debian (.deb) bundles.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct DebConfig {
 pub struct DebConfig {
@@ -113,7 +113,7 @@ where
 
 
 /// Configuration for the macOS bundles.
 /// Configuration for the macOS bundles.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct MacConfig {
 pub struct MacConfig {
@@ -164,7 +164,7 @@ fn minimum_system_version() -> Option<String> {
 }
 }
 
 
 /// Configuration for a target language for the WiX build.
 /// Configuration for a target language for the WiX build.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct WixLanguageConfig {
 pub struct WixLanguageConfig {
@@ -173,7 +173,7 @@ pub struct WixLanguageConfig {
 }
 }
 
 
 /// The languages to build using WiX.
 /// The languages to build using WiX.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged)]
 #[serde(untagged)]
 pub enum WixLanguage {
 pub enum WixLanguage {
@@ -192,7 +192,7 @@ impl Default for WixLanguage {
 }
 }
 
 
 /// Configuration for the MSI bundle using WiX.
 /// Configuration for the MSI bundle using WiX.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct WixConfig {
 pub struct WixConfig {
@@ -242,7 +242,7 @@ pub struct WixConfig {
 }
 }
 
 
 /// Windows bundler configuration.
 /// Windows bundler configuration.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct WindowsConfig {
 pub struct WindowsConfig {
@@ -293,7 +293,7 @@ fn default_allow_downgrades() -> bool {
 
 
 /// Configuration for tauri-bundler.
 /// Configuration for tauri-bundler.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct BundleConfig {
 pub struct BundleConfig {
@@ -347,7 +347,7 @@ pub struct BundleConfig {
 
 
 /// A CLI argument definition.
 /// A CLI argument definition.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct CliArg {
 pub struct CliArg {
@@ -453,7 +453,7 @@ pub struct CliArg {
 
 
 /// describes a CLI configuration
 /// describes a CLI configuration
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct CliConfig {
 pub struct CliConfig {
@@ -654,7 +654,7 @@ fn default_file_drop_enabled() -> bool {
 
 
 /// A Content-Security-Policy directive source list.
 /// A Content-Security-Policy directive source list.
 /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
 /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", untagged)]
 #[serde(rename_all = "camelCase", untagged)]
 pub enum CspDirectiveSources {
 pub enum CspDirectiveSources {
@@ -711,7 +711,7 @@ impl CspDirectiveSources {
 
 
 /// A Content-Security-Policy definition.
 /// A Content-Security-Policy definition.
 /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
 /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", untagged)]
 #[serde(rename_all = "camelCase", untagged)]
 pub enum Csp {
 pub enum Csp {
@@ -768,7 +768,7 @@ impl Display for Csp {
 }
 }
 
 
 /// The possible values for the `dangerous_disable_asset_csp_modification` config option.
 /// The possible values for the `dangerous_disable_asset_csp_modification` config option.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[serde(untagged)]
 #[serde(untagged)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub enum DisabledCspModificationKind {
 pub enum DisabledCspModificationKind {
@@ -797,7 +797,7 @@ impl Default for DisabledCspModificationKind {
 
 
 /// Security configuration.
 /// Security configuration.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct SecurityConfig {
 pub struct SecurityConfig {
@@ -854,7 +854,7 @@ macro_rules! check_feature {
 /// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
 /// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
 /// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
 /// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
 /// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.
 /// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged)]
 #[serde(untagged)]
 pub enum FsAllowlistScope {
 pub enum FsAllowlistScope {
@@ -897,7 +897,7 @@ impl FsAllowlistScope {
 }
 }
 
 
 /// Allowlist for the file system APIs.
 /// Allowlist for the file system APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct FsAllowlistConfig {
 pub struct FsAllowlistConfig {
@@ -971,7 +971,7 @@ impl Allowlist for FsAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the window APIs.
 /// Allowlist for the window APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct WindowAllowlistConfig {
 pub struct WindowAllowlistConfig {
@@ -1131,7 +1131,7 @@ impl Allowlist for WindowAllowlistConfig {
 }
 }
 
 
 /// A command allowed to be executed by the webview API.
 /// A command allowed to be executed by the webview API.
-#[derive(Debug, PartialEq, Clone, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub struct ShellAllowedCommand {
 pub struct ShellAllowedCommand {
   /// The name for this allowed shell command configuration.
   /// The name for this allowed shell command configuration.
@@ -1195,7 +1195,7 @@ impl<'de> Deserialize<'de> for ShellAllowedCommand {
 /// A value of `true` will allow any arguments to be passed to the command. `false` will disable all
 /// A value of `true` will allow any arguments to be passed to the command. `false` will disable all
 /// arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to
 /// arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to
 /// be passed to the attached command configuration.
 /// be passed to the attached command configuration.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged, deny_unknown_fields)]
 #[serde(untagged, deny_unknown_fields)]
 #[non_exhaustive]
 #[non_exhaustive]
@@ -1214,7 +1214,7 @@ impl Default for ShellAllowedArgs {
 }
 }
 
 
 /// A command argument allowed to be executed by the webview API.
 /// A command argument allowed to be executed by the webview API.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged, deny_unknown_fields)]
 #[serde(untagged, deny_unknown_fields)]
 #[non_exhaustive]
 #[non_exhaustive]
@@ -1237,12 +1237,12 @@ pub enum ShellAllowedArg {
 
 
 /// Shell scope definition.
 /// Shell scope definition.
 /// It is a list of command names and associated CLI arguments that restrict the API access from the webview.
 /// It is a list of command names and associated CLI arguments that restrict the API access from the webview.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub struct ShellAllowlistScope(pub Vec<ShellAllowedCommand>);
 pub struct ShellAllowlistScope(pub Vec<ShellAllowedCommand>);
 
 
 /// Defines the `shell > open` api scope.
 /// Defines the `shell > open` api scope.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged, deny_unknown_fields)]
 #[serde(untagged, deny_unknown_fields)]
 #[non_exhaustive]
 #[non_exhaustive]
@@ -1266,7 +1266,7 @@ impl Default for ShellAllowlistOpen {
 }
 }
 
 
 /// Allowlist for the shell APIs.
 /// Allowlist for the shell APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct ShellAllowlistConfig {
 pub struct ShellAllowlistConfig {
@@ -1322,7 +1322,7 @@ impl Allowlist for ShellAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the dialog APIs.
 /// Allowlist for the dialog APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct DialogAllowlistConfig {
 pub struct DialogAllowlistConfig {
@@ -1385,12 +1385,12 @@ impl Allowlist for DialogAllowlistConfig {
 /// - "https://*.github.com/tauri-apps/tauri": allows any subdomain of "github.com" with the "tauri-apps/api" path
 /// - "https://*.github.com/tauri-apps/tauri": allows any subdomain of "github.com" with the "tauri-apps/api" path
 /// - "https://myapi.service.com/users/*": allows access to any URLs that begins with "https://myapi.service.com/users/"
 /// - "https://myapi.service.com/users/*": allows access to any URLs that begins with "https://myapi.service.com/users/"
 #[allow(rustdoc::bare_urls)]
 #[allow(rustdoc::bare_urls)]
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub struct HttpAllowlistScope(pub Vec<Url>);
 pub struct HttpAllowlistScope(pub Vec<Url>);
 
 
 /// Allowlist for the HTTP APIs.
 /// Allowlist for the HTTP APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct HttpAllowlistConfig {
 pub struct HttpAllowlistConfig {
@@ -1429,7 +1429,7 @@ impl Allowlist for HttpAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the notification APIs.
 /// Allowlist for the notification APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct NotificationAllowlistConfig {
 pub struct NotificationAllowlistConfig {
@@ -1456,7 +1456,7 @@ impl Allowlist for NotificationAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the global shortcut APIs.
 /// Allowlist for the global shortcut APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct GlobalShortcutAllowlistConfig {
 pub struct GlobalShortcutAllowlistConfig {
@@ -1483,7 +1483,7 @@ impl Allowlist for GlobalShortcutAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the OS APIs.
 /// Allowlist for the OS APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct OsAllowlistConfig {
 pub struct OsAllowlistConfig {
@@ -1510,7 +1510,7 @@ impl Allowlist for OsAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the path APIs.
 /// Allowlist for the path APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct PathAllowlistConfig {
 pub struct PathAllowlistConfig {
@@ -1537,7 +1537,7 @@ impl Allowlist for PathAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the custom protocols.
 /// Allowlist for the custom protocols.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct ProtocolAllowlistConfig {
 pub struct ProtocolAllowlistConfig {
@@ -1576,7 +1576,7 @@ impl Allowlist for ProtocolAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the process APIs.
 /// Allowlist for the process APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct ProcessAllowlistConfig {
 pub struct ProcessAllowlistConfig {
@@ -1629,7 +1629,7 @@ impl Allowlist for ProcessAllowlistConfig {
 }
 }
 
 
 /// Allowlist for the clipboard APIs.
 /// Allowlist for the clipboard APIs.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct ClipboardAllowlistConfig {
 pub struct ClipboardAllowlistConfig {
@@ -1669,7 +1669,7 @@ impl Allowlist for ClipboardAllowlistConfig {
 }
 }
 
 
 /// Allowlist configuration.
 /// Allowlist configuration.
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct AllowlistConfig {
 pub struct AllowlistConfig {
@@ -1756,7 +1756,7 @@ impl Allowlist for AllowlistConfig {
 
 
 /// The application pattern.
 /// The application pattern.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "lowercase", tag = "use", content = "options")]
 #[serde(rename_all = "lowercase", tag = "use", content = "options")]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub enum PatternKind {
 pub enum PatternKind {
@@ -1853,7 +1853,7 @@ impl TauriConfig {
 ///
 ///
 /// The URL must use the `https` scheme on production.
 /// The URL must use the `https` scheme on production.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub struct UpdaterEndpoint(pub Url);
 pub struct UpdaterEndpoint(pub Url);
 
 
@@ -1882,7 +1882,7 @@ impl<'de> Deserialize<'de> for UpdaterEndpoint {
 }
 }
 
 
 /// Install modes for the Windows update.
 /// Install modes for the Windows update.
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", schemars(rename_all = "camelCase"))]
 #[cfg_attr(feature = "schema", schemars(rename_all = "camelCase"))]
 pub enum WindowsUpdateInstallMode {
 pub enum WindowsUpdateInstallMode {
@@ -1955,7 +1955,7 @@ impl<'de> Deserialize<'de> for WindowsUpdateInstallMode {
 
 
 /// The updater configuration for Windows.
 /// The updater configuration for Windows.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct UpdaterWindowsConfig {
 pub struct UpdaterWindowsConfig {
@@ -1966,7 +1966,7 @@ pub struct UpdaterWindowsConfig {
 
 
 /// The Updater configuration object.
 /// The Updater configuration object.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct UpdaterConfig {
 pub struct UpdaterConfig {
@@ -2045,7 +2045,7 @@ impl Default for UpdaterConfig {
 
 
 /// Configuration for application system tray icon.
 /// Configuration for application system tray icon.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct SystemTrayConfig {
 pub struct SystemTrayConfig {
@@ -2066,7 +2066,7 @@ fn default_dialog() -> bool {
 }
 }
 
 
 /// Defines the URL or assets to embed in the application.
 /// Defines the URL or assets to embed in the application.
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(untagged, deny_unknown_fields)]
 #[serde(untagged, deny_unknown_fields)]
 #[non_exhaustive]
 #[non_exhaustive]
@@ -2088,7 +2088,7 @@ impl std::fmt::Display for AppUrl {
 
 
 /// The Build configuration object.
 /// The Build configuration object.
 #[skip_serializing_none]
 #[skip_serializing_none]
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct BuildConfig {
 pub struct BuildConfig {
@@ -2155,7 +2155,7 @@ fn default_dist_dir() -> AppUrl {
   AppUrl::Url(WindowUrl::App("../dist".into()))
   AppUrl::Url(WindowUrl::App("../dist".into()))
 }
 }
 
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 struct PackageVersion(String);
 struct PackageVersion(String);
 
 
 impl<'d> serde::Deserialize<'d> for PackageVersion {
 impl<'d> serde::Deserialize<'d> for PackageVersion {
@@ -2212,7 +2212,7 @@ impl<'d> serde::Deserialize<'d> for PackageVersion {
 }
 }
 
 
 /// The package configuration.
 /// The package configuration.
-#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)]
+#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct PackageConfig {
 pub struct PackageConfig {
@@ -2325,7 +2325,7 @@ pub struct Config {
 }
 }
 
 
 /// The plugin configs holds a HashMap mapping a plugin name to its configuration object.
 /// The plugin configs holds a HashMap mapping a plugin name to its configuration object.
-#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)]
+#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 pub struct PluginConfig(pub HashMap<String, JsonValue>);
 pub struct PluginConfig(pub HashMap<String, JsonValue>);
 
 

+ 2 - 2
core/tauri/src/api/file/extract.rs

@@ -38,7 +38,7 @@ impl<R: Read + Seek> ArchiveReader<R> {
 }
 }
 
 
 /// The supported archive formats.
 /// The supported archive formats.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 #[non_exhaustive]
 pub enum ArchiveFormat {
 pub enum ArchiveFormat {
   /// Tar archive.
   /// Tar archive.
@@ -48,7 +48,7 @@ pub enum ArchiveFormat {
 }
 }
 
 
 /// The supported compression types.
 /// The supported compression types.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 #[non_exhaustive]
 pub enum Compression {
 pub enum Compression {
   /// Gz compression (e.g. `.tar.gz` archives)
   /// Gz compression (e.g. `.tar.gz` archives)

+ 3 - 3
core/tauri/src/api/process/command.rs

@@ -275,7 +275,7 @@ impl Command {
         Ok(status) => {
         Ok(status) => {
           let _l = guard.write().unwrap();
           let _l = guard.write().unwrap();
           commands().lock().unwrap().remove(&child_.id());
           commands().lock().unwrap().remove(&child_.id());
-          let _ = block_on_task(async move {
+          block_on_task(async move {
             tx.send(CommandEvent::Terminated(TerminatedPayload {
             tx.send(CommandEvent::Terminated(TerminatedPayload {
               code: status.code(),
               code: status.code(),
               #[cfg(windows)]
               #[cfg(windows)]
@@ -284,11 +284,11 @@ impl Command {
               signal: status.signal(),
               signal: status.signal(),
             }))
             }))
             .await
             .await
-          });
+          })
         }
         }
         Err(e) => {
         Err(e) => {
           let _l = guard.write().unwrap();
           let _l = guard.write().unwrap();
-          let _ = block_on_task(async move { tx.send(CommandEvent::Error(e.to_string())).await });
+          block_on_task(async move { tx.send(CommandEvent::Error(e.to_string())).await })
         }
         }
       };
       };
     });
     });

+ 1 - 1
core/tauri/src/endpoints/dialog.rs

@@ -269,7 +269,7 @@ fn set_default_path(
       if parent.components().count() > 0 {
       if parent.components().count() > 0 {
         dialog_builder = dialog_builder.set_directory(parent);
         dialog_builder = dialog_builder.set_directory(parent);
       }
       }
-      dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy().to_string());
+      dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy());
     } else {
     } else {
       dialog_builder = dialog_builder.set_directory(default_path);
       dialog_builder = dialog_builder.set_directory(default_path);
     }
     }

+ 47 - 1
core/tauri/src/window.rs

@@ -120,6 +120,52 @@ impl<'a, R: Runtime> fmt::Debug for WindowBuilder<'a, R> {
 
 
 impl<'a, R: Runtime> WindowBuilder<'a, R> {
 impl<'a, R: Runtime> WindowBuilder<'a, R> {
   /// Initializes a webview window builder with the given window label and URL to load on the webview.
   /// Initializes a webview window builder with the given window label and URL to load on the webview.
+  ///
+  /// # Examples
+  ///
+  /// - Create a window in the setup hook:
+  ///
+  /// ```
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     let window = tauri::WindowBuilder::new(app, "label", tauri::WindowUrl::App("index.html".into()))
+  ///       .build()?;
+  ///     Ok(())
+  ///   });
+  /// ```
+  ///
+  /// - Create a window in a separate thread:
+  ///
+  /// ```
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     let handle = app.handle();
+  ///     std::thread::spawn(move || {
+  ///       let window = tauri::WindowBuilder::new(&handle, "label", tauri::WindowUrl::App("index.html".into()))
+  ///         .build()
+  ///         .unwrap();
+  ///     });
+  ///     Ok(())
+  ///   });
+  /// ```
+  ///
+  /// - Create a window in a command:
+  ///
+  /// ```
+  /// #[tauri::command]
+  /// async fn create_window(app: tauri::AppHandle) {
+  ///   let window = tauri::WindowBuilder::new(&app, "label", tauri::WindowUrl::External("https://tauri.studio/".parse().unwrap()))
+  ///     .build()
+  ///     .unwrap();
+  /// }
+  /// ```
+  ///
+  /// # Known issues
+  ///
+  /// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
+  /// You should use `async` commands when creating windows.
+  ///
+  /// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
   pub fn new<M: Manager<R>, L: Into<String>>(manager: &'a M, label: L, url: WindowUrl) -> Self {
   pub fn new<M: Manager<R>, L: Into<String>>(manager: &'a M, label: L, url: WindowUrl) -> Self {
     let runtime = manager.runtime();
     let runtime = manager.runtime();
     let app_handle = manager.app_handle();
     let app_handle = manager.app_handle();
@@ -600,7 +646,7 @@ impl Window<crate::Wry> {
   ///           use webkit2gtk::traits::WebViewExt;
   ///           use webkit2gtk::traits::WebViewExt;
   ///           webview.inner().set_zoom_level(4.);
   ///           webview.inner().set_zoom_level(4.);
   ///         }
   ///         }
-  ///   
+  ///
   ///         #[cfg(windows)]
   ///         #[cfg(windows)]
   ///         unsafe {
   ///         unsafe {
   ///           // see https://docs.rs/webview2-com/latest/webview2_com/Microsoft/Web/WebView2/Win32/struct.ICoreWebView2Controller.html
   ///           // see https://docs.rs/webview2-com/latest/webview2_com/Microsoft/Web/WebView2/Win32/struct.ICoreWebView2Controller.html