Skip to content

Commit

Permalink
feat: add content protection api, closes #5132 (#5513)
Browse files Browse the repository at this point in the history
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
amrbashir and lucasfernog authored Dec 13, 2022
1 parent 233e43b commit 4ab5545
Show file tree
Hide file tree
Showing 20 changed files with 203 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changes/content-protection-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"api": "minor"
---

Added the `WindowOptions::contentProtected` option and `WebviewWindow#setContentProtected` to change it at runtime.
5 changes: 5 additions & 0 deletions .changes/content-protection-utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-utils": "patch"
---

Added the `content_protected` option to the window configuration.
7 changes: 7 additions & 0 deletions .changes/content-protection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"tauri": "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": "If `true`, hides the window icon from the taskbar on Windows and Linux.",
"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 @@ -1059,6 +1065,7 @@ pub enum WindowMessage {
Close,
SetDecorations(bool),
SetAlwaysOnTop(bool),
SetContentProtected(bool),
SetSize(Size),
SetMinSize(Option<Size>),
SetMaxSize(Option<Size>),
Expand Down Expand Up @@ -1436,6 +1443,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 @@ -2399,6 +2416,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 @@ -628,6 +628,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,
/// If `true`, hides the window icon from the taskbar on Windows and Linux.
#[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 @@ -3040,6 +3054,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 @@ -3072,6 +3087,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 @@ -240,6 +240,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 @@ -270,6 +271,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
2 changes: 1 addition & 1 deletion 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 @@ -103,6 +103,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 @@ -164,6 +166,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 @@ -299,6 +304,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 @@ -134,6 +134,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 @@ -489,6 +493,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 @@ -1125,6 +1132,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
Loading

0 comments on commit 4ab5545

Please sign in to comment.