Explorar o código

feat(core): add shadow APIs (#6206)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Amr Bashir %!s(int64=2) %!d(string=hai) anos
pai
achega
a81750d779

+ 5 - 0
.changes/shadow-api.md

@@ -0,0 +1,5 @@
+---
+'api': minor
+---
+
+Added the `shadow` option when creating a window and `setShadow` function.

+ 5 - 0
.changes/shadow-config.md

@@ -0,0 +1,5 @@
+---
+'tauri-utils': minor
+---
+
+Added the `shadow` option to the window configuration and `set_shadow` option to the `window` allow list.

+ 7 - 0
.changes/shadow.md

@@ -0,0 +1,7 @@
+---
+'tauri': minor
+'tauri-runtime-wry': minor
+'tauri-runtime': minor
+---
+
+Added the `shadow` option when creating a window and `Window::set_shadow`.

+ 13 - 0
core/config-schema/schema.json

@@ -118,6 +118,7 @@
             "setMinSize": false,
             "setPosition": false,
             "setResizable": false,
+            "setShadow": false,
             "setSize": false,
             "setSkipTaskbar": false,
             "setTitle": false,
@@ -393,6 +394,7 @@
               "setMinSize": false,
               "setPosition": false,
               "setResizable": false,
+              "setShadow": false,
               "setSize": false,
               "setSkipTaskbar": false,
               "setTitle": false,
@@ -684,6 +686,11 @@
             "string",
             "null"
           ]
+        },
+        "shadow": {
+          "description": "Whether or not the window has shadow.\n\n## Platform-specific\n\n- **Windows:** - `false` has no effect on decorated window, shadow are always ON. - `true` will make ndecorated window have a 1px white border, and on Windows 11, it will have a rounded corners. - **Linux:** Unsupported.",
+          "default": false,
+          "type": "boolean"
         }
       },
       "additionalProperties": false
@@ -1699,6 +1706,7 @@
             "setMinSize": false,
             "setPosition": false,
             "setResizable": false,
+            "setShadow": false,
             "setSize": false,
             "setSkipTaskbar": false,
             "setTitle": false,
@@ -2031,6 +2039,11 @@
           "default": false,
           "type": "boolean"
         },
