Skip to content

Commit

Permalink
feat: add content protection api, closes #5132
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Oct 30, 2022
1 parent 35264b4 commit a6fbe9f
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .changes/content-protection-utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

Added the `content_protected` option to the window configuration.
8 changes: 8 additions & 0 deletions .changes/content-protection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"tauri": "minor"
"api": "minor"
"tauri-runtime": "minor"
"tauri-runtime-wry": "minor"
---

Added the `content_protected` option when creating a window and `Window::set_content_protected` to change it at runtime.
13 changes: 13 additions & 0 deletions core/config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"print": false,
"requestUserAttention": false,
"setAlwaysOnTop": false,
"setContentProtected": false,
"setCursorGrab": false,
"setCursorIcon": false,
"setCursorPosition": false,
Expand Down Expand Up @@ -378,6 +379,7 @@
"print": false,
"requestUserAttention": false,
"setAlwaysOnTop": false,
"setContentProtected": false,
"setCursorGrab": false,
"setCursorIcon": false,
"setCursorPosition": false,
Expand Down Expand Up @@ -641,6 +643,11 @@
"default": false,
"type": "boolean"
},
"contentProtected": {
"description": "Prevents the window contents from being captured by other apps.",
"default": false,
"type": "boolean"
},
"skipTaskbar": {
"description": "Whether or not the window icon should be added to the taskbar.",
"default": false,
Expand Down Expand Up @@ -1661,6 +1668,7 @@
"print": false,
"requestUserAttention": false,
"setAlwaysOnTop": false,
"setContentProtected": false,
"setCursorGrab": false,
"setCursorIcon": false,
"setCursorPosition": false,
Expand Down Expand Up @@ -2011,6 +2019,11 @@
"default": false,
"type": "boolean"
},
"setContentProtected": {
"description": "Allows preventing the window contents from being captured by other apps.",
"default": false,
"type": "boolean"
},
"setSize": {
"description": "Allows setting the window size.",
"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 @@ -705,6 +705,7 @@ impl WindowBuilder for WindowBuilderWrapper {
.decorations(config.decorations)
.maximized(config.maximized)
.always_on_top(config.always_on_top)
.content_protected(config.content_protected)
.skip_taskbar(config.skip_taskbar)
.theme(config.theme);

Expand Down Expand Up @@ -839,6 +840,11 @@ impl WindowBuilder for WindowBuilderWrapper {
self
}

fn content_protected(mut self, protected: bool) -> Self {
self.inner = self.inner.with_content_protection(protected);
self
}

#[cfg(windows)]
fn parent_window(mut self, parent: HWND) -> Self {
self.inner = self.inner.with_parent_window(parent);
Expand Down Expand Up @@ -1057,6 +1063,7 @@ pub enum WindowMessage {
Close,
SetDecorations(bool),
SetAlwaysOnTop(bool),
SetContentProtected(bool),
SetSize(Size),
SetMinSize(Option<Size>),
SetMaxSize(Option<Size>),
Expand Down Expand Up @@ -1426,6 +1433,16 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
)
}

fn set_content_protected(&self, protected: bool) -> Result<()> {
send_user_message(
&self.context,
Message::Window(
self.window_id,
WindowMessage::SetContentProtected(protected),
),
)
}

fn set_size(&self, size: Size) -> Result<()> {
send_user_message(
&self.context,
Expand Down Expand Up @@ -2387,6 +2404,9 @@ fn handle_user_message<T: UserEvent>(
}
WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations),
WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top),
WindowMessage::SetContentProtected(protected) => {
window.set_content_protection(protected)
}
WindowMessage::SetSize(size) => {
window.set_inner_size(SizeWrapper::from(size).0);
}
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 @@ -623,6 +623,9 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
/// Updates the window alwaysOnTop flag.
fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;

/// Prevents the window contents from being captured by other apps.
fn set_content_protected(&self, protected: bool) -> Result<()>;

/// Resizes the window.
fn set_size(&self, size: Size) -> 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 @@ -172,6 +172,10 @@ pub trait WindowBuilder: WindowBuilderBase {
#[must_use]
fn always_on_top(self, always_on_top: bool) -> Self;

/// Prevents the window contents from being captured by other apps.
#[must_use]
fn content_protected(self, protected: bool) -> Self;

/// Sets the window icon.
fn icon(self, icon: Icon) -> crate::Result<Self>;

Expand Down
16 changes: 16 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,9 @@ pub struct WindowConfig {
/// Whether the window should always be on top of other windows.
#[serde(default, alias = "always-on-top")]
pub always_on_top: bool,
/// Prevents the window contents from being captured by other apps.
#[serde(default, alias = "content-protected")]
pub content_protected: bool,
/// Whether or not the window icon should be added to the taskbar.
#[serde(default, alias = "skip-taskbar")]
pub skip_taskbar: bool,
Expand Down Expand Up @@ -908,6 +911,7 @@ impl Default for WindowConfig {
visible: default_visible(),
decorations: default_decorations(),
always_on_top: false,
content_protected: false,
skip_taskbar: false,
theme: None,
title_bar_style: Default::default(),
Expand Down Expand Up @@ -1329,6 +1333,9 @@ pub struct WindowAllowlistConfig {
/// Allows setting the always_on_top flag of the window.
#[serde(default, alias = "set-always-on-top")]
pub set_always_on_top: bool,
/// Allows preventing the window contents from being captured by other apps.
#[serde(default, alias = "set-content-protected")]
pub set_content_protected: bool,
/// Allows setting the window size.
#[serde(default, alias = "set-size")]
pub set_size: bool,
Expand Down Expand Up @@ -1394,6 +1401,7 @@ impl Allowlist for WindowAllowlistConfig {
close: true,
set_decorations: true,
set_always_on_top: true,
set_content_protected: false,
set_size: true,
set_min_size: true,
set_max_size: true,
Expand Down Expand Up @@ -1444,6 +1452,12 @@ impl Allowlist for WindowAllowlistConfig {
set_always_on_top,
"window-set-always-on-top"
);
check_feature!(
self,
features,
set_content_protected,
"window-set-content-protected"
);
check_feature!(self, features, set_size, "window-set-size");
check_feature!(self, features, set_min_size, "window-set-min-size");
check_feature!(self, features, set_max_size, "window-set-max-size");
Expand Down Expand Up @@ -3039,6 +3053,7 @@ mod build {
let visible = self.visible;
let decorations = self.decorations;
let always_on_top = self.always_on_top;
let content_protected = self.content_protected;
let skip_taskbar = self.skip_taskbar;
let theme = opt_lit(self.theme.as_ref());
let title_bar_style = &self.title_bar_style;
Expand Down Expand Up @@ -3071,6 +3086,7 @@ mod build {
visible,
decorations,
always_on_top,
content_protected,
skip_taskbar,
theme,
title_bar_style,
Expand Down
2 changes: 2 additions & 0 deletions core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ window-all = [
"window-close",
"window-set-decorations",
"window-set-always-on-top",
"window-set-content-protected",
"window-set-size",
"window-set-min-size",
"window-set-max-size",
Expand Down Expand Up @@ -269,6 +270,7 @@ window-hide = [ ]
window-close = [ ]
window-set-decorations = [ ]
window-set-always-on-top = [ ]
window-set-content-protected = [ ]
window-set-size = [ ]
window-set-min-size = [ ]
window-set-max-size = [ ]
Expand Down
1 change: 1 addition & 0 deletions core/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ fn main() {
"close",
"set-decorations",
"set-always-on-top",
"set-content-protected",
"set-size",
"set-min-size",
"set-max-size",
Expand Down
8 changes: 4 additions & 4 deletions core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions core/tauri/src/endpoints/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ pub enum WindowManagerCmd {
#[cfg(window_set_always_on_top)]
#[serde(rename_all = "camelCase")]
SetAlwaysOnTop(bool),
#[cfg(window_set_content_protected)]
SetContentProtected(bool),
#[cfg(window_set_size)]
SetSize(Size),
#[cfg(window_set_min_size)]
Expand Down Expand Up @@ -162,6 +164,9 @@ pub fn into_allowlist_error(variant: &str) -> crate::Error {
"close" => crate::Error::ApiNotAllowlisted("window > close".to_string()),
"setDecorations" => crate::Error::ApiNotAllowlisted("window > setDecorations".to_string()),
"setAlwaysOnTop" => crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string()),
"setContentProtected" => {
crate::Error::ApiNotAllowlisted("window > setContentProtected".to_string())
}
"setSize" => crate::Error::ApiNotAllowlisted("window > setSize".to_string()),
"setMinSize" => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()),
"setMaxSize" => crate::Error::ApiNotAllowlisted("window > setMaxSize".to_string()),
Expand Down Expand Up @@ -295,6 +300,10 @@ impl Cmd {
WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
#[cfg(window_set_always_on_top)]
WindowManagerCmd::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
#[cfg(window_set_content_protected)]
WindowManagerCmd::SetContentProtected(protected) => {
window.set_content_protected(protected)?
}
#[cfg(window_set_size)]
WindowManagerCmd::SetSize(size) => window.set_size(size)?,
#[cfg(window_set_min_size)]
Expand Down
1 change: 1 addition & 0 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
//! - **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-always-on-top**: Enables the [`setAlwaysOnTop` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setalwaysontop).
//! - **window-set-content-protected**: Enables the [`setContentProtected` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setcontentprotected).
//! - **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).
//! - **window-set-max-size**: Enables the [`setMaxSize` API](https://tauri.app/en/docs/api/js/classes/window.WebviewWindow#setmaxsize).
Expand Down
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 @@ -250,6 +250,10 @@ impl WindowBuilder for MockWindowBuilder {
self
}

fn content_protected(self, protected: bool) -> Self {
self
}

fn icon(self, icon: Icon) -> Result<Self> {
Ok(self)
}
Expand Down Expand Up @@ -481,6 +485,10 @@ impl<T: UserEvent> Dispatch<T> for MockDispatcher {
Ok(())
}

fn set_content_protected(&self, protected: bool) -> Result<()> {
Ok(())
}

fn set_size(&self, size: Size) -> Result<()> {
Ok(())
}
Expand Down
16 changes: 16 additions & 0 deletions core/tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,13 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
self
}

/// Whether the window should always be on top of other windows.
#[must_use]
pub fn content_protected(mut self, protected: bool) -> Self {
self.window_builder = self.window_builder.content_protected(protected);
self
}

/// Sets the window icon.
pub fn icon(mut self, icon: Icon) -> crate::Result<Self> {
self.window_builder = self.window_builder.icon(icon.try_into()?)?;
Expand Down Expand Up @@ -1111,6 +1118,15 @@ impl<R: Runtime> Window<R> {
.map_err(Into::into)
}

/// Prevents the window contents from being captured by other apps.
pub fn set_content_protected(&self, protected: bool) -> crate::Result<()> {
self
.window
.dispatcher
.set_content_protected(protected)
.map_err(Into::into)
}

/// Resizes this window.
pub fn set_size<S: Into<Size>>(&self, size: S) -> crate::Result<()> {
self
Expand Down
31 changes: 31 additions & 0 deletions tooling/api/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* "close": true,
* "setDecorations": true,
* "setAlwaysOnTop": true,
* "setContentProtected": true,
* "setSize": true,
* "setMinSize": true,
* "setMaxSize": true,
Expand Down Expand Up @@ -1093,6 +1094,34 @@ class WindowManager extends WebviewWindowHandle {
})
}

/**
* Prevents the window contents from being captured by other apps.
* @example
* ```typescript
* import { appWindow } from '@tauri-apps/api/window';
* await appWindow.setContentProtected(true);
* ```
*
* @returns A promise indicating the success or failure of the operation.
*
* @since 1.2.0
*/
async setContentProtected(protected_: boolean): Promise<void> {
return invokeTauriCommand({
__tauriModule: 'Window',
message: {
cmd: 'manage',
data: {
label: this.label,
cmd: {
type: 'setContentProtected',
payload: protected_
}
}
}
})
}

/**
* Resizes the window with a new inner size.
* @example
Expand Down Expand Up @@ -2020,6 +2049,8 @@ interface WindowOptions {
decorations?: boolean
/** Whether the window should always be on top of other windows or not. */
alwaysOnTop?: boolean
/** Prevents the window contents from being captured by other apps. */
contentPortected?: boolean
/** Whether or not the window icon should be added to the taskbar. */
skipTaskbar?: boolean
/**
Expand Down

0 comments on commit a6fbe9f

Please sign in to comment.