mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-11 07:55:34 +03:00
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
233e43b0c3
commit
4ab5545b7a
5
.changes/content-protection-api.md
Normal file
5
.changes/content-protection-api.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"api": "minor"
|
||||
---
|
||||
|
||||
Added the `WindowOptions::contentProtected` option and `WebviewWindow#setContentProtected` to change it at runtime.
|
5
.changes/content-protection-utils.md
Normal file
5
.changes/content-protection-utils.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-utils": "patch"
|
||||
---
|
||||
|
||||
Added the `content_protected` option to the window configuration.
|
7
.changes/content-protection.md
Normal file
7
.changes/content-protection.md
Normal file
@ -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.
|
@ -105,6 +105,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -378,6 +379,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -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,
|
||||
@ -1661,6 +1668,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
@ -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);
|
||||
@ -1059,6 +1065,7 @@ pub enum WindowMessage {
|
||||
Close,
|
||||
SetDecorations(bool),
|
||||
SetAlwaysOnTop(bool),
|
||||
SetContentProtected(bool),
|
||||
SetSize(Size),
|
||||
SetMinSize(Option<Size>),
|
||||
SetMaxSize(Option<Size>),
|
||||
@ -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,
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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<()>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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,
|
||||
@ -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(),
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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");
|
||||
@ -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;
|
||||
@ -3072,6 +3087,7 @@ mod build {
|
||||
visible,
|
||||
decorations,
|
||||
always_on_top,
|
||||
content_protected,
|
||||
skip_taskbar,
|
||||
theme,
|
||||
title_bar_style,
|
||||
|
@ -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",
|
||||
@ -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 = [ ]
|
||||
|
@ -81,6 +81,7 @@ fn main() {
|
||||
"close",
|
||||
"set-decorations",
|
||||
"set-always-on-top",
|
||||
"set-content-protected",
|
||||
"set-size",
|
||||
"set-min-size",
|
||||
"set-max-size",
|
||||
|
File diff suppressed because one or more lines are too long
@ -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)]
|
||||
@ -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()),
|
||||
@ -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)]
|
||||
|
@ -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).
|
||||
|
@ -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)
|
||||
}
|
||||
@ -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(())
|
||||
}
|
||||
|
@ -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()?)?;
|
||||
@ -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
|
||||
|
75
examples/api/dist/assets/index.js
vendored
75
examples/api/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
@ -65,7 +65,8 @@ impl AppBuilder {
|
||||
.user_agent("Tauri API")
|
||||
.title("Tauri API Validation")
|
||||
.inner_size(1000., 800.)
|
||||
.min_inner_size(600., 400.);
|
||||
.min_inner_size(600., 400.)
|
||||
.content_protected(true);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
|
@ -66,6 +66,7 @@
|
||||
let maximized = false
|
||||
let decorations = true
|
||||
let alwaysOnTop = false
|
||||
let contentProtected = true
|
||||
let fullscreen = false
|
||||
let width = null
|
||||
let height = null
|
||||
@ -182,6 +183,7 @@
|
||||
: windowMap[selectedWindow]?.unmaximize()
|
||||
$: windowMap[selectedWindow]?.setDecorations(decorations)
|
||||
$: windowMap[selectedWindow]?.setAlwaysOnTop(alwaysOnTop)
|
||||
$: windowMap[selectedWindow]?.setContentProtected(contentProtected)
|
||||
$: windowMap[selectedWindow]?.setFullscreen(fullscreen)
|
||||
|
||||
$: width &&
|
||||
@ -286,6 +288,10 @@
|
||||
Always on top
|
||||
<input type="checkbox" bind:checked={alwaysOnTop} />
|
||||
</label>
|
||||
<label>
|
||||
Content protected
|
||||
<input type="checkbox" bind:checked={contentProtected} />
|
||||
</label>
|
||||
<label>
|
||||
Fullscreen
|
||||
<input type="checkbox" bind:checked={fullscreen} />
|
||||
|
@ -28,6 +28,7 @@
|
||||
* "close": true,
|
||||
* "setDecorations": true,
|
||||
* "setAlwaysOnTop": true,
|
||||
* "setContentProtected": true,
|
||||
* "setSize": true,
|
||||
* "setMinSize": true,
|
||||
* "setMaxSize": true,
|
||||
@ -1142,6 +1143,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
|
||||
@ -2073,6 +2102,10 @@ 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. */
|
||||
contentProtected?: 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
|
||||
/**
|
||||
|
@ -105,6 +105,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -378,6 +379,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -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,
|
||||
@ -1661,6 +1668,7 @@
|
||||
"print": false,
|
||||
"requestUserAttention": false,
|
||||
"setAlwaysOnTop": false,
|
||||
"setContentProtected": false,
|
||||
"setCursorGrab": false,
|
||||
"setCursorIcon": false,
|
||||
"setCursorPosition": false,
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user