Skip to content

Commit

Permalink
feat: add Window::is_always_on_top method (#981)
Browse files Browse the repository at this point in the history
  • Loading branch information
thep0y authored Sep 25, 2024
1 parent 11d83cf commit 2ee007a
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changes/is-always-on-top.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": patch
---

Add `Window::is_always_on_top` method to check if a window is always on top on macOS, Linux and Windows.
5 changes: 5 additions & 0 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
5 changes: 5 additions & 0 deletions src/platform_impl/ios/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions src/platform_impl/linux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub struct Window {
position: Rc<(AtomicI32, AtomicI32)>,
size: Rc<(AtomicI32, AtomicI32)>,
maximized: Rc<AtomicBool>,
is_always_on_top: Rc<AtomicBool>,
minimized: Rc<AtomicBool>,
fullscreen: RefCell<Option<Fullscreen>>,
inner_size_constraints: RefCell<WindowSizeConstraints>,
Expand Down Expand Up @@ -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
});

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
});

Expand All @@ -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),
Expand Down Expand Up @@ -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)
}
Expand Down
5 changes: 5 additions & 0 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 10 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 2ee007a

Please sign in to comment.