+        "setShadow": {
+          "description": "Allows setting the shadow flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
         "setAlwaysOnTop": {
           "description": "Allows setting the always_on_top flag of the window.",
           "default": false,

+ 4 - 4
core/tauri-runtime-wry/Cargo.toml

@@ -21,11 +21,11 @@ rand = "0.8"
 raw-window-handle = "0.5"
 
 [target."cfg(windows)".dependencies]
-webview2-com = "0.19.1"
+webview2-com = "0.22"
 
-  [target."cfg(windows)".dependencies.windows]
-  version = "0.39.0"
-  features = [ "Win32_Foundation" ]
+[target."cfg(windows)".dependencies.windows]
+version = "0.44"
+features = [ "Win32_Foundation" ]
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
 gtk = { version = "0.16", features = [ "v3_24" ] }

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

@@ -741,7 +741,8 @@ impl WindowBuilder for WindowBuilderWrapper {
         .maximized(config.maximized)
         .always_on_top(config.always_on_top)
         .skip_taskbar(config.skip_taskbar)
-        .theme(config.theme);
+        .theme(config.theme)
+        .shadow(config.shadow);
 
       if let (Some(min_width), Some(min_height)) = (config.min_width, config.min_height) {
         window = window.min_inner_size(min_width, min_height);
@@ -849,6 +850,18 @@ impl WindowBuilder for WindowBuilderWrapper {
     self
   }
 
+  fn shadow(#[allow(unused_mut)] mut self, _enable: bool) -> Self {
+    #[cfg(windows)]
+    {
+      self.inner = self.inner.with_undecorated_shadow(_enable);
+    }
+    #[cfg(target_os = "macos")]
+    {
+      self.inner = self.inner.with_has_shadow(_enable);
+    }
+    self
+  }
+
   #[cfg(windows)]
   fn parent_window(mut self, parent: HWND) -> Self {
     self.inner = self.inner.with_parent_window(parent);
@@ -1066,6 +1079,7 @@ pub enum WindowMessage {
   Hide,
   Close,
   SetDecorations(bool),
+  SetShadow(bool),
   SetAlwaysOnTop(bool),
   SetSize(Size),
   SetMinSize(Option<Size>),
@@ -1430,6 +1444,13 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
     )
   }
 
+  fn set_shadow(&self, enable: bool) -> Result<()> {
+    send_user_message(
+      &self.context,
+      Message::Window(self.window_id, WindowMessage::SetShadow(enable)),
+    )
+  }
+
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
     send_user_message(
       &self.context,
@@ -2420,6 +2441,12 @@ fn handle_user_message<T: UserEvent>(
               panic!("cannot handle `WindowMessage::Close` on the main thread")
             }
             WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations),
+            WindowMessage::SetShadow(_enable) => {
+              #[cfg(windows)]
+              window.set_undecorated_shadow(_enable);
+              #[cfg(target_os = "macos")]
+              window.set_has_shadow(_enable);
+            }
             WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top),
             WindowMessage::SetSize(size) => {
               window.set_inner_size(SizeWrapper::from(size).0);

+ 4 - 4
core/tauri-runtime/Cargo.toml

@@ -34,11 +34,11 @@ raw-window-handle = "0.5"
 rand = "0.8"
 
 [target."cfg(windows)".dependencies]
-webview2-com = "0.19.1"
+webview2-com = "0.22"
 
-  [target."cfg(windows)".dependencies.windows]
-  version = "0.39.0"
-  features = [ "Win32_Foundation" ]
+[target."cfg(windows)".dependencies.windows]
+version = "0.44"
+features = [ "Win32_Foundation" ]
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
 gtk = { version = "0.16", features = [ "v3_24" ] }

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

@@ -639,9 +639,12 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
   /// Closes the window.
   fn close(&self) -> Result<()>;
 
-  /// Updates the hasDecorations flag.
+  /// Updates the decorations flag.
   fn set_decorations(&self, decorations: bool) -> Result<()>;
 
+  /// Updates the shadow flag.
+  fn set_shadow(&self, enable: bool) -> Result<()>;
+
   /// Updates the window alwaysOnTop flag.
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
 

+ 12 - 0
core/tauri-runtime/src/webview.rs

@@ -179,6 +179,18 @@ pub trait WindowBuilder: WindowBuilderBase {
   #[must_use]
   fn skip_taskbar(self, skip: bool) -> Self;
 
+  /// Sets whether or not the window has shadow.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **Windows:**
+  ///   - `false` has no effect on decorated window, shadows are always ON.
+  ///   - `true` will make ndecorated window have a 1px white border,
+  /// and on Windows 11, it will have a rounded corners.
+  /// - **Linux:** Unsupported.
+  #[must_use]
+  fn shadow(self, enable: bool) -> Self;
+
   /// Sets a parent to the window to be created.
   ///
   /// A child window has the WS_CHILD style and is confined to the client area of its parent window.

+ 1 - 1
core/tauri-utils/Cargo.toml

@@ -41,7 +41,7 @@ infer = "0.7"
 heck = "0.4"
 
 [target."cfg(windows)".dependencies.windows]
-version = "0.39.0"
+version = "0.44.0"
 features = [
   "implement",
   "Win32_Foundation",

+ 40 - 59
core/tauri-utils/src/config.rs

@@ -431,7 +431,7 @@ pub enum WebviewInstallMode {
   /// Results in a smaller installer size, but is not recommended on Windows 7.
   DownloadBootstrapper {
     /// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
-    #[serde(default = "default_webview_install_silent")]
+    #[serde(default = "default_true")]
     silent: bool,
   },
   /// Embed the bootstrapper and run it.
@@ -439,7 +439,7 @@ pub enum WebviewInstallMode {
   /// Increases the installer size by around 1.8MB, but offers better support on Windows 7.
   EmbedBootstrapper {
     /// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
-    #[serde(default = "default_webview_install_silent")]
+    #[serde(default = "default_true")]
     silent: bool,
   },
   /// Embed the offline installer and run it.
@@ -447,7 +447,7 @@ pub enum WebviewInstallMode {
   /// Increases the installer size by around 127MB.
   OfflineInstaller {
     /// Instructs the installer to run the installer in silent mode. Defaults to `true`.
-    #[serde(default = "default_webview_install_silent")]
+    #[serde(default = "default_true")]
     silent: bool,
   },
   /// Embed a fixed webview2 version and use it at runtime.
@@ -461,14 +461,10 @@ pub enum WebviewInstallMode {
   },
 }
 
-fn default_webview_install_silent() -> bool {
-  true
-}
-
 impl Default for WebviewInstallMode {
   fn default() -> Self {
     Self::DownloadBootstrapper {
-      silent: default_webview_install_silent(),
+      silent: default_true(),
     }
   }
 }
@@ -508,7 +504,7 @@ pub struct WindowsConfig {
   /// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
   ///
   /// The default value of this flag is `true`.
-  #[serde(default = "default_allow_downgrades", alias = "allow-downgrades")]
+  #[serde(default = "default_true", alias = "allow-downgrades")]
   pub allow_downgrades: bool,
   /// Configuration for the MSI generated with WiX.
   pub wix: Option<WixConfig>,
@@ -523,16 +519,12 @@ impl Default for WindowsConfig {
       tsp: false,
       webview_install_mode: Default::default(),
       webview_fixed_runtime_path: None,
-      allow_downgrades: default_allow_downgrades(),
+      allow_downgrades: default_true(),
       wix: None,
     }
   }
 }
 
-fn default_allow_downgrades() -> bool {
-  true
-}
-
 /// Configuration for tauri-bundler.
 #[skip_serializing_none]
 #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
@@ -805,7 +797,7 @@ pub struct WindowConfig {
   /// Whether the file drop is enabled or not on the webview. By default it is enabled.
   ///
   /// Disabling it is required to use drag and drop on the frontend on Windows.
-  #[serde(default = "default_file_drop_enabled", alias = "file-drop-enabled")]
+  #[serde(default = "default_true", alias = "file-drop-enabled")]
   pub file_drop_enabled: bool,
   /// Whether or not the window starts centered or not.
   #[serde(default)]
@@ -833,7 +825,7 @@ pub struct WindowConfig {
   #[serde(alias = "max-height")]
   pub max_height: Option<f64>,
   /// Whether the window is resizable or not.
-  #[serde(default = "default_resizable")]
+  #[serde(default = "default_true")]
   pub resizable: bool,
   /// The window title.
   #[serde(default = "default_title")]
@@ -842,7 +834,7 @@ pub struct WindowConfig {
   #[serde(default)]
   pub fullscreen: bool,
   /// Whether the window will be initially focused or not.
-  #[serde(default = "default_focus")]
+  #[serde(default = "default_true")]
   pub focus: bool,
   /// Whether the window is transparent or not.
   ///
@@ -854,10 +846,10 @@ pub struct WindowConfig {
   #[serde(default)]
   pub maximized: bool,
   /// Whether the window is visible or not.
-  #[serde(default = "default_visible")]
+  #[serde(default = "default_true")]
   pub visible: bool,
   /// Whether the window should have borders and bars.
-  #[serde(default = "default_decorations")]
+  #[serde(default = "default_true")]
   pub decorations: bool,
   /// Whether the window should always be on top of other windows.
   #[serde(default, alias = "always-on-top")]
@@ -884,6 +876,17 @@ pub struct WindowConfig {
   /// [tabbing identifier]: <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
   #[serde(default, alias = "tabbing-identifier")]
   pub tabbing_identifier: Option<String>,
+  /// Whether or not the window has shadow.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **Windows:**
+  ///   - `false` has no effect on decorated window, shadow are always ON.
+  ///   - `true` will make ndecorated window have a 1px white border,
+  /// and on Windows 11, it will have a rounded corners.
+  /// - **Linux:** Unsupported.
+  #[serde(default)]
+  pub shadow: bool,
 }
 
 impl Default for WindowConfig {
@@ -892,7 +895,7 @@ impl Default for WindowConfig {
       label: default_window_label(),
       url: WindowUrl::default(),
       user_agent: None,
-      file_drop_enabled: default_file_drop_enabled(),
+      file_drop_enabled: default_true(),
       center: false,
       x: None,
       y: None,
@@ -902,14 +905,14 @@ impl Default for WindowConfig {
       min_height: None,
       max_width: None,
       max_height: None,
-      resizable: default_resizable(),
+      resizable: default_true(),
       title: default_title(),
       fullscreen: false,
       focus: false,
       transparent: false,
       maximized: false,
-      visible: default_visible(),
-      decorations: default_decorations(),
+      visible: default_true(),
+      decorations: default_true(),
       always_on_top: false,
       skip_taskbar: false,
       theme: None,
@@ -917,6 +920,7 @@ impl Default for WindowConfig {
       hidden_title: false,
       accept_first_mouse: false,
       tabbing_identifier: None,
+      shadow: false,
     }
   }
 }
@@ -933,7 +937,7 @@ fn default_height() -> f64 {
   600f64
 }
 
-fn default_resizable() -> bool {
+fn default_true() -> bool {
   true
 }
 
@@ -941,22 +945,6 @@ fn default_title() -> String {
   "Tauri App".to_string()
 }
 
-fn default_focus() -> bool {
-  true
-}
-
-fn default_visible() -> bool {
-  true
-}
-
-fn default_decorations() -> bool {
-  true
-}
-
-fn default_file_drop_enabled() -> bool {
-  true
-}
-
 /// A Content-Security-Policy directive source list.
 /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
 #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
@@ -1329,6 +1317,9 @@ pub struct WindowAllowlistConfig {
   /// Allows setting the decorations flag of the window.
   #[serde(default, alias = "set-decorations")]
   pub set_decorations: bool,
+  /// Allows setting the shadow flag of the window.
+  #[serde(default, alias = "set-shadow")]
+  pub set_shadow: bool,
   /// Allows setting the always_on_top flag of the window.
   #[serde(default, alias = "set-always-on-top")]
   pub set_always_on_top: bool,
@@ -1410,6 +1401,7 @@ impl Allowlist for WindowAllowlistConfig {
       set_cursor_icon: true,
       set_cursor_position: true,
       set_ignore_cursor_events: true,
+      set_shadow: true,
       start_dragging: true,
       print: true,
     };
@@ -1441,6 +1433,7 @@ impl Allowlist for WindowAllowlistConfig {
       check_feature!(self, features, hide, "window-hide");
       check_feature!(self, features, close, "window-close");
       check_feature!(self, features, set_decorations, "window-set-decorations");
+      check_feature!(self, features, set_shadow, "window-set-shadow");
       check_feature!(
         self,
         features,
@@ -2376,7 +2369,7 @@ pub struct UpdaterConfig {
   #[serde(default)]
   pub active: bool,
   /// Display built-in dialog or use event system if disabled.
-  #[serde(default = "default_dialog")]
+  #[serde(default = "default_true")]
   pub dialog: bool,
   /// The updater endpoints. TLS is enforced on production.
   ///
@@ -2407,7 +2400,7 @@ impl<'de> Deserialize<'de> for UpdaterConfig {
     struct InnerUpdaterConfig {
       #[serde(default)]
       active: bool,
-      #[serde(default = "default_dialog")]
+      #[serde(default = "default_true")]
       dialog: bool,
       endpoints: Option<Vec<UpdaterEndpoint>>,
       pubkey: Option<String>,
@@ -2437,7 +2430,7 @@ impl Default for UpdaterConfig {
   fn default() -> Self {
     Self {
       active: false,
-      dialog: default_dialog(),
+      dialog: default_true(),
       endpoints: None,
       pubkey: "".into(),
       windows: Default::default(),
@@ -2458,26 +2451,12 @@ pub struct SystemTrayConfig {
   #[serde(default, alias = "icon-as-template")]
   pub icon_as_template: bool,
   /// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
-  #[serde(
-    default = "default_tray_menu_on_left_click",
-    alias = "menu-on-left-click"
-  )]
+  #[serde(default = "default_true", alias = "menu-on-left-click")]
   pub menu_on_left_click: bool,
   /// Title for MacOS tray
   pub title: Option<String>,
 }
 
-fn default_tray_menu_on_left_click() -> bool {
-  true
-}
-
-// We enable the unnecessary_wraps because we need
-// to use an Option for dialog otherwise the CLI schema will mark
-// the dialog as a required field which is not as we default it to true.
-fn default_dialog() -> bool {
-  true
-}
-
 /// General configuration for the iOS target.
 #[skip_serializing_none]
 #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
@@ -3060,6 +3039,7 @@ mod build {
       let hidden_title = self.hidden_title;
       let accept_first_mouse = self.accept_first_mouse;
       let tabbing_identifier = opt_str_lit(self.tabbing_identifier.as_ref());
+      let shadow = self.shadow;
 
       literal_struct!(
         tokens,
@@ -3091,7 +3071,8 @@ mod build {
         title_bar_style,
         hidden_title,
         accept_first_mouse,
-        tabbing_identifier
+        tabbing_identifier,
+        shadow
       );
     }
   }

+ 6 - 4
core/tauri/Cargo.toml

@@ -101,12 +101,12 @@ cocoa = "0.24"
 objc = "0.2"
 
 [target."cfg(windows)".dependencies]
-webview2-com = "0.19.1"
+webview2-com = "0.22"
 win7-notifications = { version = "0.3.1", optional = true }
 
-  [target."cfg(windows)".dependencies.windows]
-  version = "0.39.0"
-  features = [ "Win32_Foundation" ]
+[target."cfg(windows)".dependencies.windows]
+version = "0.44"
+features = [ "Win32_Foundation" ]
 
 [target."cfg(target_os = \"android\")".dependencies]
 paste = "1.0"
@@ -250,6 +250,7 @@ window-all = [
   "window-hide",
   "window-close",
   "window-set-decorations",
+  "window-set-shadow",
   "window-set-always-on-top",
   "window-set-size",
   "window-set-min-size",
@@ -280,6 +281,7 @@ window-show = [ ]
 window-hide = [ ]
 window-close = [ ]
 window-set-decorations = [ ]
+window-set-shadow = [ ]
 window-set-always-on-top = [ ]
 window-set-size = [ ]
 window-set-min-size = [ ]

+ 1 - 0
core/tauri/build.rs

@@ -80,6 +80,7 @@ fn main() {
       "hide",
       "close",
       "set-decorations",
+      "set-shadow",
       "set-always-on-top",
       "set-size",
       "set-min-size",

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
core/tauri/scripts/bundle.global.js


+ 5 - 0
core/tauri/src/endpoints/window.rs

@@ -98,6 +98,8 @@ pub enum WindowManagerCmd {
   Close,
   #[cfg(window_set_decorations)]
   SetDecorations(bool),
+  #[cfg(window_set_shadow)]
+  SetShadow(bool),
   #[cfg(window_set_always_on_top)]
   #[serde(rename_all = "camelCase")]
   SetAlwaysOnTop(bool),
@@ -161,6 +163,7 @@ pub fn into_allowlist_error(variant: &str) -> crate::Error {
     "hide" => crate::Error::ApiNotAllowlisted("window > hide".to_string()),
     "close" => crate::Error::ApiNotAllowlisted("window > close".to_string()),
     "setDecorations" => crate::Error::ApiNotAllowlisted("window > setDecorations".to_string()),
+    "setShadow" => crate::Error::ApiNotAllowlisted("window > setShadow".to_string()),
     "setAlwaysOnTop" => crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string()),
     "setSize" => crate::Error::ApiNotAllowlisted("window > setSize".to_string()),
     "setMinSize" => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()),
@@ -293,6 +296,8 @@ impl Cmd {
       WindowManagerCmd::Close => window.close()?,
       #[cfg(all(desktop, window_set_decorations))]
       WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
+      #[cfg(all(desktop, window_set_shadow))]
+      WindowManagerCmd::SetShadow(enable) => window.set_shadow(enable)?,
       #[cfg(all(desktop, window_set_always_on_top))]
       WindowManagerCmd::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
       #[cfg(all(desktop, window_set_size))]

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

@@ -135,6 +135,7 @@
 //! - **window-hide**: Enables the [`hide` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#hide).
 //! - **window-close**: Enables the [`close` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#close).
 //! - **window-set-decorations**: Enables the [`setDecorations` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setdecorations).
+//! - **window-set-shadow**: Enables the [`setShadow` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setshadow).
 //! - **window-set-always-on-top**: Enables the [`setAlwaysOnTop` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setalwaysontop).
 //! - **window-set-size**: Enables the [`setSize` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setsize).
 //! - **window-set-min-size**: Enables the [`setMinSize` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setminsize).

+ 8 - 0
core/tauri/src/test/mock_runtime.rs

@@ -278,6 +278,10 @@ impl WindowBuilder for MockWindowBuilder {
     self
   }
 
+  fn shadow(self, enable: bool) -> Self {
+    self
+  }
+
   #[cfg(windows)]
   fn parent_window(self, parent: HWND) -> Self {
     self
@@ -502,6 +506,10 @@ impl<T: UserEvent> Dispatch<T> for MockDispatcher {
     Ok(())
   }
 
+  fn set_shadow(&self, shadow: bool) -> Result<()> {
+    Ok(())
+  }
+
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
     Ok(())
   }

+ 32 - 0
core/tauri/src/window.rs

@@ -425,6 +425,21 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
     self
   }
 
+  /// Sets whether or not the window has shadow.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **Windows:**
+  ///   - `false` has no effect on decorated window, shadows are always ON.
+  ///   - `true` will make ndecorated window have a 1px white border,
+  /// and on Windows 11, it will have a rounded corners.
+  /// - **Linux:** Unsupported.
+  #[must_use]
+  pub fn shadow(mut self, enable: bool) -> Self {
+    self.window_builder = self.window_builder.shadow(enable);
+    self
+  }
+
   /// Sets a parent to the window to be created.
   ///
   /// A child window has the WS_CHILD style and is confined to the client area of its parent window.
@@ -1134,6 +1149,23 @@ impl<R: Runtime> Window<R> {
       .map_err(Into::into)
   }
 
+  /// Determines if this window should have shadow.
+  ///
+  /// ## Platform-specific
+  ///
+  /// - **Windows:**
+  ///   - `false` has no effect on decorated window, shadow are always ON.
+  ///   - `true` will make ndecorated window have a 1px white border,
+  /// and on Windows 11, it will have a rounded corners.
+  /// - **Linux:** Unsupported.
+  pub fn set_shadow(&self, enable: bool) -> crate::Result<()> {
+    self
+      .window
+      .dispatcher
+      .set_shadow(enable)
+      .map_err(Into::into)
+  }
+
   /// Determines if this window should always be on top of other windows.
   pub fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> {
     self

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
examples/api/dist/assets/index.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
examples/api/dist/assets/index.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 206 - 166
examples/api/src-tauri/Cargo.lock


+ 0 - 4
examples/api/src-tauri/Cargo.toml

@@ -40,10 +40,6 @@ features = [
   "updater"
 ]
 
-[target."cfg(target_os = \"windows\")".dependencies]
-window-vibrancy = "0.2"
-window-shadows= "0.2"
-
 [features]
 default = [ "custom-protocol" ]
 custom-protocol = [ "tauri/custom-protocol" ]

+ 4 - 8
examples/api/src-tauri/src/lib.rs

@@ -83,18 +83,14 @@ impl AppBuilder {
 
         #[cfg(target_os = "windows")]
         {
-          window_builder = window_builder.transparent(true);
-          window_builder = window_builder.decorations(false);
+          window_builder = window_builder
+            .transparent(true)
+            .shadow(true)
+            .decorations(false);
         }
 
         let window = window_builder.build().unwrap();
 
-        #[cfg(target_os = "windows")]
-        {
-          let _ = window_shadows::set_shadow(&window, true);
-          let _ = window_vibrancy::apply_blur(&window, Some((0, 0, 0, 0)));
-        }
-
         #[cfg(debug_assertions)]
         window.open_devtools();
 

+ 1 - 3
examples/api/src/App.svelte

@@ -368,9 +368,7 @@
   <aside
     id="sidebar"
     class="lt-sm:h-screen lt-sm:shadow-lg lt-sm:shadow lt-sm:transition-transform lt-sm:absolute lt-sm:z-1999
-     {isWindows
-      ? 'bg-darkPrimaryLighter/60 lt-sm:bg-darkPrimaryLighter'
-      : 'bg-darkPrimaryLighter'} transition-colors-250 overflow-hidden grid select-none px-2"
+      bg-darkPrimaryLighter transition-colors-250 overflow-hidden grid select-none px-2"
   >
     <img
       on:click={() => open('https://tauri.app/')}

+ 1 - 0
examples/splashscreen/tauri.conf.json

@@ -42,6 +42,7 @@
         "width": 400,
         "height": 200,
         "decorations": false,
+        "shadow": true,
         "resizable": false,
         "url": "splashscreen.html"
       }

+ 67 - 15
tooling/api/src/window.ts

@@ -27,6 +27,7 @@
  *         "hide": true,
  *         "close": true,
  *         "setDecorations": true,
+ *         "setShadow": true,
  *         "setAlwaysOnTop": true,
  *         "setSize": true,
  *         "setMinSize": true,
@@ -1065,6 +1066,43 @@ class WindowManager extends WebviewWindowHandle {
     })
   }
 
+  /**
+   * Whether or not the window should have shadow.
+   *
+   * #### Platform-specific
+   *
+   * - **Windows:**
+   *   - `false` has no effect on decorated window, shadows are always ON.
+   *   - `true` will make ndecorated window have a 1px white border,
+   * and on Windows 11, it will have a rounded corners.
+   * - **Linux:** Unsupported.
+   *
+   * @example
+   * ```typescript
+   * import { appWindow } from '@tauri-apps/api/window';
+   * await appWindow.setShadow(false);
+   * ```
+   *
+   * @returns A promise indicating the success or failure of the operation.
+   *
+   * @since 2.0
+   */
+  async setShadow(enable: boolean): Promise<void> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'manage',
+        data: {
+          label: this.label,
+          cmd: {
+            type: 'setShadow',
+            payload: enable
+          }
+        }
+      }
+    })
+  }
+
   /**
    * Whether the window should always be on top of other windows.
    * @example
@@ -1159,12 +1197,12 @@ class WindowManager extends WebviewWindowHandle {
             type: 'setMinSize',
             payload: size
               ? {
-                  type: size.type,
-                  data: {
-                    width: size.width,
-                    height: size.height
-                  }
+                type: size.type,
+                data: {
+                  width: size.width,
+                  height: size.height
                 }
+              }
               : null
           }
         }
@@ -1201,12 +1239,12 @@ class WindowManager extends WebviewWindowHandle {
             type: 'setMaxSize',
             payload: size
               ? {
-                  type: size.type,
-                  data: {
-                    width: size.width,
-                    height: size.height
-                  }
+                type: size.type,
+                data: {
+                  width: size.width,
+                  height: size.height
                 }
+              }
               : null
           }
         }
@@ -2025,6 +2063,20 @@ interface WindowOptions {
   alwaysOnTop?: boolean
   /** Whether or not the window icon should be added to the taskbar. */
   skipTaskbar?: boolean
+  /**
+   *  Whether or not the window has shadow.
+   *
+   * #### Platform-specific
+   *
+   * - **Windows:**
+   *   - `false` has no effect on decorated window, shadows are always ON.
+   *   - `true` will make ndecorated window have a 1px white border,
+   * and on Windows 11, it will have a rounded corners.
+   * - **Linux:** Unsupported.
+   *
+   * @since 2.0
+   */
+  shadow?: boolean
   /**
    * Whether the file drop is enabled or not on the webview. By default it is enabled.
    *
@@ -2066,11 +2118,11 @@ function mapMonitor(m: Monitor | null): Monitor | null {
   return m === null
     ? null
     : {
-        name: m.name,
-        scaleFactor: m.scaleFactor,
-        position: new PhysicalPosition(m.position.x, m.position.y),
-        size: new PhysicalSize(m.size.width, m.size.height)
-      }
+      name: m.name,
+      scaleFactor: m.scaleFactor,
+      position: new PhysicalPosition(m.position.x, m.position.y),
+      size: new PhysicalSize(m.size.width, m.size.height)
+    }
 }
 
 /**

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 193 - 159
tooling/cli/Cargo.lock


+ 13 - 0
tooling/cli/schema.json

@@ -118,6 +118,7 @@
             "setMinSize": false,
             "setPosition": false,
             "setResizable": false,
+            "setShadow": false,
             "setSize": false,
             "setSkipTaskbar": false,
             "setTitle": false,
@@ -393,6 +394,7 @@
               "setMinSize": false,
               "setPosition": false,
               "setResizable": false,
+              "setShadow": false,
               "setSize": false,
               "setSkipTaskbar": false,
               "setTitle": false,
@@ -684,6 +686,11 @@
             "string",
             "null"
           ]
+        },
+        "shadow": {
+          "description": "Whether or not the window has shadow.\n\n## Platform-specific\n\n- **Windows:** - `false` has no effect on decorated window, shadow are always ON. - `true` will make ndecorated window have a 1px white border, and on Windows 11, it will have a rounded corners. - **Linux:** Unsupported.",
+          "default": false,
+          "type": "boolean"
         }
       },
       "additionalProperties": false
@@ -1699,6 +1706,7 @@
             "setMinSize": false,
             "setPosition": false,
             "setResizable": false,
+            "setShadow": false,
             "setSize": false,
             "setSkipTaskbar": false,
             "setTitle": false,
@@ -2031,6 +2039,11 @@
           "default": false,
           "type": "boolean"
         },
+        "setShadow": {
+          "description": "Allows setting the shadow flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
         "setAlwaysOnTop": {
           "description": "Allows setting the always_on_top flag of the window.",
           "default": false,

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio