Skip to content

Commit 4ab5545

Browse files
feat: add content protection api, closes #5132 (#5513)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 233e43b commit 4ab5545

File tree

20 files changed

+203
-39
lines changed

20 files changed

+203
-39
lines changed

.changes/content-protection-api.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"api": "minor"
3+
---
4+
5+
Added the `WindowOptions::contentProtected` option and `WebviewWindow#setContentProtected` to change it at runtime.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-utils": "patch"
3+
---
4+
5+
Added the `content_protected` option to the window configuration.

.changes/content-protection.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": "minor"
3+
"tauri-runtime": "minor"
4+
"tauri-runtime-wry": "minor"
5+
---
6+
7+
Added the `content_protected` option when creating a window and `Window::set_content_protected` to change it at runtime.

core/config-schema/schema.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
"print": false,
106106
"requestUserAttention": false,
107107
"setAlwaysOnTop": false,
108+
"setContentProtected": false,
108109
"setCursorGrab": false,
109110
"setCursorIcon": false,
110111
"setCursorPosition": false,
@@ -378,6 +379,7 @@
378379
"print": false,
379380
"requestUserAttention": false,
380381
"setAlwaysOnTop": false,
382+
"setContentProtected": false,
381383
"setCursorGrab": false,
382384
"setCursorIcon": false,
383385
"setCursorPosition": false,
@@ -641,6 +643,11 @@
641643
"default": false,
642644
"type": "boolean"
643645
},
646+
"contentProtected": {
647+
"description": "Prevents the window contents from being captured by other apps.",
648+
"default": false,
649+
"type": "boolean"
650+
},
644651
"skipTaskbar": {
645652
"description": "If `true`, hides the window icon from the taskbar on Windows and Linux.",
646653
"default": false,
@@ -1661,6 +1668,7 @@
16611668
"print": false,
16621669
"requestUserAttention": false,
16631670
"setAlwaysOnTop": false,
1671+
"setContentProtected": false,
16641672
"setCursorGrab": false,
16651673
"setCursorIcon": false,
16661674
"setCursorPosition": false,
@@ -2011,6 +2019,11 @@
20112019
"default": false,
20122020
"type": "boolean"
20132021
},
2022+
"setContentProtected": {
2023+
"description": "Allows preventing the window contents from being captured by other apps.",
2024+
"default": false,
2025+
"type": "boolean"
2026+
},
20142027
"setSize": {
20152028
"description": "Allows setting the window size.",
20162029
"default": false,

core/tauri-runtime-wry/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ impl WindowBuilder for WindowBuilderWrapper {
705705
.decorations(config.decorations)
706706
.maximized(config.maximized)
707707
.always_on_top(config.always_on_top)
708+
.content_protected(config.content_protected)
708709
.skip_taskbar(config.skip_taskbar)
709710
.theme(config.theme);
710711

@@ -839,6 +840,11 @@ impl WindowBuilder for WindowBuilderWrapper {
839840
self
840841
}
841842

843+
fn content_protected(mut self, protected: bool) -> Self {
844+
self.inner = self.inner.with_content_protection(protected);
845+
self
846+
}
847+
842848
#[cfg(windows)]
843849
fn parent_window(mut self, parent: HWND) -> Self {
844850
self.inner = self.inner.with_parent_window(parent);
@@ -1059,6 +1065,7 @@ pub enum WindowMessage {
10591065
Close,
10601066
SetDecorations(bool),
10611067
SetAlwaysOnTop(bool),
1068+
SetContentProtected(bool),
10621069
SetSize(Size),
10631070
SetMinSize(Option<Size>),
10641071
SetMaxSize(Option<Size>),
@@ -1436,6 +1443,16 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
14361443
)
14371444
}
14381445

1446+
fn set_content_protected(&self, protected: bool) -> Result<()> {
1447+
send_user_message(
1448+
&self.context,
1449+
Message::Window(
1450+
self.window_id,
1451+
WindowMessage::SetContentProtected(protected),
1452+
),
1453+
)
1454+
}
1455+
14391456
fn set_size(&self, size: Size) -> Result<()> {
14401457
send_user_message(
14411458
&self.context,
@@ -2399,6 +2416,9 @@ fn handle_user_message<T: UserEvent>(
23992416
}
24002417
WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations),
24012418
WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top),
2419+
WindowMessage::SetContentProtected(protected) => {
2420+
window.set_content_protection(protected)
2421+
}
24022422
WindowMessage::SetSize(size) => {
24032423
window.set_inner_size(SizeWrapper::from(size).0);
24042424
}

core/tauri-runtime/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,9 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
628628
/// Updates the window alwaysOnTop flag.
629629
fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
630630

631+
/// Prevents the window contents from being captured by other apps.
632+
fn set_content_protected(&self, protected: bool) -> Result<()>;
633+
631634
/// Resizes the window.
632635
fn set_size(&self, size: Size) -> Result<()>;
633636

core/tauri-runtime/src/webview.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ pub trait WindowBuilder: WindowBuilderBase {
172172
#[must_use]
173173
fn always_on_top(self, always_on_top: bool) -> Self;
174174

175+
/// Prevents the window contents from being captured by other apps.
176+
#[must_use]
177+
fn content_protected(self, protected: bool) -> Self;
178+
175179
/// Sets the window icon.
176180
fn icon(self, icon: Icon) -> crate::Result<Self>;
177181

core/tauri-utils/src/config.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,9 @@ pub struct WindowConfig {
859859
/// Whether the window should always be on top of other windows.
860860
#[serde(default, alias = "always-on-top")]
861861
pub always_on_top: bool,
862+
/// Prevents the window contents from being captured by other apps.
863+
#[serde(default, alias = "content-protected")]
864+
pub content_protected: bool,
862865
/// If `true`, hides the window icon from the taskbar on Windows and Linux.
863866
#[serde(default, alias = "skip-taskbar")]
864867
pub skip_taskbar: bool,
@@ -908,6 +911,7 @@ impl Default for WindowConfig {
908911
visible: default_visible(),
909912
decorations: default_decorations(),
910913
always_on_top: false,
914+
content_protected: false,
911915
skip_taskbar: false,
912916
theme: None,
913917
title_bar_style: Default::default(),
@@ -1329,6 +1333,9 @@ pub struct WindowAllowlistConfig {
13291333
/// Allows setting the always_on_top flag of the window.
13301334
#[serde(default, alias = "set-always-on-top")]
13311335
pub set_always_on_top: bool,
1336+
/// Allows preventing the window contents from being captured by other apps.
1337+
#[serde(default, alias = "set-content-protected")]
1338+
pub set_content_protected: bool,
13321339
/// Allows setting the window size.
13331340
#[serde(default, alias = "set-size")]
13341341
pub set_size: bool,
@@ -1394,6 +1401,7 @@ impl Allowlist for WindowAllowlistConfig {
13941401
close: true,
13951402
set_decorations: true,
13961403
set_always_on_top: true,
1404+
set_content_protected: false,
13971405
set_size: true,
13981406
set_min_size: true,
13991407
set_max_size: true,
@@ -1444,6 +1452,12 @@ impl Allowlist for WindowAllowlistConfig {
14441452
set_always_on_top,
14451453
"window-set-always-on-top"
14461454
);
1455+
check_feature!(
1456+
self,
1457+
features,
1458+
set_content_protected,
1459+
"window-set-content-protected"
1460+
);
14471461
check_feature!(self, features, set_size, "window-set-size");
14481462
check_feature!(self, features, set_min_size, "window-set-min-size");
14491463
check_feature!(self, features, set_max_size, "window-set-max-size");
@@ -3040,6 +3054,7 @@ mod build {
30403054
let visible = self.visible;
30413055
let decorations = self.decorations;
30423056
let always_on_top = self.always_on_top;
3057+
let content_protected = self.content_protected;
30433058
let skip_taskbar = self.skip_taskbar;
30443059
let theme = opt_lit(self.theme.as_ref());
30453060
let title_bar_style = &self.title_bar_style;
@@ -3072,6 +3087,7 @@ mod build {
30723087
visible,
30733088
decorations,
30743089
always_on_top,
3090+
content_protected,
30753091
skip_taskbar,
30763092
theme,
30773093
title_bar_style,

core/tauri/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ window-all = [
240240
"window-close",
241241
"window-set-decorations",
242242
"window-set-always-on-top",
243+
"window-set-content-protected",
243244
"window-set-size",
244245
"window-set-min-size",
245246
"window-set-max-size",
@@ -270,6 +271,7 @@ window-hide = [ ]
270271
window-close = [ ]
271272
window-set-decorations = [ ]
272273
window-set-always-on-top = [ ]
274+
window-set-content-protected = [ ]
273275
window-set-size = [ ]
274276
window-set-min-size = [ ]
275277
window-set-max-size = [ ]

core/tauri/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ fn main() {
8181
"close",
8282
"set-decorations",
8383
"set-always-on-top",
84+
"set-content-protected",
8485
"set-size",
8586
"set-min-size",
8687
"set-max-size",

0 commit comments

Comments
 (0)