diff --git a/Cargo.lock b/Cargo.lock index f33797312..2bf131cba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,7 @@ dependencies = [ "scopeguard", "static_assertions", "windows", + "windows-core", "winit", ] @@ -101,7 +102,7 @@ dependencies = [ "accesskit_unix", "accesskit_windows", "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "winit", ] @@ -1040,7 +1041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.3", + "windows-targets 0.52.6", ] [[package]] @@ -1162,7 +1163,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "thiserror", ] @@ -1575,9 +1576,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "raw-window-handle" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" @@ -2368,31 +2369,32 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.54.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ "windows-core", - "windows-implement", - "windows-interface", - "windows-targets 0.52.3", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.54.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ + "windows-implement", + "windows-interface", "windows-result", - "windows-targets 0.52.3", + "windows-strings", + "windows-targets 0.52.6", ] [[package]] name = "windows-implement" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", @@ -2401,9 +2403,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", @@ -2412,11 +2414,21 @@ dependencies = [ [[package]] name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-targets 0.52.3", + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -2458,7 +2470,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.6", ] [[package]] @@ -2493,17 +2505,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2520,9 +2533,9 @@ checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2538,9 +2551,9 @@ checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2556,9 +2569,15 @@ checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2574,9 +2593,9 @@ checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2592,9 +2611,9 @@ checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2610,9 +2629,9 @@ checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2628,9 +2647,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" @@ -2661,7 +2680,7 @@ dependencies = [ "percent-encoding", "pin-project", "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "redox_syscall 0.4.1", "rustix 0.38.21", "sctk-adwaita", diff --git a/platforms/windows/Cargo.toml b/platforms/windows/Cargo.toml index f0ad52c5f..b2cb366ac 100644 --- a/platforms/windows/Cargo.toml +++ b/platforms/windows/Cargo.toml @@ -16,9 +16,10 @@ accesskit = { version = "0.16.0", path = "../../common" } accesskit_consumer = { version = "0.24.0", path = "../../consumer" } paste = "1.0" static_assertions = "1.1.0" +windows-core = "0.58.0" [dependencies.windows] -version = "0.54" +version = "0.58.0" features = [ "implement", "Win32_Foundation", @@ -36,4 +37,3 @@ features = [ once_cell = "1.13.0" scopeguard = "1.1.0" winit = "0.30" - diff --git a/platforms/windows/examples/hello_world.rs b/platforms/windows/examples/hello_world.rs index e380e99ad..c962ce85d 100644 --- a/platforms/windows/examples/hello_world.rs +++ b/platforms/windows/examples/hello_world.rs @@ -189,6 +189,9 @@ struct SimpleActionHandler { window: HWND, } +unsafe impl Send for SimpleActionHandler {} +unsafe impl Sync for SimpleActionHandler {} + impl ActionHandler for SimpleActionHandler { fn do_action(&mut self, request: ActionRequest) { match request.action { @@ -334,9 +337,9 @@ fn create_window(title: &str, initial_focus: NodeId) -> Result { None, GetModuleHandleW(None).unwrap(), Some(Box::into_raw(create_params) as _), - ) + )? }; - if window.0 == 0 { + if window.is_invalid() { return Err(Error::from_win32()); } @@ -350,11 +353,11 @@ fn main() -> Result<()> { println!("Enable Narrator with [Win]+[Ctrl]+[Enter] (or [Win]+[Enter] on older versions of Windows)."); let window = create_window(WINDOW_TITLE, INITIAL_FOCUS)?; - unsafe { ShowWindow(window, SW_SHOW) }; + let _ = unsafe { ShowWindow(window, SW_SHOW) }; let mut message = MSG::default(); - while unsafe { GetMessageW(&mut message, HWND(0), 0, 0) }.into() { - unsafe { TranslateMessage(&message) }; + while unsafe { GetMessageW(&mut message, HWND::default(), 0, 0) }.into() { + let _ = unsafe { TranslateMessage(&message) }; unsafe { DispatchMessageW(&message) }; } diff --git a/platforms/windows/src/adapter.rs b/platforms/windows/src/adapter.rs index 362b4cdfc..fe25450ab 100644 --- a/platforms/windows/src/adapter.rs +++ b/platforms/windows/src/adapter.rs @@ -21,6 +21,7 @@ use crate::{ filters::filter, node::{NodeWrapper, PlatformNode}, util::QueuedEvent, + window_handle::WindowHandle, }; fn focus_event(context: &Arc, node_id: NodeId) -> QueuedEvent { @@ -140,7 +141,7 @@ const PLACEHOLDER_ROOT_ID: NodeId = NodeId(0); enum State { Inactive { - hwnd: HWND, + hwnd: WindowHandle, is_window_focused: bool, action_handler: Arc, }, @@ -186,7 +187,7 @@ impl Adapter { init_uia(); let state = State::Inactive { - hwnd, + hwnd: hwnd.into(), is_window_focused, action_handler, }; @@ -356,7 +357,7 @@ fn normalize_objid(lparam: LPARAM) -> i32 { } struct WmGetObjectResult { - hwnd: HWND, + hwnd: WindowHandle, wparam: WPARAM, lparam: LPARAM, el: IRawElementProviderSimple, @@ -364,7 +365,7 @@ struct WmGetObjectResult { impl From for LRESULT { fn from(this: WmGetObjectResult) -> Self { - unsafe { UiaReturnRawElementProvider(this.hwnd, this.wparam, this.lparam, &this.el) } + unsafe { UiaReturnRawElementProvider(this.hwnd.0, this.wparam, this.lparam, &this.el) } } } diff --git a/platforms/windows/src/context.rs b/platforms/windows/src/context.rs index d2acbd748..d22466fc0 100644 --- a/platforms/windows/src/context.rs +++ b/platforms/windows/src/context.rs @@ -6,9 +6,8 @@ use accesskit::{ActionHandler, ActionRequest, Point}; use accesskit_consumer::Tree; use std::sync::{atomic::AtomicBool, Arc, Mutex, RwLock, RwLockReadGuard}; -use windows::Win32::Foundation::*; -use crate::util::*; +use crate::{util::*, window_handle::WindowHandle}; pub(crate) trait ActionHandlerNoMut { fn do_action(&self, request: ActionRequest); @@ -29,7 +28,7 @@ impl ActionHandlerNoMut for ActionHandlerWrapper { } pub(crate) struct Context { - pub(crate) hwnd: HWND, + pub(crate) hwnd: WindowHandle, pub(crate) tree: RwLock, pub(crate) action_handler: Arc, pub(crate) is_placeholder: AtomicBool, @@ -37,7 +36,7 @@ pub(crate) struct Context { impl Context { pub(crate) fn new( - hwnd: HWND, + hwnd: WindowHandle, tree: Tree, action_handler: Arc, is_placeholder: bool, diff --git a/platforms/windows/src/lib.rs b/platforms/windows/src/lib.rs index dbd0fb296..7aee09b3e 100644 --- a/platforms/windows/src/lib.rs +++ b/platforms/windows/src/lib.rs @@ -8,6 +8,7 @@ mod filters; mod node; mod text; mod util; +mod window_handle; mod adapter; pub use adapter::{Adapter, QueuedEvents}; diff --git a/platforms/windows/src/node.rs b/platforms/windows/src/node.rs index 06504aa32..f9ecf42a6 100644 --- a/platforms/windows/src/node.rs +++ b/platforms/windows/src/node.rs @@ -614,7 +614,7 @@ impl PlatformNode { } #[allow(non_snake_case)] -impl IRawElementProviderSimple_Impl for PlatformNode { +impl IRawElementProviderSimple_Impl for PlatformNode_Impl { fn ProviderOptions(&self) -> Result { Ok(ProviderOptions_ServerSideProvider) } @@ -634,7 +634,7 @@ impl IRawElementProviderSimple_Impl for PlatformNode { result = window_title(context.hwnd).into(); } UIA_NativeWindowHandlePropertyId => { - result = (context.hwnd.0 as i32).into(); + result = (context.hwnd.0 .0 as i32).into(); } _ => (), } @@ -654,7 +654,7 @@ impl IRawElementProviderSimple_Impl for PlatformNode { fn HostRawElementProvider(&self) -> Result { self.with_tree_state_and_context(|state, context| { if self.is_root(state) { - unsafe { UiaHostProviderFromHwnd(context.hwnd) } + unsafe { UiaHostProviderFromHwnd(context.hwnd.0) } } else { Err(Error::empty()) } @@ -663,7 +663,7 @@ impl IRawElementProviderSimple_Impl for PlatformNode { } #[allow(non_snake_case)] -impl IRawElementProviderFragment_Impl for PlatformNode { +impl IRawElementProviderFragment_Impl for PlatformNode_Impl { fn Navigate(&self, direction: NavigateDirection) -> Result { self.resolve(|node| { let result = match direction { @@ -735,7 +735,7 @@ impl IRawElementProviderFragment_Impl for PlatformNode { } #[allow(non_snake_case)] -impl IRawElementProviderFragmentRoot_Impl for PlatformNode { +impl IRawElementProviderFragmentRoot_Impl for PlatformNode_Impl { fn ElementProviderFromPoint(&self, x: f64, y: f64) -> Result { self.resolve_with_context(|node, context| { let client_top_left = context.client_top_left(); @@ -851,7 +851,7 @@ macro_rules! patterns { } paste! { $(#[allow(non_snake_case)] - impl [< I $base_pattern_id Provider_Impl>] for PlatformNode { + impl [< I $base_pattern_id Provider_Impl>] for PlatformNode_Impl { $(fn $base_property_id(&self) -> Result<$com_type> { self.resolve(|node| { let wrapper = NodeWrapper(&node); diff --git a/platforms/windows/src/tests/mod.rs b/platforms/windows/src/tests/mod.rs index 0d045f088..dc9bba4ef 100644 --- a/platforms/windows/src/tests/mod.rs +++ b/platforms/windows/src/tests/mod.rs @@ -22,6 +22,8 @@ use windows::{ }, }; +use crate::window_handle::WindowHandle; + use super::{ context::{ActionHandlerNoMut, ActionHandlerWrapper}, Adapter, @@ -155,9 +157,9 @@ fn create_window( None, GetModuleHandleW(None).unwrap(), Some(Box::into_raw(create_params) as _), - ) + )? }; - if window.0 == 0 { + if window.is_invalid() { return Err(Error::from_win32()); } @@ -166,13 +168,13 @@ fn create_window( pub(crate) struct Scope { pub(crate) uia: IUIAutomation, - pub(crate) window: HWND, + pub(crate) window: WindowHandle, } impl Scope { pub(crate) fn show_and_focus_window(&self) { - unsafe { ShowWindow(self.window, SW_SHOW) }; - unsafe { SetForegroundWindow(self.window) }; + let _ = unsafe { ShowWindow(self.window.0, SW_SHOW) }; + let _ = unsafe { SetForegroundWindow(self.window.0) }; } } @@ -190,7 +192,7 @@ where { let _lock_guard = MUTEX.lock().unwrap(); - let window_mutex: Mutex> = Mutex::new(None); + let window_mutex: Mutex> = Mutex::new(None); let window_cv = Condvar::new(); thread::scope(|thread_scope| { @@ -206,13 +208,13 @@ where { let mut state = window_mutex.lock().unwrap(); - *state = Some(window); + *state = Some(window.into()); window_cv.notify_one(); } let mut message = MSG::default(); - while unsafe { GetMessageW(&mut message, HWND(0), 0, 0) }.into() { - unsafe { TranslateMessage(&message) }; + while unsafe { GetMessageW(&mut message, HWND::default(), 0, 0) }.into() { + let _ = unsafe { TranslateMessage(&message) }; unsafe { DispatchMessageW(&message) }; } }); @@ -228,7 +230,7 @@ where }; let _window_guard = scopeguard::guard((), |_| { - unsafe { PostMessageW(window, WM_CLOSE, WPARAM(0), LPARAM(0)) }.unwrap() + unsafe { PostMessageW(window.0, WM_CLOSE, WPARAM(0), LPARAM(0)) }.unwrap() }); // We must initialize COM before creating the UIA client. The MTA option @@ -323,7 +325,7 @@ impl FocusEventHandler { } #[allow(non_snake_case)] -impl IUIAutomationFocusChangedEventHandler_Impl for FocusEventHandler { +impl IUIAutomationFocusChangedEventHandler_Impl for FocusEventHandler_Impl { fn HandleFocusChangedEvent(&self, sender: Option<&IUIAutomationElement>) -> Result<()> { self.received.put(sender.unwrap().clone()); Ok(()) diff --git a/platforms/windows/src/tests/simple.rs b/platforms/windows/src/tests/simple.rs index c744b591e..7c324d8cb 100644 --- a/platforms/windows/src/tests/simple.rs +++ b/platforms/windows/src/tests/simple.rs @@ -72,7 +72,7 @@ where #[test] fn has_native_uia() -> Result<()> { scope(|s| { - let has_native_uia: bool = unsafe { UiaHasServerSideProvider(s.window) }.into(); + let has_native_uia: bool = unsafe { UiaHasServerSideProvider(s.window.0) }.into(); assert!(has_native_uia); Ok(()) }) @@ -96,7 +96,7 @@ fn is_button_2(element: &IUIAutomationElement) -> bool { #[test] fn navigation() -> Result<()> { scope(|s| { - let root = unsafe { s.uia.ElementFromHandle(s.window) }?; + let root = unsafe { s.uia.ElementFromHandle(s.window.0) }?; let walker = unsafe { s.uia.ControlViewWalker() }?; // The children of the window include the children that we provide, diff --git a/platforms/windows/src/tests/subclassed.rs b/platforms/windows/src/tests/subclassed.rs index ff3ba298d..4f22e5413 100644 --- a/platforms/windows/src/tests/subclassed.rs +++ b/platforms/windows/src/tests/subclassed.rs @@ -82,7 +82,7 @@ impl ApplicationHandler<()> for TestApplication { let window = event_loop.create_window(window_attributes).unwrap(); let hwnd = match window.window_handle().unwrap().as_raw() { - RawWindowHandle::Win32(handle) => HWND(handle.hwnd.get()), + RawWindowHandle::Win32(handle) => HWND(handle.hwnd.get() as *mut core::ffi::c_void), RawWindowHandle::WinRt(_) => unimplemented!(), _ => unreachable!(), }; diff --git a/platforms/windows/src/text.rs b/platforms/windows/src/text.rs index 55a2f12a3..6f204a9df 100644 --- a/platforms/windows/src/text.rs +++ b/platforms/windows/src/text.rs @@ -323,9 +323,9 @@ impl Clone for PlatformRange { // within this process. This seems a safe assumption for most AccessKit users. #[allow(non_snake_case)] -impl ITextRangeProvider_Impl for PlatformRange { +impl ITextRangeProvider_Impl for PlatformRange_Impl { fn Clone(&self) -> Result { - Ok(self.clone().into()) + Ok(self.this.clone().into()) } fn Compare(&self, other: Option<&ITextRangeProvider>) -> Result { @@ -342,7 +342,7 @@ impl ITextRangeProvider_Impl for PlatformRange { other_endpoint: TextPatternRangeEndpoint, ) -> Result { let other = unsafe { required_param(other)?.as_impl() }; - if std::ptr::eq(other as *const _, self as *const _) { + if std::ptr::eq(other as *const _, &self.this as *const _) { // Comparing endpoints within the same range can be done // safely without upgrading the range. This allows ATs // to determine whether an old range is degenerate even if diff --git a/platforms/windows/src/util.rs b/platforms/windows/src/util.rs index 8d7ceb600..efdb4da16 100644 --- a/platforms/windows/src/util.rs +++ b/platforms/windows/src/util.rs @@ -16,6 +16,8 @@ use windows::{ }, }; +use crate::window_handle::WindowHandle; + pub(crate) struct Variant(VARIANT); impl From for VARIANT { @@ -178,21 +180,21 @@ pub(crate) fn invalid_operation() -> Error { HRESULT(UIA_E_INVALIDOPERATION as _).into() } -pub(crate) fn client_top_left(hwnd: HWND) -> Point { +pub(crate) fn client_top_left(hwnd: WindowHandle) -> Point { let mut result = POINT::default(); // If ClientToScreen fails, that means the window is gone. // That's an unexpected condition, so we should fail loudly. - unsafe { ClientToScreen(hwnd, &mut result) }.unwrap(); + unsafe { ClientToScreen(hwnd.0, &mut result) }.unwrap(); Point::new(result.x.into(), result.y.into()) } -pub(crate) fn window_title(hwnd: HWND) -> Option { +pub(crate) fn window_title(hwnd: WindowHandle) -> Option { // The following is an old hack to get the window caption without ever // sending messages to the window itself, even if the window is in // the same process but possibly a separate thread. This prevents // possible hangs and sluggishness. This hack has been proven to work // over nearly 20 years on every version of Windows back to XP. - let result = unsafe { DefWindowProcW(hwnd, WM_GETTEXTLENGTH, WPARAM(0), LPARAM(0)) }; + let result = unsafe { DefWindowProcW(hwnd.0, WM_GETTEXTLENGTH, WPARAM(0), LPARAM(0)) }; if result.0 <= 0 { return None; } @@ -200,7 +202,7 @@ pub(crate) fn window_title(hwnd: HWND) -> Option { let mut buffer = Vec::::with_capacity(capacity); let result = unsafe { DefWindowProcW( - hwnd, + hwnd.0, WM_GETTEXT, WPARAM(capacity), LPARAM(buffer.as_mut_ptr() as _), diff --git a/platforms/windows/src/window_handle.rs b/platforms/windows/src/window_handle.rs new file mode 100644 index 000000000..0538d5bfc --- /dev/null +++ b/platforms/windows/src/window_handle.rs @@ -0,0 +1,32 @@ +// Copyright 2024 The AccessKit Authors. All rights reserved. +// Licensed under the Apache License, Version 2.0 (found in +// the LICENSE-APACHE file) or the MIT license (found in +// the LICENSE-MIT file), at your option. + +use windows::Win32::Foundation::HWND; + +#[repr(transparent)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct WindowHandle(pub HWND); + +unsafe impl Send for WindowHandle {} +unsafe impl Sync for WindowHandle {} + +impl From for WindowHandle { + fn from(value: HWND) -> Self { + Self(value) + } +} + +impl From for HWND { + fn from(value: WindowHandle) -> Self { + value.0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + static_assertions::assert_impl_all!(WindowHandle: Send, Sync); +} diff --git a/platforms/winit/Cargo.toml b/platforms/winit/Cargo.toml index 288eef6cb..bf63838ff 100644 --- a/platforms/winit/Cargo.toml +++ b/platforms/winit/Cargo.toml @@ -25,7 +25,7 @@ tokio = ["accesskit_unix/tokio"] accesskit = { version = "0.16.0", path = "../../common" } winit = { version = "0.30", default-features = false } rwh_05 = { package = "raw-window-handle", version = "0.5", features = ["std"], optional = true } -rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"], optional = true } +rwh_06 = { package = "raw-window-handle", version = "0.6.2", features = ["std"], optional = true } [target.'cfg(target_os = "windows")'.dependencies] accesskit_windows = { version = "0.22.0", path = "../windows" } diff --git a/platforms/winit/src/platform_impl/windows.rs b/platforms/winit/src/platform_impl/windows.rs index 299878519..8ada48bd7 100644 --- a/platforms/winit/src/platform_impl/windows.rs +++ b/platforms/winit/src/platform_impl/windows.rs @@ -23,13 +23,13 @@ impl Adapter { ) -> Self { #[cfg(feature = "rwh_05")] let hwnd = match window.raw_window_handle() { - RawWindowHandle::Win32(handle) => handle.hwnd as isize, + RawWindowHandle::Win32(handle) => handle.hwnd, RawWindowHandle::WinRt(_) => unimplemented!(), _ => unreachable!(), }; #[cfg(feature = "rwh_06")] let hwnd = match window.window_handle().unwrap().as_raw() { - RawWindowHandle::Win32(handle) => handle.hwnd.get(), + RawWindowHandle::Win32(handle) => handle.hwnd.get() as *mut _, RawWindowHandle::WinRt(_) => unimplemented!(), _ => unreachable!(), };