From ceac0451fdb759f0b41e150346bc0c94d92a5639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Didrik=20Nordstr=C3=B6m?= Date: Mon, 7 Feb 2022 15:08:50 -0800 Subject: [PATCH 1/3] MacOS: Expose `Window.[hide/show]_application()` from Tao --- .changes/show-hide-application.md | 7 +++++++ core/tauri-runtime-wry/src/lib.rs | 27 +++++++++++++++++++++++++++ core/tauri-runtime/src/lib.rs | 8 ++++++++ core/tauri/src/test/mock_runtime.rs | 10 ++++++++++ core/tauri/src/window.rs | 20 ++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 .changes/show-hide-application.md diff --git a/.changes/show-hide-application.md b/.changes/show-hide-application.md new file mode 100644 index 000000000000..0c3c3de4279f --- /dev/null +++ b/.changes/show-hide-application.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +--- + +MacOS: Added `Window.show_application` and `Window.hide_application` method, +which shows or hides the entire app. The `Window.show` and `Window.hide` +methods are unaffected by this change. \ No newline at end of file diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index 5512330d926b..92f1453addf3 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -28,6 +28,9 @@ use tauri_runtime::{SystemTray, SystemTrayEvent}; use webview2_com::FocusChangedEventHandler; #[cfg(windows)] use windows::Win32::{Foundation::HWND, System::WinRT::EventRegistrationToken}; + +#[cfg(target_os = "macos")] +use wry::application::platform::macos::EventLoopWindowTargetExtMacOS; #[cfg(all(feature = "system-tray", target_os = "macos"))] use wry::application::platform::macos::{SystemTrayBuilderExtMacOS, SystemTrayExtMacOS}; #[cfg(target_os = "linux")] @@ -1037,6 +1040,10 @@ pub enum WindowMessage { HideMenu, Show, Hide, + #[cfg(target_os = "macos")] + ShowApplication, + #[cfg(target_os = "macos")] + HideApplication, Close, SetDecorations(bool), SetAlwaysOnTop(bool), @@ -1388,6 +1395,22 @@ impl Dispatch for WryDispatcher { ) } + #[cfg(target_os = "macos")] + fn show_application(&self) -> crate::Result<()> { + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::ShowApplication), + ) + } + + #[cfg(target_os = "macos")] + fn hide_application(&self) -> crate::Result<()> { + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::HideApplication), + ) + } + fn close(&self) -> Result<()> { // NOTE: close cannot use the `send_user_message` function because it accesses the event loop callback self @@ -2107,6 +2130,10 @@ fn handle_user_message( WindowMessage::HideMenu => window.hide_menu(), WindowMessage::Show => window.set_visible(true), WindowMessage::Hide => window.set_visible(false), + #[cfg(target_os = "macos")] + WindowMessage::ShowApplication => event_loop.show_application(), + #[cfg(target_os = "macos")] + WindowMessage::HideApplication => event_loop.hide_application(), WindowMessage::Close => panic!("cannot handle `WindowMessage::Close` on the main thread"), WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations), WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top), diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index 26cd65da1a7d..968af0ba2ea4 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -528,6 +528,14 @@ pub trait Dispatch: Debug + Clone + Send + Sync + Sized + 'static /// Hides the window. fn hide(&self) -> Result<()>; + /// Shows the application on MacOS (independent of current window). + #[cfg(target_os = "macos")] + fn show_application(&self) -> crate::Result<()>; + + /// Hides the application on MacOS (independent of current window). + #[cfg(target_os = "macos")] + fn hide_application(&self) -> crate::Result<()>; + /// Closes the window. fn close(&self) -> Result<()>; diff --git a/core/tauri/src/test/mock_runtime.rs b/core/tauri/src/test/mock_runtime.rs index 2ab8a2217a78..9abd86db4235 100644 --- a/core/tauri/src/test/mock_runtime.rs +++ b/core/tauri/src/test/mock_runtime.rs @@ -427,6 +427,16 @@ impl Dispatch for MockDispatcher { Ok(()) } + #[cfg(target_os = "macos")] + fn show_application(&self) -> Result<()> { + Ok(()) + } + + #[cfg(target_os = "macos")] + fn hide_application(&self) -> Result<()> { + Ok(()) + } + fn close(&self) -> Result<()> { Ok(()) } diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index 3427e15b3ae0..a045bdd84b3e 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -1058,6 +1058,26 @@ impl Window { self.window.dispatcher.hide().map_err(Into::into) } + /// Shows the application on MacOS (independent of current window). + #[cfg(target_os = "macos")] + pub fn show_application(&self) -> crate::Result<()> { + self + .window + .dispatcher + .show_application() + .map_err(Into::into) + } + + /// Hides the application on MacOS (independent of current window). + #[cfg(target_os = "macos")] + pub fn hide_application(&self) -> crate::Result<()> { + self + .window + .dispatcher + .hide_application() + .map_err(Into::into) + } + /// Closes this window. /// # Panics /// From bba4ed98ddd984fea686a87bcbd8c1892fdf4023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Didrik=20Nordstr=C3=B6m?= Date: Mon, 7 Feb 2022 15:16:20 -0800 Subject: [PATCH 2/3] MacOS: Expose `Window.set_activation_policy_at_runtime(..)` from Tao --- .changes/set-activation-policy-at-runtime.md | 7 ++++ core/tauri-runtime-wry/src/lib.rs | 37 ++++++++++++++++---- core/tauri-runtime/src/lib.rs | 8 +++++ core/tauri/src/test/mock_runtime.rs | 5 +++ core/tauri/src/window.rs | 16 +++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 .changes/set-activation-policy-at-runtime.md diff --git a/.changes/set-activation-policy-at-runtime.md b/.changes/set-activation-policy-at-runtime.md new file mode 100644 index 000000000000..7bada2d9179e --- /dev/null +++ b/.changes/set-activation-policy-at-runtime.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +--- + +MacOS: Added `Window.set_activation_policy_at_runtime` method, which allows +dynamically changing the activation policy (previously only possible at +application-build time). diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index 92f1453addf3..d3dae10bd48b 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -391,6 +391,16 @@ impl std::fmt::Debug for NativeImageWrapper { } } +#[cfg(target_os = "macos")] +fn to_wry_activation_policy(act_pol: ActivationPolicy) -> WryActivationPolicy { + match act_pol { + ActivationPolicy::Regular => WryActivationPolicy::Regular, + ActivationPolicy::Accessory => WryActivationPolicy::Accessory, + ActivationPolicy::Prohibited => WryActivationPolicy::Prohibited, + _ => unimplemented!(), + } +} + #[cfg(target_os = "macos")] impl From for NativeImageWrapper { fn from(image: NativeImage) -> NativeImageWrapper { @@ -1044,6 +1054,8 @@ pub enum WindowMessage { ShowApplication, #[cfg(target_os = "macos")] HideApplication, + #[cfg(target_os = "macos")] + SetActivationPolicy(ActivationPolicy), Close, SetDecorations(bool), SetAlwaysOnTop(bool), @@ -1411,6 +1423,20 @@ impl Dispatch for WryDispatcher { ) } + #[cfg(target_os = "macos")] + fn set_activation_policy_at_runtime( + &self, + activation_policy: ActivationPolicy, + ) -> crate::Result<()> { + send_user_message( + &self.context, + Message::Window( + self.window_id, + WindowMessage::SetActivationPolicy(activation_policy), + ), + ) + } + fn close(&self) -> Result<()> { // NOTE: close cannot use the `send_user_message` function because it accesses the event loop callback self @@ -1908,12 +1934,7 @@ impl Runtime for Wry { fn set_activation_policy(&mut self, activation_policy: ActivationPolicy) { self .event_loop - .set_activation_policy(match activation_policy { - ActivationPolicy::Regular => WryActivationPolicy::Regular, - ActivationPolicy::Accessory => WryActivationPolicy::Accessory, - ActivationPolicy::Prohibited => WryActivationPolicy::Prohibited, - _ => unimplemented!(), - }); + .set_activation_policy(to_wry_activation_policy(activation_policy)); } fn run_iteration) + 'static>(&mut self, mut callback: F) -> RunIteration { @@ -2134,6 +2155,10 @@ fn handle_user_message( WindowMessage::ShowApplication => event_loop.show_application(), #[cfg(target_os = "macos")] WindowMessage::HideApplication => event_loop.hide_application(), + #[cfg(target_os = "macos")] + WindowMessage::SetActivationPolicy(act_pol) => { + event_loop.set_activation_policy_at_runtime(to_wry_activation_policy(act_pol)) + } WindowMessage::Close => panic!("cannot handle `WindowMessage::Close` on the main thread"), WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations), WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top), diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index 968af0ba2ea4..83c8c635320d 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -261,6 +261,7 @@ pub struct RunIteration { /// Application's activation policy. Corresponds to NSApplicationActivationPolicy. #[cfg(target_os = "macos")] #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))] +#[derive(Debug, Clone)] #[non_exhaustive] pub enum ActivationPolicy { /// Corresponds to NSApplicationActivationPolicyRegular. @@ -536,6 +537,13 @@ pub trait Dispatch: Debug + Clone + Send + Sync + Sized + 'static #[cfg(target_os = "macos")] fn hide_application(&self) -> crate::Result<()>; + /// Sets the activation policy at runtime on MacOS (independent of current window). + #[cfg(target_os = "macos")] + fn set_activation_policy_at_runtime( + &self, + activation_policy: ActivationPolicy, + ) -> crate::Result<()>; + /// Closes the window. fn close(&self) -> Result<()>; diff --git a/core/tauri/src/test/mock_runtime.rs b/core/tauri/src/test/mock_runtime.rs index 9abd86db4235..05b031d71d47 100644 --- a/core/tauri/src/test/mock_runtime.rs +++ b/core/tauri/src/test/mock_runtime.rs @@ -437,6 +437,11 @@ impl Dispatch for MockDispatcher { Ok(()) } + #[cfg(target_os = "macos")] + fn set_activation_policy_at_runtime(&self, _: tauri_runtime::ActivationPolicy) -> Result<()> { + Ok(()) + } + fn close(&self) -> Result<()> { Ok(()) } diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index a045bdd84b3e..f38e9dc4c1c8 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -32,6 +32,9 @@ use crate::{ PageLoadPayload, Runtime, WindowEvent, }; +#[cfg(target_os = "macos")] +use crate::runtime::ActivationPolicy; + use serde::Serialize; #[cfg(windows)] use windows::Win32::Foundation::HWND; @@ -1078,6 +1081,19 @@ impl Window { .map_err(Into::into) } + /// Sets the activation policy at runtime on MacOS (independent of current window). + #[cfg(target_os = "macos")] + pub fn set_activation_policy_at_runtime( + &self, + activation_policy: ActivationPolicy, + ) -> crate::Result<()> { + self + .window + .dispatcher + .set_activation_policy_at_runtime(activation_policy) + .map_err(Into::into) + } + /// Closes this window. /// # Panics /// From 668d12a9c573c3b2ec04f879e47c51c8501b0f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Didrik=20Nordstr=C3=B6m?= Date: Tue, 5 Jul 2022 11:52:47 -0700 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Lorenzo Lewis --- .changes/set-activation-policy-at-runtime.md | 2 +- .changes/show-hide-application.md | 2 +- core/tauri-runtime/src/lib.rs | 6 +++--- core/tauri/src/window.rs | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.changes/set-activation-policy-at-runtime.md b/.changes/set-activation-policy-at-runtime.md index 7bada2d9179e..9c33ae9ee960 100644 --- a/.changes/set-activation-policy-at-runtime.md +++ b/.changes/set-activation-policy-at-runtime.md @@ -2,6 +2,6 @@ "tauri": patch --- -MacOS: Added `Window.set_activation_policy_at_runtime` method, which allows +macOS: Added `Window.set_activation_policy_at_runtime` method, which allows dynamically changing the activation policy (previously only possible at application-build time). diff --git a/.changes/show-hide-application.md b/.changes/show-hide-application.md index 0c3c3de4279f..fa856e47a787 100644 --- a/.changes/show-hide-application.md +++ b/.changes/show-hide-application.md @@ -2,6 +2,6 @@ "tauri": patch --- -MacOS: Added `Window.show_application` and `Window.hide_application` method, +macOS: Added `Window.show_application` and `Window.hide_application` method, which shows or hides the entire app. The `Window.show` and `Window.hide` methods are unaffected by this change. \ No newline at end of file diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index 83c8c635320d..17c9819987a9 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -529,15 +529,15 @@ pub trait Dispatch: Debug + Clone + Send + Sync + Sized + 'static /// Hides the window. fn hide(&self) -> Result<()>; - /// Shows the application on MacOS (independent of current window). + /// Shows the application on macOS (independent of current window). #[cfg(target_os = "macos")] fn show_application(&self) -> crate::Result<()>; - /// Hides the application on MacOS (independent of current window). + /// Hides the application on macOS (independent of current window). #[cfg(target_os = "macos")] fn hide_application(&self) -> crate::Result<()>; - /// Sets the activation policy at runtime on MacOS (independent of current window). + /// Sets the activation policy at runtime on macOS (independent of current window). #[cfg(target_os = "macos")] fn set_activation_policy_at_runtime( &self, diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index f38e9dc4c1c8..517e723b21c0 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -1061,7 +1061,7 @@ impl Window { self.window.dispatcher.hide().map_err(Into::into) } - /// Shows the application on MacOS (independent of current window). + /// Shows the application on macOS (independent of current window). #[cfg(target_os = "macos")] pub fn show_application(&self) -> crate::Result<()> { self @@ -1071,7 +1071,7 @@ impl Window { .map_err(Into::into) } - /// Hides the application on MacOS (independent of current window). + /// Hides the application on macOS (independent of current window). #[cfg(target_os = "macos")] pub fn hide_application(&self) -> crate::Result<()> { self @@ -1081,7 +1081,7 @@ impl Window { .map_err(Into::into) } - /// Sets the activation policy at runtime on MacOS (independent of current window). + /// Sets the activation policy at runtime on macOS (independent of current window). #[cfg(target_os = "macos")] pub fn set_activation_policy_at_runtime( &self,