Skip to content

Commit

Permalink
feat(core): expose always_on_bottom, closes #7847 (#7933)
Browse files Browse the repository at this point in the history
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
aelew and lucasfernog committed Oct 18, 2023
1 parent c085add commit c1ec0f1
Show file tree
Hide file tree
Showing 17 changed files with 154 additions and 41 deletions.
5 changes: 5 additions & 0 deletions .changes/always-on-bottom-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tauri-apps/api": patch:feat
---

Added `setAlwaysOnBottom` function on `Window` and the `alwaysOnBottom` option when creating a window.
5 changes: 5 additions & 0 deletions .changes/always-on-bottom-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-utils': 'minor:feat'
---

Added the `always_on_bottom` option to the window configuration.
7 changes: 7 additions & 0 deletions .changes/always-on-bottom.md
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 20 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1022,6 +1028,7 @@ pub enum WindowMessage {
Close,
SetDecorations(bool),
SetShadow(bool),
SetAlwaysOnBottom(bool),
SetAlwaysOnTop(bool),
SetVisibleOnAllWorkspaces(bool),
SetContentProtected(bool),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions core/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()>;

Expand Down
4 changes: 4 additions & 0 deletions core/tauri-runtime/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2290,6 +2295,7 @@ mod build {
maximized,
visible,
decorations,
always_on_bottom,
always_on_top,
visible_on_all_workspaces,
content_protected,
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions core/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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(())
}
Expand Down
16 changes: 16 additions & 0 deletions core/tauri/src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions core/tauri/src/window/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>);
Expand Down Expand Up @@ -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,
Expand Down
79 changes: 40 additions & 39 deletions examples/api/dist/assets/index.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions examples/api/src/views/Window.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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} />
Expand Down
2 changes: 1 addition & 1 deletion tooling/api/docs/js-api.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions tooling/api/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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. */
Expand Down
5 changes: 5 additions & 0 deletions tooling/cli/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit c1ec0f1

Please sign in to comment.