From dc2cd71dc81e8cb5750be196ddf0071908f53231 Mon Sep 17 00:00:00 2001 From: Brezak Date: Sun, 29 Dec 2024 20:54:57 +0100 Subject: [PATCH] Make `RawHandleWrapper` fields private to save users from themselves (#16968) # Objective Fixes #16683 ## Solution Make all fields ine `RawHandleWrapper` private. ## Testing - CI - `cargo clippy` - The lightmaps example --- ## Migration Guide The `window_handle` and `dispay_handle` fields on `RawHandleWrapper` are no longer public. Use the newly added getters and setters to manipulate them instead. --- crates/bevy_render/src/view/window/mod.rs | 4 +-- crates/bevy_window/src/raw_handle.rs | 39 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index 14c0fe45be..c39090a205 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -322,8 +322,8 @@ pub fn create_surfaces( .entry(window.entity) .or_insert_with(|| { let surface_target = SurfaceTargetUnsafe::RawHandle { - raw_display_handle: window.handle.display_handle, - raw_window_handle: window.handle.window_handle, + raw_display_handle: window.handle.get_display_handle(), + raw_window_handle: window.handle.get_window_handle(), }; // SAFETY: The window handles in ExtractedWindows will always be valid objects to create surfaces on let surface = unsafe { diff --git a/crates/bevy_window/src/raw_handle.rs b/crates/bevy_window/src/raw_handle.rs index 6084bc728f..d42ae60424 100644 --- a/crates/bevy_window/src/raw_handle.rs +++ b/crates/bevy_window/src/raw_handle.rs @@ -49,9 +49,9 @@ impl Deref for WindowWrapper { pub struct RawHandleWrapper { _window: Arc, /// Raw handle to a window. - pub window_handle: RawWindowHandle, + window_handle: RawWindowHandle, /// Raw handle to the display server. - pub display_handle: RawDisplayHandle, + display_handle: RawDisplayHandle, } impl RawHandleWrapper { @@ -75,6 +75,41 @@ impl RawHandleWrapper { pub unsafe fn get_handle(&self) -> ThreadLockedRawWindowHandleWrapper { ThreadLockedRawWindowHandleWrapper(self.clone()) } + + /// Gets the stored window handle. + pub fn get_window_handle(&self) -> RawWindowHandle { + self.window_handle + } + + /// Sets the window handle. + /// + /// # Safety + /// + /// The passed in [`RawWindowHandle`] must be a valid window handle. + // NOTE: The use of an explicit setter instead of a getter for a mutable reference is to limit the amount of time unsoundness can happen. + // If we handed out a mutable reference the user would have to maintain safety invariants throughout its lifetime. For consistency + // we also prefer to handout copies of the handles instead of immutable references. + pub unsafe fn set_window_handle(&mut self, window_handle: RawWindowHandle) -> &mut Self { + self.window_handle = window_handle; + + self + } + + /// Gets the stored display handle + pub fn get_display_handle(&self) -> RawDisplayHandle { + self.display_handle + } + + /// Sets the display handle. + /// + /// # Safety + /// + /// The passed in [`RawDisplayHandle`] must be a valid display handle. + pub fn set_display_handle(&mut self, display_handle: RawDisplayHandle) -> &mut Self { + self.display_handle = display_handle; + + self + } } // SAFETY: [`RawHandleWrapper`] is just a normal "raw pointer", which doesn't impl Send/Sync. However the pointer is only