From 016e122c5f10eb61f8abe052a888950a460e0804 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Tue, 24 Sep 2024 07:58:32 +0800 Subject: [PATCH 1/3] fix(windows): changing the theme activates the window (#978) * Fix changing theme activates the window * Add change file * Combine unsafe blocks --- .changes/windows-theme-active-state.md | 5 +++++ src/platform_impl/windows/dark_mode.rs | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .changes/windows-theme-active-state.md diff --git a/.changes/windows-theme-active-state.md b/.changes/windows-theme-active-state.md new file mode 100644 index 000000000..4471fd7bd --- /dev/null +++ b/.changes/windows-theme-active-state.md @@ -0,0 +1,5 @@ +--- +tao: patch +--- + +Fix changing the theme activates the window on Windows diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index b12f98b4b..85a907c0c 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -12,7 +12,7 @@ use windows::{ Foundation::{BOOL, HANDLE, HMODULE, HWND, WPARAM}, Graphics::Dwm::{DwmSetWindowAttribute, DWMWINDOWATTRIBUTE}, System::LibraryLoader::*, - UI::{Accessibility::*, WindowsAndMessaging::*}, + UI::{Accessibility::*, Input::KeyboardAndMouse::GetActiveWindow, WindowsAndMessaging::*}, }, }; @@ -187,9 +187,14 @@ fn refresh_titlebar_theme_color(hwnd: HWND, is_dark_mode: bool) { &dark_mode as *const BOOL as *const c_void, std::mem::size_of::() as u32, ); + if GetActiveWindow() == hwnd { + DefWindowProcW(hwnd, WM_NCACTIVATE, None, None); + DefWindowProcW(hwnd, WM_NCACTIVATE, WPARAM(true.into()), None); + } else { + DefWindowProcW(hwnd, WM_NCACTIVATE, WPARAM(true.into()), None); + DefWindowProcW(hwnd, WM_NCACTIVATE, None, None); + } } - unsafe { DefWindowProcW(hwnd, WM_NCACTIVATE, None, None) }; - unsafe { DefWindowProcW(hwnd, WM_NCACTIVATE, WPARAM(true.into()), None) }; } } } From 11d83cffd5f50af6271f536e819c12fc611e7691 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 03:17:10 +0300 Subject: [PATCH 2/3] Publish New Versions (#980) Co-authored-by: amrbashir --- .changes/windows-theme-active-state.md | 5 ----- CHANGELOG.md | 4 ++++ Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 .changes/windows-theme-active-state.md diff --git a/.changes/windows-theme-active-state.md b/.changes/windows-theme-active-state.md deleted file mode 100644 index 4471fd7bd..000000000 --- a/.changes/windows-theme-active-state.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -tao: patch ---- - -Fix changing the theme activates the window on Windows diff --git a/CHANGELOG.md b/CHANGELOG.md index e35947c8c..04ed1c6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## \[0.30.2] + +- [`016e122c`](https://github.com/tauri-apps/tao/commit/016e122c5f10eb61f8abe052a888950a460e0804) ([#978](https://github.com/tauri-apps/tao/pull/978) by [@Legend-Master](https://github.com/tauri-apps/tao/../../Legend-Master)) Fix changing the theme activates the window on Windows + ## \[0.30.1] - [`ad652e50`](https://github.com/tauri-apps/tao/commit/ad652e50bfca1195481cd347ccaa486818f9334d) ([#969](https://github.com/tauri-apps/tao/pull/969) by [@CampioneDev](https://github.com/tauri-apps/tao/../../CampioneDev)) On iOS, implement `application:openURL:options:` to handle custom URL schemes. diff --git a/Cargo.toml b/Cargo.toml index c2913aaa0..89fbb557d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tao" -version = "0.30.1" +version = "0.30.2" description = "Cross-platform window manager library." authors = [ "Tauri Programme within The Commons Conservancy", From 2ee007a56a86980d329745eaf7b748fbf30edeac Mon Sep 17 00:00:00 2001 From: thep0y <51874567+thep0y@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:37:51 +0800 Subject: [PATCH 3/3] feat: add `Window::is_always_on_top` method (#981) --- .changes/is-always-on-top.md | 5 +++++ src/platform_impl/android/mod.rs | 5 +++++ src/platform_impl/ios/window.rs | 5 +++++ src/platform_impl/linux/window.rs | 13 +++++++++++++ src/platform_impl/macos/window.rs | 5 +++++ src/platform_impl/windows/window.rs | 8 ++++++++ src/window.rs | 10 ++++++++++ 7 files changed, 51 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..0c69ca131 --- /dev/null +++ b/.changes/is-always-on-top.md @@ -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. 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 { 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/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/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() 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