diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 61799d0394c9..c417c804acbd 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -1381,6 +1381,7 @@ pub enum WindowMessage { SetSizeConstraints(WindowSizeConstraints), SetPosition(Position), SetFullscreen(bool), + SetFullscreenOnMonitor(PhysicalPosition), #[cfg(target_os = "macos")] SetSimpleFullscreen(bool), SetFocus, @@ -2246,6 +2247,16 @@ impl WindowDispatch for WryWindowDispatcher { ) } + fn set_fullscreen_on_monitor(&self, position: PhysicalPosition) -> Result<()> { + send_user_message( + &self.context, + Message::Window( + self.window_id, + WindowMessage::SetFullscreenOnMonitor(position), + ), + ) + } + fn set_fullscreen(&self, fullscreen: bool) -> Result<()> { send_user_message( &self.context, @@ -3419,6 +3430,11 @@ fn handle_user_message( window.set_fullscreen(None) } } + WindowMessage::SetFullscreenOnMonitor(position) => { + if let Some(monitor) = window.monitor_from_point(position.x, position.y) { + window.set_fullscreen(Some(Fullscreen::Borderless(Some(monitor)))) + } + } #[cfg(target_os = "macos")] WindowMessage::SetSimpleFullscreen(enable) => { diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs index 5bf869dcde55..38ad39c4bf4c 100644 --- a/crates/tauri-runtime/src/lib.rs +++ b/crates/tauri-runtime/src/lib.rs @@ -878,6 +878,9 @@ pub trait WindowDispatch: Debug + Clone + Send + Sync + Sized + 's /// Updates the window fullscreen state. fn set_fullscreen(&self, fullscreen: bool) -> Result<()>; + /// Sets the window as fullscreen, on the monitor that contains the specified position. + fn set_fullscreen_on_monitor(&self, position: PhysicalPosition) -> Result<()>; + #[cfg(target_os = "macos")] fn set_simple_fullscreen(&self, enable: bool) -> Result<()>; diff --git a/crates/tauri/build.rs b/crates/tauri/build.rs index d63401ed099e..8c4db2118555 100644 --- a/crates/tauri/build.rs +++ b/crates/tauri/build.rs @@ -99,6 +99,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[ ("set_max_size", false), ("set_position", false), ("set_fullscreen", false), + ("set_fullscreen_on_monitor", false), ("set_simple_fullscreen", false), ("set_focus", false), ("set_focusable", false), diff --git a/crates/tauri/permissions/window/autogenerated/reference.md b/crates/tauri/permissions/window/autogenerated/reference.md index 00158661d0ed..efe203c11129 100644 --- a/crates/tauri/permissions/window/autogenerated/reference.md +++ b/crates/tauri/permissions/window/autogenerated/reference.md @@ -1317,6 +1317,32 @@ Denies the set_fullscreen command without any pre-configured scope. +`core:window:allow-set-fullscreen-on-monitor` + + + + +Enables the set_fullscreen_on_monitor command without any pre-configured scope. + + + + + + + +`core:window:deny-set-fullscreen-on-monitor` + + + + +Denies the set_fullscreen_on_monitor command without any pre-configured scope. + + + + + + + `core:window:allow-set-icon` diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 5fbedd013fb4..4905faeb2716 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -997,6 +997,10 @@ impl WindowDispatch for MockWindowDispatcher { Ok(()) } + fn set_fullscreen_on_monitor(&self, position: PhysicalPosition) -> Result<()> { + Ok(()) + } + #[cfg(target_os = "macos")] fn set_simple_fullscreen(&self, enable: bool) -> Result<()> { Ok(()) diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 47c95628bcc4..f9ffb35a5387 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -1968,6 +1968,15 @@ tauri::Builder::default() .map_err(Into::into) } + /// Sets the window as fullscreen, on the monitor that contains the specified position. + pub fn set_fullscreen_on_monitor(&self, position: PhysicalPosition) -> crate::Result<()> { + self + .window + .dispatcher + .set_fullscreen_on_monitor(position) + .map_err(Into::into) + } + /// Toggles a fullscreen mode that doesn't require a new macOS space. /// Returns a boolean indicating whether the transition was successful (this won't work if the window was already in the native fullscreen). /// diff --git a/crates/tauri/src/window/plugin.rs b/crates/tauri/src/window/plugin.rs index e1fecd9b732d..64a50a68f7e9 100644 --- a/crates/tauri/src/window/plugin.rs +++ b/crates/tauri/src/window/plugin.rs @@ -128,6 +128,7 @@ mod desktop_commands { setter!(set_max_size, Option); setter!(set_position, Position); setter!(set_fullscreen, bool); + setter!(set_fullscreen_on_monitor, PhysicalPosition); setter!(set_simple_fullscreen, bool); setter!(set_focus); setter!(set_focusable, bool); @@ -303,6 +304,7 @@ pub fn init() -> TauriPlugin { desktop_commands::set_size_constraints, desktop_commands::set_position, desktop_commands::set_fullscreen, + desktop_commands::set_fullscreen_on_monitor, desktop_commands::set_simple_fullscreen, desktop_commands::set_focus, desktop_commands::set_focusable, diff --git a/examples/api/src-tauri/capabilities/run-app.json b/examples/api/src-tauri/capabilities/run-app.json index 99a2c118ca37..86211c426832 100644 --- a/examples/api/src-tauri/capabilities/run-app.json +++ b/examples/api/src-tauri/capabilities/run-app.json @@ -52,6 +52,7 @@ "core:window:allow-set-max-size", "core:window:allow-set-position", "core:window:allow-set-fullscreen", + "core:window:allow-set-fullscreen-on-monitor", "core:window:allow-set-simple-fullscreen", "core:window:allow-set-focus", "core:window:allow-set-focusable", diff --git a/examples/api/src/views/Window.svelte b/examples/api/src/views/Window.svelte index 98be2b074c8f..a66d7a2a9133 100644 --- a/examples/api/src/views/Window.svelte +++ b/examples/api/src/views/Window.svelte @@ -7,7 +7,9 @@ PhysicalPosition, Effect, EffectState, - ProgressBarStatus + ProgressBarStatus, + availableMonitors, + currentMonitor, } from '@tauri-apps/api/window' import { WebviewWindow } from '@tauri-apps/api/webviewWindow' @@ -20,6 +22,14 @@ [webview.label]: webview }) + let monitor = $state("") + let selectedMonitor = $state("") + let monitorMap = $state({}) + + availableMonitors().then((response) => { + monitorMap = Object.fromEntries(response.map((m) => [m.name, m])) + }) + let focusable = $state(true) const cursorIconOptions = [ @@ -222,6 +232,11 @@ x = outerPosition.x y = outerPosition.y }) + currentMonitor().then((response) => { + if (response) { + monitor = response.name + } + }) } async function addWindowEventListeners(window) { @@ -501,6 +516,27 @@ > Set focusable to {!focusable} + +
+
{ + if (selectedMonitor) { + webviewMap[selectedWebview].setFullscreenOnMonitor(monitorMap[selectedMonitor].position) + .then((r) => {fullscreen = true}) + } + ev.preventDefault() + }} + > + + +
+
+
+
+ Current Monitor +
+ {monitor} +

Cursor

diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index 8a11d2cc3cb6..b5a75f18d13b 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -1405,6 +1405,13 @@ class Window { }) } + async setFullscreenOnMonitor(position: PhysicalPosition): Promise { + return invoke('plugin:window|set_fullscreen_on_monitor', { + label: this.label, + value: position + }) + } + /** * On macOS, Toggles a fullscreen mode that doesn’t require a new macOS space. Returns a boolean indicating whether the transition was successful (this won’t work if the window was already in the native fullscreen). * This is how fullscreen used to work on macOS in versions before Lion. And allows the user to have a fullscreen window without using another space or taking control over the entire monitor.