From 93c9c4de2ed19c0cf72c95b897a637c87ca62ed8 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Tue, 24 Sep 2024 22:11:43 +0800 Subject: [PATCH 1/7] feat(macos, window): Add is_always_on_top method to check if a window is always on top - Implemented `is_always_on_top` in `UnownedWindow` for macOS. - Exposed `is_always_on_top` through the cross-platform `Window` API. - Noted that this feature is unsupported on iOS and Android platforms. This change allows developers to query whether a given window is set to always stay on top of other windows, enhancing the platform's window management capabilities. --- src/platform_impl/macos/window.rs | 5 +++++ src/window.rs | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 49d420ea5..0564a8f3f 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -990,6 +990,11 @@ impl UnownedWindow { is_visible == YES } + #[inline] + pub fn is_always_on_top(&self) -> bool { + unsafe { self.ns_window.level() == ffi::kCGFloatingWindowLevelKey } + } + #[inline] pub fn is_maximized(&self) -> bool { self.is_zoomed() diff --git a/src/window.rs b/src/window.rs index 3b9d57c60..abe11c25b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -809,6 +809,16 @@ impl Window { self.window.is_focused() } + /// Indicates whether the window is always on top of other windows. + /// + /// ## Platform-specific + /// + /// - **iOS / Android:** Unsupported. + #[inline] + pub fn is_always_on_top(&self) -> bool { + self.window.is_always_on_top() + } + /// Sets whether the window is resizable or not. /// /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be From 346ec083e65377044e97707da56994668da2a0c9 Mon Sep 17 00:00:00 2001 From: thepoy Date: Wed, 25 Sep 2024 08:08:19 +0800 Subject: [PATCH 2/7] Add is_always_on_top method to check if the window is set to always on top This commit introduces a new public method `is_always_on_top` in the `Window` struct. The method checks whether the `ALWAYS_ON_TOP` flag is present in the `window_flags` of the current window state, and returns a boolean value accordingly. --- src/platform_impl/windows/window.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index a3a1978c6..ea4f2a0dc 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -583,6 +583,14 @@ impl Window { window_state.window_flags.contains(WindowFlags::MAXIMIZED) } + #[inline] + pub fn is_always_on_top(&self) -> bool { + let window_state = self.window_state.lock(); + window_state + .window_flags + .contains(WindowFlags::ALWAYS_ON_TOP) + } + #[inline] pub fn is_minimized(&self) -> bool { unsafe { IsIconic(self.hwnd()) }.as_bool() From 6e2ab65431c14adf150f56c08f5882e97f23c260 Mon Sep 17 00:00:00 2001 From: thepoy Date: Wed, 25 Sep 2024 08:54:03 +0800 Subject: [PATCH 3/7] Update documentation for is_always_on_top to include Linux as unsupported --- src/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.rs b/src/window.rs index abe11c25b..063477e74 100644 --- a/src/window.rs +++ b/src/window.rs @@ -813,7 +813,7 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS / Android:** Unsupported. + /// - **Linux / iOS / Android:** Unsupported. #[inline] pub fn is_always_on_top(&self) -> bool { self.window.is_always_on_top() From 313adf9dda4c4de08358a0f122fb603c5857af75 Mon Sep 17 00:00:00 2001 From: thepoy Date: Wed, 25 Sep 2024 09:44:23 +0800 Subject: [PATCH 4/7] feat(linux): Add is_always_on_top method --- src/platform_impl/linux/window.rs | 13 +++++++++++++ src/window.rs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/platform_impl/linux/window.rs b/src/platform_impl/linux/window.rs index 07a1ca9bc..a458f420e 100644 --- a/src/platform_impl/linux/window.rs +++ b/src/platform_impl/linux/window.rs @@ -60,6 +60,7 @@ pub struct Window { position: Rc<(AtomicI32, AtomicI32)>, size: Rc<(AtomicI32, AtomicI32)>, maximized: Rc, + is_always_on_top: Rc, minimized: Rc, fullscreen: RefCell>, inner_size_constraints: RefCell, @@ -258,11 +259,14 @@ impl Window { let max_clone = maximized.clone(); let minimized = Rc::new(AtomicBool::new(false)); let minimized_clone = minimized.clone(); + let is_always_on_top = Rc::new(AtomicBool::new(attributes.always_on_top)); + let is_always_on_top_clone = is_always_on_top.clone(); window.connect_window_state_event(move |_, event| { let state = event.new_window_state(); max_clone.store(state.contains(WindowState::MAXIMIZED), Ordering::Release); minimized_clone.store(state.contains(WindowState::ICONIFIED), Ordering::Release); + is_always_on_top_clone.store(state.contains(WindowState::ABOVE), Ordering::Release); glib::Propagation::Proceed }); @@ -304,6 +308,7 @@ impl Window { size, maximized, minimized, + is_always_on_top, fullscreen: RefCell::new(attributes.fullscreen), inner_size_constraints: RefCell::new(attributes.inner_size_constraints), preferred_theme: RefCell::new(preferred_theme), @@ -354,11 +359,14 @@ impl Window { let max_clone = maximized.clone(); let minimized = Rc::new(AtomicBool::new(false)); let minimized_clone = minimized.clone(); + let is_always_on_top = Rc::new(AtomicBool::new(false)); + let is_always_on_top_clone = is_always_on_top.clone(); window.connect_window_state_event(move |_, event| { let state = event.new_window_state(); max_clone.store(state.contains(WindowState::MAXIMIZED), Ordering::Release); minimized_clone.store(state.contains(WindowState::ICONIFIED), Ordering::Release); + is_always_on_top_clone.store(state.contains(WindowState::ABOVE), Ordering::Release); glib::Propagation::Proceed }); @@ -383,6 +391,7 @@ impl Window { size, maximized, minimized, + is_always_on_top, fullscreen: RefCell::new(None), inner_size_constraints: RefCell::new(WindowSizeConstraints::default()), preferred_theme: RefCell::new(None), @@ -577,6 +586,10 @@ impl Window { } } + pub fn is_always_on_top(&self) -> bool { + self.is_always_on_top.load(Ordering::Acquire) + } + pub fn is_maximized(&self) -> bool { self.maximized.load(Ordering::Acquire) } diff --git a/src/window.rs b/src/window.rs index 063477e74..abe11c25b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -813,7 +813,7 @@ impl Window { /// /// ## Platform-specific /// - /// - **Linux / iOS / Android:** Unsupported. + /// - **iOS / Android:** Unsupported. #[inline] pub fn is_always_on_top(&self) -> bool { self.window.is_always_on_top() From 1c8b4ae40009ab1adc78f47980df464fcb36ea03 Mon Sep 17 00:00:00 2001 From: thepoy Date: Wed, 25 Sep 2024 09:57:11 +0800 Subject: [PATCH 5/7] add change file --- .changes/is-always-on-top.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/is-always-on-top.md diff --git a/.changes/is-always-on-top.md b/.changes/is-always-on-top.md new file mode 100644 index 000000000..9f1dffbbe --- /dev/null +++ b/.changes/is-always-on-top.md @@ -0,0 +1,5 @@ +--- +"tao": patch +--- + +Add is_always_on_top method to check if a window is always on top on macOS, Linux and Windows. From b0c66f502a2c59d95db373c618599ee18e8e8189 Mon Sep 17 00:00:00 2001 From: thepoy Date: Wed, 25 Sep 2024 10:02:29 +0800 Subject: [PATCH 6/7] Add no-op `is_always_on_top` method for Android and iOS --- src/platform_impl/android/mod.rs | 5 +++++ src/platform_impl/ios/window.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 896f064d5..069272311 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -569,6 +569,11 @@ impl Window { false } + pub fn is_always_on_top(&self) -> bool { + log::warn!("`Window::is_always_on_top` is ignored on Android"); + false + } + pub fn set_resizable(&self, _resizeable: bool) { warn!("`Window::set_resizable` is ignored on Android") } diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 62164ae4b..d24f63d22 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -77,6 +77,11 @@ impl Inner { false } + pub fn is_always_on_top(&self) -> bool { + log::warn!("`Window::is_always_on_top` is ignored on iOS"); + false + } + pub fn request_redraw(&self) { unsafe { if self.gl_or_metal_backed { From e36d4004d9e623e66a2ef25099af69c439347fc3 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 25 Sep 2024 05:16:26 +0300 Subject: [PATCH 7/7] Update .changes/is-always-on-top.md --- .changes/is-always-on-top.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/is-always-on-top.md b/.changes/is-always-on-top.md index 9f1dffbbe..0c69ca131 100644 --- a/.changes/is-always-on-top.md +++ b/.changes/is-always-on-top.md @@ -2,4 +2,4 @@ "tao": patch --- -Add is_always_on_top method to check if a window is always on top on macOS, Linux and Windows. +Add `Window::is_always_on_top` method to check if a window is always on top on macOS, Linux and Windows.