浏览代码

feat(core): expose `always_on_bottom`, closes #7847 (#7933)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Andre Lew 1 年之前
父节点
当前提交
c1ec0f1551

+ 5 - 0
.changes/always-on-bottom-api.md

@@ -0,0 +1,5 @@
+---
+"@tauri-apps/api": patch:feat
+---
+
+Added `setAlwaysOnBottom` function on `Window` and the `alwaysOnBottom` option when creating a window.

+ 5 - 0
.changes/always-on-bottom-config.md

@@ -0,0 +1,5 @@
+---
+'tauri-utils': 'minor:feat'
+---
+
+Added the `always_on_bottom` option to the window configuration.

+ 7 - 0
.changes/always-on-bottom.md

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

+ 5 - 0
core/tauri-config-schema/schema.json

@@ -440,6 +440,11 @@
           "default": true,
           "type": "boolean"
         },
+        "alwaysOnBottom": {
+          "description": "Whether the window should always be below other windows.",
+          "default": false,
+          "type": "boolean"
+        },
         "alwaysOnTop": {
           "description": "Whether the window should always be on top of other windows.",
           "default": false,

+ 20 - 0
core/tauri-runtime-wry/src/lib.rs

@@ -627,6 +627,7 @@ impl WindowBuilder for WindowBuilderWrapper {
         .fullscreen(config.fullscreen)
         .decorations(config.decorations)
         .maximized(config.maximized)
+        .always_on_bottom(config.always_on_bottom)
         .always_on_top(config.always_on_top)
         .visible_on_all_workspaces(config.visible_on_all_workspaces)
         .content_protected(config.content_protected)
@@ -745,6 +746,11 @@ impl WindowBuilder for WindowBuilderWrapper {
     self
   }
 
+  fn always_on_bottom(mut self, always_on_bottom: bool) -> Self {
+    self.inner = self.inner.with_always_on_bottom(always_on_bottom);
+    self
+  }
+
   fn always_on_top(mut self, always_on_top: bool) -> Self {
     self.inner = self.inner.with_always_on_top(always_on_top);
     self
@@ -1022,6 +1028,7 @@ pub enum WindowMessage {
   Close,
   SetDecorations(bool),
   SetShadow(bool),
+  SetAlwaysOnBottom(bool),
   SetAlwaysOnTop(bool),
   SetVisibleOnAllWorkspaces(bool),
   SetContentProtected(bool),
@@ -1413,6 +1420,16 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
     )
   }
 
+  fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()> {
+    send_user_message(
+      &self.context,
+      Message::Window(
+        self.window_id,
+        WindowMessage::SetAlwaysOnBottom(always_on_bottom),
+      ),
+    )
+  }
+
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
     send_user_message(
       &self.context,
@@ -2289,6 +2306,9 @@ fn handle_user_message<T: UserEvent>(
             #[cfg(target_os = "macos")]
             window.set_has_shadow(_enable);
           }
+          WindowMessage::SetAlwaysOnBottom(always_on_bottom) => {
+            window.set_always_on_bottom(always_on_bottom)
+          }
           WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top),
           WindowMessage::SetVisibleOnAllWorkspaces(visible_on_all_workspaces) => {
             window.set_visible_on_all_workspaces(visible_on_all_workspaces)

+ 3 - 0
core/tauri-runtime/src/lib.rs

@@ -531,6 +531,9 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
   /// Updates the shadow flag.
   fn set_shadow(&self, enable: bool) -> Result<()>;
 
+  /// Updates the window alwaysOnBottom flag.
+  fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
+
   /// Updates the window alwaysOnTop flag.
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
 

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

@@ -240,6 +240,10 @@ pub trait WindowBuilder: WindowBuilderBase {
   #[must_use]
   fn decorations(self, decorations: bool) -> Self;
 
+  /// Whether the window should always be below other windows.
+  #[must_use]
+  fn always_on_bottom(self, always_on_bottom: bool) -> Self;
+
   /// Whether the window should always be on top of other windows.
   #[must_use]
   fn always_on_top(self, always_on_top: bool) -> Self;

+ 6 - 0
core/tauri-utils/src/config.rs

@@ -965,6 +965,9 @@ pub struct WindowConfig {
   /// Whether the window should have borders and bars.
   #[serde(default = "default_true")]
   pub decorations: bool,
+  /// Whether the window should always be below other windows.
+  #[serde(default, alias = "always-on-bottom")]
+  pub always_on_bottom: bool,
   /// Whether the window should always be on top of other windows.
   #[serde(default, alias = "always-on-top")]
   pub always_on_top: bool,
@@ -1057,6 +1060,7 @@ impl Default for WindowConfig {
       maximized: false,
       visible: true,
       decorations: true,
+      always_on_bottom: false,
       always_on_top: false,
       visible_on_all_workspaces: false,
       content_protected: false,
@@ -2249,6 +2253,7 @@ mod build {
       let maximized = self.maximized;
       let visible = self.visible;
       let decorations = self.decorations;
+      let always_on_bottom = self.always_on_bottom;
       let always_on_top = self.always_on_top;
       let visible_on_all_workspaces = self.visible_on_all_workspaces;
       let content_protected = self.content_protected;
@@ -2290,6 +2295,7 @@ mod build {
         maximized,
         visible,
         decorations,
+        always_on_bottom,
         always_on_top,
         visible_on_all_workspaces,
         content_protected,

文件差异内容过多而无法显示
+ 0 - 0
core/tauri/scripts/bundle.global.js


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

@@ -283,6 +283,10 @@ impl WindowBuilder for MockWindowBuilder {
     self
   }
 
+  fn always_on_bottom(self, always_on_bottom: bool) -> Self {
+    self
+  }
+
   fn always_on_top(self, always_on_top: bool) -> Self {
     self
   }
@@ -600,6 +604,10 @@ impl<T: UserEvent> Dispatch<T> for MockDispatcher {
     Ok(())
   }
 
+  fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()> {
+    Ok(())
+  }
+
   fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
     Ok(())
   }

+ 16 - 0
core/tauri/src/window/mod.rs

@@ -614,6 +614,13 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
     self
   }
 
+  /// Whether the window should always be below other windows.
+  #[must_use]
+  pub fn always_on_bottom(mut self, always_on_bottom: bool) -> Self {
+    self.window_builder = self.window_builder.always_on_bottom(always_on_bottom);
+    self
+  }
+
   /// Whether the window should always be on top of other windows.
   #[must_use]
   pub fn always_on_top(mut self, always_on_top: bool) -> Self {
@@ -1880,6 +1887,15 @@ impl<R: Runtime> Window<R> {
     })
   }
 
+  /// Determines if this window should always be below other windows.
+  pub fn set_always_on_bottom(&self, always_on_bottom: bool) -> crate::Result<()> {
+    self
+      .window
+      .dispatcher
+      .set_always_on_bottom(always_on_bottom)
+      .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

+ 2 - 0
core/tauri/src/window/plugin.rs

@@ -140,6 +140,7 @@ mod desktop_commands {
   setter!(set_shadow, bool);
   setter!(set_effects, Option<WindowEffectsConfig>);
   setter!(set_always_on_top, bool);
+  setter!(set_always_on_bottom, bool);
   setter!(set_content_protected, bool);
   setter!(set_size, Size);
   setter!(set_min_size, Option<Size>);
@@ -290,6 +291,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
             desktop_commands::set_shadow,
             desktop_commands::set_effects,
             desktop_commands::set_always_on_top,
+            desktop_commands::set_always_on_bottom,
             desktop_commands::set_content_protected,
             desktop_commands::set_size,
             desktop_commands::set_min_size,

文件差异内容过多而无法显示
+ 0 - 0
examples/api/dist/assets/index.js


+ 6 - 0
examples/api/src/views/Window.svelte

@@ -95,6 +95,7 @@
   let maximized = false
   let decorations = true
   let alwaysOnTop = false
+  let alwaysOnBottom = false
   let contentProtected = true
   let fullscreen = false
   let width = null
@@ -248,6 +249,7 @@
     : windowMap[selectedWindow]?.unmaximize()
   $: windowMap[selectedWindow]?.setDecorations(decorations)
   $: windowMap[selectedWindow]?.setAlwaysOnTop(alwaysOnTop)
+  $: windowMap[selectedWindow]?.setAlwaysOnBottom(alwaysOnBottom)
   $: windowMap[selectedWindow]?.setContentProtected(contentProtected)
   $: windowMap[selectedWindow]?.setFullscreen(fullscreen)
 
@@ -373,6 +375,10 @@
         Always on top
         <input type="checkbox" bind:checked={alwaysOnTop} />
       </label>
+      <label>
+        Always on bottom
+        <input type="checkbox" bind:checked={alwaysOnBottom} />
+      </label>
       <label>
         Content protected
         <input type="checkbox" bind:checked={contentProtected} />

文件差异内容过多而无法显示
+ 0 - 0
tooling/api/docs/js-api.json


+ 20 - 0
tooling/api/src/window.ts

@@ -1115,6 +1115,24 @@ class Window {
     })
   }
 
+  /**
+   * Whether the window should always be below other windows.
+   * @example
+   * ```typescript
+   * import { getCurrent } from '@tauri-apps/api/window';
+   * await getCurrent().setAlwaysOnBottom(true);
+   * ```
+   *
+   * @param alwaysOnBottom Whether the window should always be below other windows or not.
+   * @returns A promise indicating the success or failure of the operation.
+   */
+  async setAlwaysOnBottom(alwaysOnBottom: boolean): Promise<void> {
+    return invoke('plugin:window|set_always_on_bottom', {
+      label: this.label,
+      value: alwaysOnBottom
+    })
+  }
+
   /**
    * Prevents the window contents from being captured by other apps.
    * @example
@@ -1996,6 +2014,8 @@ interface WindowOptions {
   decorations?: boolean
   /** Whether the window should always be on top of other windows or not. */
   alwaysOnTop?: boolean
+  /** Whether the window should always be below other windows. */
+  alwaysOnBottom?: boolean
   /** Prevents the window contents from being captured by other apps. */
   contentProtected?: boolean
   /** Whether or not the window icon should be added to the taskbar. */

+ 5 - 0
tooling/cli/schema.json

@@ -440,6 +440,11 @@
           "default": true,
           "type": "boolean"
         },
+        "alwaysOnBottom": {
+          "description": "Whether the window should always be below other windows.",
+          "default": false,
+          "type": "boolean"
+        },
         "alwaysOnTop": {
           "description": "Whether the window should always be on top of other windows.",
           "default": false,

部分文件因为文件数量过多而无法显示