From 5692a26859414c97eff033603906819539908169 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 15:22:05 -0700 Subject: [PATCH 01/12] Make the compile errors go away on X11 Signed-off-by: John Nunley --- Cargo.toml | 8 +- examples/child_window.rs | 19 +- examples/util/fill.rs | 6 +- src/event_loop.rs | 31 +++- src/lib.rs | 10 ++ src/platform/startup_notify.rs | 2 +- src/platform/wayland.rs | 2 +- src/platform/x11.rs | 2 +- src/platform_impl/linux/mod.rs | 47 ++++- .../linux/wayland/event_loop/mod.rs | 23 ++- src/platform_impl/linux/wayland/window/mod.rs | 53 ++++-- src/platform_impl/linux/x11/mod.rs | 22 ++- src/platform_impl/linux/x11/window.rs | 62 +++++-- src/window.rs | 164 +++++++++++++----- 14 files changed, 347 insertions(+), 104 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1e189755a2..752a8576b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ categories = ["gui"] rust-version = "1.65.0" [package.metadata.docs.rs] -features = ["serde"] +features = ["rwh_04", "rwh_05", "rwh_06", "serde"] default-target = "x86_64-unknown-linux-gnu" # These are all tested in CI targets = [ @@ -35,7 +35,7 @@ targets = [ rustdoc-args = ["--cfg", "docsrs"] [features] -default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] +default = ["rwh_06", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] x11 = ["x11-dl", "bytemuck", "percent-encoding", "xkbcommon-dl/x11", "x11rb"] wayland = ["wayland-client", "wayland-backend", "wayland-protocols", "wayland-protocols-plasma", "sctk", "fnv", "memmap2"] wayland-dlopen = ["wayland-backend/dlopen"] @@ -55,7 +55,9 @@ cursor-icon = "1.0.0" log = "0.4" mint = { version = "0.5.6", optional = true } once_cell = "1.12" -raw_window_handle = { package = "raw-window-handle", version = "0.5", features = ["std"] } +rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true } +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 } serde = { version = "1", optional = true, features = ["serde_derive"] } smol_str = "0.2.0" diff --git a/examples/child_window.rs b/examples/child_window.rs index df036075c6..6b30ba6d7a 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -1,8 +1,14 @@ -#[cfg(any(x11_platform, macos_platform, windows_platform))] +#[cfg(all( + feature = "rwh_06", + any(x11_platform, macos_platform, windows_platform) +))] #[path = "util/fill.rs"] mod fill; -#[cfg(any(x11_platform, macos_platform, windows_platform))] +#[cfg(all( + feature = "rwh_06", + any(x11_platform, macos_platform, windows_platform) +))] fn main() -> Result<(), impl std::error::Error> { use std::collections::HashMap; @@ -10,7 +16,7 @@ fn main() -> Result<(), impl std::error::Error> { dpi::{LogicalPosition, LogicalSize, Position}, event::{ElementState, Event, KeyEvent, WindowEvent}, event_loop::{EventLoop, EventLoopWindowTarget}, - window::raw_window_handle::HasRawWindowHandle, + raw_window_handle::HasWindowHandle, window::{Window, WindowBuilder, WindowId}, }; @@ -19,7 +25,7 @@ fn main() -> Result<(), impl std::error::Error> { event_loop: &EventLoopWindowTarget<()>, windows: &mut HashMap, ) { - let parent = parent.raw_window_handle(); + let parent = parent.window_handle().unwrap(); let mut builder = WindowBuilder::new() .with_title("child window") .with_inner_size(LogicalSize::new(200.0f32, 200.0f32)) @@ -81,7 +87,10 @@ fn main() -> Result<(), impl std::error::Error> { }) } -#[cfg(not(any(x11_platform, macos_platform, windows_platform)))] +#[cfg(not(all( + feature = "rwh_06", + any(x11_platform, macos_platform, windows_platform) +)))] fn main() { panic!("This example is supported only on x11, macOS, and Windows."); } diff --git a/examples/util/fill.rs b/examples/util/fill.rs index 7f1f1b1f63..36d3c8b087 100644 --- a/examples/util/fill.rs +++ b/examples/util/fill.rs @@ -7,9 +7,11 @@ //! The `softbuffer` crate is used, largely because of its ease of use. `glutin` or `wgpu` could //! also be used to fill the window buffer, but they are more complicated to use. +// TODO: Once softbuffer uses rwh_06, use that instead. + use winit::window::Window; -#[cfg(not(any(target_os = "android", target_os = "ios")))] +#[cfg(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios"))))] pub(super) fn fill_window(window: &Window) { use softbuffer::{Context, Surface}; use std::cell::RefCell; @@ -80,7 +82,7 @@ pub(super) fn fill_window(window: &Window) { }) } -#[cfg(any(target_os = "android", target_os = "ios"))] +#[cfg(not(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios")))))] pub(super) fn fill_window(_window: &Window) { // No-op on mobile platforms. } diff --git a/src/event_loop.rs b/src/event_loop.rs index 1b9d688831..503bb79e5f 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -12,7 +12,6 @@ use std::ops::Deref; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::{error, fmt}; -use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle}; #[cfg(not(wasm_platform))] use std::time::{Duration, Instant}; #[cfg(wasm_platform)] @@ -248,10 +247,18 @@ impl EventLoop { } } -unsafe impl HasRawDisplayHandle for EventLoop { +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for EventLoop { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + rwh_06::HasDisplayHandle::display_handle(&**self) + } +} + +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for EventLoop { /// Returns a [`raw_window_handle::RawDisplayHandle`] for the event loop. - fn raw_display_handle(&self) -> RawDisplayHandle { - self.event_loop.window_target().p.raw_display_handle() + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + rwh_05::HasRawDisplayHandle::raw_display_handle(&**self) } } @@ -327,10 +334,20 @@ impl EventLoopWindowTarget { } } -unsafe impl HasRawDisplayHandle for EventLoopWindowTarget { +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.p.raw_display_handle_rwh_06()?; + // SAFETY: The display will never be deallocated while the event loop is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) + } +} + +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for EventLoopWindowTarget { /// Returns a [`raw_window_handle::RawDisplayHandle`] for the event loop. - fn raw_display_handle(&self) -> RawDisplayHandle { - self.p.raw_display_handle() + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + self.p.raw_display_handle_rwh_05() } } diff --git a/src/lib.rs b/src/lib.rs index 651681d7a1..c6fb16d7e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,6 +139,16 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![allow(clippy::missing_safety_doc)] +#[cfg(all(not(feature = "rwh_06"), not(feature = "rwh_05"), feature = "rwh_04"))] +#[doc(inline)] +pub use rwh_04 as raw_window_handle; +#[cfg(all(not(feature = "rwh_06"), feature = "rwh_05"))] +#[doc(inline)] +pub use rwh_05 as raw_window_handle; +#[cfg(feature = "rwh_06")] +#[doc(inline)] +pub use rwh_06 as raw_window_handle; + #[allow(unused_imports)] #[macro_use] extern crate log; diff --git a/src/platform/startup_notify.rs b/src/platform/startup_notify.rs index 323c2fe624..35bf8d2e57 100644 --- a/src/platform/startup_notify.rs +++ b/src/platform/startup_notify.rs @@ -74,7 +74,7 @@ impl WindowExtStartupNotify for Window { } } -impl WindowBuilderExtStartupNotify for WindowBuilder { +impl WindowBuilderExtStartupNotify for WindowBuilder<'_> { fn with_activation_token(mut self, token: ActivationToken) -> Self { self.platform_specific.activation_token = Some(token); self diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index ba87651858..abe0dcde26 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -64,7 +64,7 @@ pub trait WindowBuilderExtWayland { fn with_name(self, general: impl Into, instance: impl Into) -> Self; } -impl WindowBuilderExtWayland for WindowBuilder { +impl WindowBuilderExtWayland for WindowBuilder<'_> { #[inline] fn with_name(mut self, general: impl Into, instance: impl Into) -> Self { self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into())); diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 5cbd2fe32a..059f644b90 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -140,7 +140,7 @@ pub trait WindowBuilderExtX11 { fn with_embed_parent_window(self, parent_window_id: XWindow) -> Self; } -impl WindowBuilderExtX11 for WindowBuilder { +impl WindowBuilderExtX11 for WindowBuilder<'_> { #[inline] fn with_x11_visual(mut self, visual_id: XVisualID) -> Self { self.platform_specific.x11.visual_id = Some(visual_id); diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 8fb148564a..d9b4d88ba5 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -11,7 +11,6 @@ use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Mutex}; #[cfg(x11_platform)] use once_cell::sync::Lazy; -use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use smol_str::SmolStr; #[cfg(x11_platform)] @@ -291,7 +290,7 @@ impl Window { #[inline] pub(crate) fn new( window_target: &EventLoopWindowTarget, - attribs: WindowAttributes, + attribs: WindowAttributes<'_>, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { match *window_target { @@ -578,14 +577,36 @@ impl Window { Some(x11_or_wayland!(match self; Window(w) => w.primary_monitor()?; as MonitorHandle)) } + #[cfg(feature = "rwh_04")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - x11_or_wayland!(match self; Window(window) => window.raw_window_handle()) + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + x11_or_wayland!(match self; Window(window) => window.raw_window_handle_rwh_04()) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - x11_or_wayland!(match self; Window(window) => window.raw_display_handle()) + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + x11_or_wayland!(match self; Window(window) => window.raw_window_handle_rwh_05()) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + x11_or_wayland!(match self; Window(window) => window.raw_display_handle_rwh_05()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + x11_or_wayland!(match self; Window(window) => window.raw_window_handle_rwh_06()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + x11_or_wayland!(match self; Window(window) => window.raw_display_handle_rwh_06()) } #[inline] @@ -855,8 +876,18 @@ impl EventLoopWindowTarget { x11_or_wayland!(match self; Self(evlp) => evlp.listen_device_events(allowed)) } - pub fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - x11_or_wayland!(match self; Self(evlp) => evlp.raw_display_handle()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + x11_or_wayland!(match self; Self(evlp) => evlp.raw_display_handle_rwh_05()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + x11_or_wayland!(match self; Self(evlp) => evlp.raw_display_handle_rwh_06()) } pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index c0baead6a1..bb0c52eb34 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -9,8 +9,6 @@ use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle}; - use sctk::reexports::calloop; use sctk::reexports::calloop::Error as CalloopError; use sctk::reexports::client::globals; @@ -653,10 +651,25 @@ impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} - pub fn raw_display_handle(&self) -> RawDisplayHandle { - let mut display_handle = WaylandDisplayHandle::empty(); + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + let mut display_handle = rwh_05::WaylandDisplayHandle::empty(); display_handle.display = self.connection.display().id().as_ptr() as *mut _; - RawDisplayHandle::Wayland(display_handle) + rwh_05::RawDisplayHandle::Wayland(display_handle) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::WaylandDisplayHandle::new(unsafe { + // SAFETY: The display handle will never be null. + let ptr = self.connection.display().id().as_ptr(); + std::ptr::NonNull::new_unchecked(ptr as *mut _) + }) + .into()) } } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index d7b5bbe396..f2e08fa9dc 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -3,10 +3,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; -use raw_window_handle::{ - RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle, -}; - use sctk::reexports::calloop; use sctk::reexports::client::protocol::wl_display::WlDisplay; use sctk::reexports::client::protocol::wl_surface::WlSurface; @@ -84,7 +80,7 @@ pub struct Window { impl Window { pub(crate) fn new( event_loop_window_target: &EventLoopWindowTarget, - attributes: WindowAttributes, + attributes: WindowAttributes<'_>, platform_attributes: PlatformAttributes, ) -> Result { let queue_handle = event_loop_window_target.queue_handle.clone(); @@ -650,18 +646,53 @@ impl Window { None } + #[cfg(feature = "rwh_04")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = WaylandWindowHandle::empty(); + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::WaylandHandle::empty(); window_handle.surface = self.window.wl_surface().id().as_ptr() as *mut _; - RawWindowHandle::Wayland(window_handle) + window_handle.display = self.display.id().as_ptr() as *mut _; + rwh_04::RawWindowHandle::Wayland(window_handle) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - let mut display_handle = WaylandDisplayHandle::empty(); + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::WaylandWindowHandle::empty(); + window_handle.surface = self.window.wl_surface().id().as_ptr() as *mut _; + rwh_05::RawWindowHandle::Wayland(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + let mut display_handle = rwh_05::WaylandDisplayHandle::empty(); display_handle.display = self.display.id().as_ptr() as *mut _; - RawDisplayHandle::Wayland(display_handle) + rwh_05::RawDisplayHandle::Wayland(display_handle) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + Ok(rwh_06::WaylandWindowHandle::new(unsafe { + // SAFETY: Surface pointer will never be null. + let ptr = self.window.wl_surface().id().as_ptr(); + std::ptr::NonNull::new_unchecked(ptr as *mut _) + }) + .into()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::WaylandDisplayHandle::new(unsafe { + // SAFETY: Display pointer will never be null. + let ptr = self.display.id().as_ptr(); + std::ptr::NonNull::new_unchecked(ptr as *mut _) + }) + .into()) } #[inline] diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 037426a036..8c3d7d1b73 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -45,7 +45,6 @@ use std::{ use libc::{self, setlocale, LC_CTYPE}; use atoms::*; -use raw_window_handle::{RawDisplayHandle, XlibDisplayHandle}; use x11rb::x11_utils::X11Error as LogicalError; use x11rb::{ @@ -704,11 +703,24 @@ impl EventLoopWindowTarget { .expect_then_ignore_error("Failed to update device event filter"); } - pub fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let mut display_handle = XlibDisplayHandle::empty(); + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + let mut display_handle = rwh_05::XlibDisplayHandle::empty(); display_handle.display = self.xconn.display as *mut _; display_handle.screen = self.xconn.default_screen_index() as c_int; - RawDisplayHandle::Xlib(display_handle) + display_handle.into() + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + let display_handle = rwh_06::XlibDisplayHandle::new( + // SAFETY: display will never be null + Some(unsafe { std::ptr::NonNull::new_unchecked(self.xconn.display as *mut _) }), + self.xconn.default_screen_index() as c_int, + ); + Ok(display_handle.into()) } pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { @@ -807,7 +819,7 @@ impl Deref for Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - attribs: WindowAttributes, + attribs: WindowAttributes<'_>, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let window = Arc::new(UnownedWindow::new(event_loop, attribs, pl_attribs)?); diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index bab2f8c59f..5db0fc7fe7 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -7,7 +7,6 @@ use std::{ sync::{Arc, Mutex, MutexGuard}, }; -use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XlibDisplayHandle, XlibWindowHandle}; use x11rb::{ connection::Connection, properties::{WmHints, WmHintsState, WmSizeHints, WmSizeHintsSpecification}, @@ -77,7 +76,10 @@ pub enum Visibility { } impl SharedState { - fn new(last_monitor: X11MonitorHandle, window_attributes: &WindowAttributes) -> Mutex { + fn new( + last_monitor: X11MonitorHandle, + window_attributes: &WindowAttributes<'_>, + ) -> Mutex { let visibility = if window_attributes.visible { Visibility::YesWait } else { @@ -143,17 +145,20 @@ impl UnownedWindow { #[allow(clippy::unnecessary_cast)] pub(crate) fn new( event_loop: &EventLoopWindowTarget, - window_attrs: WindowAttributes, + window_attrs: WindowAttributes<'_>, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let xconn = &event_loop.xconn; let atoms = xconn.atoms(); - let root = match window_attrs.parent_window { - Some(RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window, - Some(RawWindowHandle::Xcb(handle)) => handle.window, + #[cfg(feature = "rwh_06")] + let root = match window_attrs.parent_window.map(|x| x.as_raw()) { + Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window, + Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(), Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"), None => event_loop.root, }; + #[cfg(not(feature = "rwh_06"))] + let root = event_loop.root; let mut monitors = leap!(xconn.available_monitors()); let guessed_monitor = if monitors.is_empty() { @@ -1817,20 +1822,53 @@ impl UnownedWindow { // TODO timer } + #[cfg(feature = "rwh_04")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = XlibWindowHandle::empty(); + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::XlibHandle::empty(); + window_handle.display = self.xlib_display(); window_handle.window = self.xlib_window(); window_handle.visual_id = self.visual as c_ulong; - RawWindowHandle::Xlib(window_handle) + rwh_04::RawWindowHandle::Xlib(window_handle) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - let mut display_handle = XlibDisplayHandle::empty(); + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::XlibWindowHandle::empty(); + window_handle.window = self.xlib_window(); + window_handle.visual_id = self.visual as c_ulong; + window_handle.into() + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + let mut display_handle = rwh_05::XlibDisplayHandle::empty(); display_handle.display = self.xlib_display(); display_handle.screen = self.screen_id; - RawDisplayHandle::Xlib(display_handle) + display_handle.into() + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let mut window_handle = rwh_06::XlibWindowHandle::new(self.xlib_window()); + window_handle.visual_id = self.visual as c_ulong; + Ok(window_handle.into()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::XlibDisplayHandle::new( + // SAFETY: The Xlib display pointer will never be null + Some(unsafe { std::ptr::NonNull::new_unchecked(self.xlib_display()) }), + self.screen_id, + ) + .into()) } #[inline] diff --git a/src/window.rs b/src/window.rs index a232062ad1..d599b51cc4 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,10 +1,6 @@ //! The [`Window`] struct and associated types. use std::fmt; -use raw_window_handle::{ - HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, -}; - use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{ExternalError, NotSupportedError, OsError}, @@ -18,9 +14,6 @@ pub use crate::icon::{BadIcon, Icon}; #[doc(inline)] pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError}; -#[doc(inline)] -pub use raw_window_handle; - /// Represents a window. /// /// @@ -122,15 +115,15 @@ impl From for WindowId { /// Object that allows building windows. #[derive(Clone, Default)] #[must_use] -pub struct WindowBuilder { +pub struct WindowBuilder<'a> { /// The attributes to use to create the window. - pub(crate) window: WindowAttributes, + pub(crate) window: WindowAttributes<'a>, // Platform-specific configuration. pub(crate) platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes, } -impl fmt::Debug for WindowBuilder { +impl fmt::Debug for WindowBuilder<'_> { fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result { fmtr.debug_struct("WindowBuilder") .field("window", &self.window) @@ -140,7 +133,7 @@ impl fmt::Debug for WindowBuilder { /// Attributes to use when creating a window. #[derive(Debug, Clone)] -pub struct WindowAttributes { +pub struct WindowAttributes<'a> { pub inner_size: Option, pub min_inner_size: Option, pub max_inner_size: Option, @@ -159,13 +152,14 @@ pub struct WindowAttributes { pub resize_increments: Option, pub content_protected: bool, pub window_level: WindowLevel, - pub parent_window: Option, + #[cfg(feature = "rwh_06")] + pub parent_window: Option>, pub active: bool, } -impl Default for WindowAttributes { +impl<'a> Default for WindowAttributes<'a> { #[inline] - fn default() -> WindowAttributes { + fn default() -> WindowAttributes<'a> { WindowAttributes { inner_size: None, min_inner_size: None, @@ -191,15 +185,17 @@ impl Default for WindowAttributes { } } -impl WindowBuilder { +impl WindowBuilder<'static> { /// Initializes a new builder with default values. #[inline] pub fn new() -> Self { Default::default() } +} +impl<'a> WindowBuilder<'a> { /// Get the current window attributes. - pub fn window_attributes(&self) -> &WindowAttributes { + pub fn window_attributes(&self) -> &WindowAttributes<'a> { &self.window } @@ -456,7 +452,7 @@ impl WindowBuilder { /// /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused. #[inline] - pub fn with_active(mut self, active: bool) -> WindowBuilder { + pub fn with_active(mut self, active: bool) -> Self { self.window.active = active; self } @@ -476,10 +472,62 @@ impl WindowBuilder { /// /// - **X11**: A child window is confined to the client area of its parent window. /// - **Android / iOS / Wayland / Web:** Unsupported. + #[cfg(feature = "rwh_06")] #[inline] - pub unsafe fn with_parent_window(mut self, parent_window: Option) -> Self { - self.window.parent_window = parent_window; - self + pub unsafe fn with_parent_window( + self, + parent_window: Option>, + ) -> WindowBuilder<'_> { + let Self { + window: + WindowAttributes { + inner_size, + min_inner_size, + max_inner_size, + position, + resizable, + enabled_buttons, + title, + fullscreen, + maximized, + visible, + transparent, + decorations, + window_icon, + preferred_theme, + resize_increments, + content_protected, + window_level, + active, + .. + }, + platform_specific, + } = self; + + WindowBuilder { + window: WindowAttributes { + inner_size, + min_inner_size, + max_inner_size, + position, + resizable, + enabled_buttons, + title, + fullscreen, + maximized, + visible, + transparent, + decorations, + window_icon, + preferred_theme, + resize_increments, + content_protected, + window_level, + active, + parent_window, + }, + platform_specific, + } } /// Builds the window. @@ -1505,41 +1553,71 @@ impl Window { } } -unsafe impl HasRawWindowHandle for Window { - /// Returns a [`raw_window_handle::RawWindowHandle`] for the Window - /// - /// ## Platform-specific - /// - /// ### Android - /// - /// Only available after receiving [`Event::Resumed`] and before [`Event::Suspended`]. *If you - /// try to get the handle outside of that period, this function will panic*! - /// - /// Make sure to release or destroy any resources created from this `RawWindowHandle` (ie. Vulkan - /// or OpenGL surfaces) before returning from [`Event::Suspended`], at which point Android will - /// release the underlying window/surface: any subsequent interaction is undefined behavior. - /// - /// [`Event::Resumed`]: crate::event::Event::Resumed - /// [`Event::Suspended`]: crate::event::Event::Suspended - fn raw_window_handle(&self) -> RawWindowHandle { - struct Wrapper(RawWindowHandle); +#[cfg(feature = "rwh_06")] +impl rwh_06::HasWindowHandle for Window { + fn window_handle(&self) -> Result, rwh_06::HandleError> { + struct Wrapper(rwh_06::RawWindowHandle); + unsafe impl Send for Wrapper {} + + let raw = self + .window + .maybe_wait_on_main(|w| w.raw_window_handle_rwh_06().map(Wrapper))? + .0; + + // SAFETY: The window handle will never be deallocated while the window is alive. + Ok(unsafe { rwh_06::WindowHandle::borrow_raw(raw) }) + } +} + +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for Window { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + struct Wrapper(rwh_06::RawDisplayHandle); + unsafe impl Send for Wrapper {} + + let raw = self + .window + .maybe_wait_on_main(|w| w.raw_display_handle_rwh_06().map(Wrapper))? + .0; + + // SAFETY: The window handle will never be deallocated while the window is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) + } +} + +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawWindowHandle for Window { + fn raw_window_handle(&self) -> rwh_05::RawWindowHandle { + struct Wrapper(rwh_05::RawWindowHandle); unsafe impl Send for Wrapper {} self.window - .maybe_wait_on_main(|w| Wrapper(w.raw_window_handle())) + .maybe_wait_on_main(|w| Wrapper(w.raw_window_handle_rwh_05())) .0 } } -unsafe impl HasRawDisplayHandle for Window { +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for Window { /// Returns a [`raw_window_handle::RawDisplayHandle`] used by the [`EventLoop`] that /// created a window. /// /// [`EventLoop`]: crate::event_loop::EventLoop - fn raw_display_handle(&self) -> RawDisplayHandle { - struct Wrapper(RawDisplayHandle); + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + struct Wrapper(rwh_05::RawDisplayHandle); + unsafe impl Send for Wrapper {} + self.window + .maybe_wait_on_main(|w| Wrapper(w.raw_display_handle_rwh_05())) + .0 + } +} + +#[cfg(feature = "rwh_04")] +unsafe impl rwh_04::HasRawWindowHandle for Window { + fn raw_window_handle(&self) -> rwh_04::RawWindowHandle { + struct Wrapper(rwh_04::RawWindowHandle); unsafe impl Send for Wrapper {} self.window - .maybe_wait_on_main(|w| Wrapper(w.raw_display_handle())) + .maybe_wait_on_main(|w| Wrapper(w.raw_window_handle_rwh_04())) .0 } } From ebab7cb36f820a21068311b79c8accc5844079a1 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 15:30:40 -0700 Subject: [PATCH 02/12] Make the errors go away on macOS Signed-off-by: John Nunley --- src/platform/macos.rs | 50 +++++++-------- src/platform_impl/macos/event_loop.rs | 16 ++++- src/platform_impl/macos/window.rs | 91 +++++++++++++++++---------- 3 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/platform/macos.rs b/src/platform/macos.rs index d3fedeb116..0fb26716e2 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -183,92 +183,88 @@ pub enum ActivationPolicy { /// - `with_fullsize_content_view` pub trait WindowBuilderExtMacOS { /// Enables click-and-drag behavior for the entire window, not just the titlebar. - fn with_movable_by_window_background(self, movable_by_window_background: bool) - -> WindowBuilder; + fn with_movable_by_window_background(self, movable_by_window_background: bool) -> Self; /// Makes the titlebar transparent and allows the content to appear behind it. - fn with_titlebar_transparent(self, titlebar_transparent: bool) -> WindowBuilder; + fn with_titlebar_transparent(self, titlebar_transparent: bool) -> Self; /// Hides the window title. - fn with_title_hidden(self, title_hidden: bool) -> WindowBuilder; + fn with_title_hidden(self, title_hidden: bool) -> Self; /// Hides the window titlebar. - fn with_titlebar_hidden(self, titlebar_hidden: bool) -> WindowBuilder; + fn with_titlebar_hidden(self, titlebar_hidden: bool) -> Self; /// Hides the window titlebar buttons. - fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> WindowBuilder; + fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> Self; /// Makes the window content appear behind the titlebar. - fn with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder; - fn with_disallow_hidpi(self, disallow_hidpi: bool) -> WindowBuilder; - fn with_has_shadow(self, has_shadow: bool) -> WindowBuilder; + fn with_fullsize_content_view(self, fullsize_content_view: bool) -> Self; + fn with_disallow_hidpi(self, disallow_hidpi: bool) -> Self; + fn with_has_shadow(self, has_shadow: bool) -> Self; /// Window accepts click-through mouse events. - fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> WindowBuilder; + fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> Self; /// Defines the window tabbing identifier. /// /// - fn with_tabbing_identifier(self, identifier: &str) -> WindowBuilder; + fn with_tabbing_identifier(self, identifier: &str) -> Self; /// Set how the Option keys are interpreted. /// /// See [`WindowExtMacOS::set_option_as_alt`] for details on what this means if set. - fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> WindowBuilder; + fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self; } -impl WindowBuilderExtMacOS for WindowBuilder { +impl WindowBuilderExtMacOS for WindowBuilder<'_> { #[inline] - fn with_movable_by_window_background( - mut self, - movable_by_window_background: bool, - ) -> WindowBuilder { + fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self { self.platform_specific.movable_by_window_background = movable_by_window_background; self } #[inline] - fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> WindowBuilder { + fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self { self.platform_specific.titlebar_transparent = titlebar_transparent; self } #[inline] - fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> WindowBuilder { + fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self { self.platform_specific.titlebar_hidden = titlebar_hidden; self } #[inline] - fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> WindowBuilder { + fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self { self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden; self } #[inline] - fn with_title_hidden(mut self, title_hidden: bool) -> WindowBuilder { + fn with_title_hidden(mut self, title_hidden: bool) -> Self { self.platform_specific.title_hidden = title_hidden; self } #[inline] - fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> WindowBuilder { + fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self { self.platform_specific.fullsize_content_view = fullsize_content_view; self } #[inline] - fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> WindowBuilder { + fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self { self.platform_specific.disallow_hidpi = disallow_hidpi; self } #[inline] - fn with_has_shadow(mut self, has_shadow: bool) -> WindowBuilder { + fn with_has_shadow(mut self, has_shadow: bool) -> Self { self.platform_specific.has_shadow = has_shadow; self } #[inline] - fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> WindowBuilder { + fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self { self.platform_specific.accepts_first_mouse = accepts_first_mouse; self } #[inline] - fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> WindowBuilder { + fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self { self.platform_specific .tabbing_identifier .replace(tabbing_identifier.to_string()); @@ -276,7 +272,7 @@ impl WindowBuilderExtMacOS for WindowBuilder { } #[inline] - fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> WindowBuilder { + fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self { self.platform_specific.option_as_alt = option_as_alt; self } diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 0fca45aded..fc56b11d37 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -21,7 +21,6 @@ use icrate::Foundation::MainThreadMarker; use objc2::rc::{autoreleasepool, Id}; use objc2::runtime::NSObjectProtocol; use objc2::{msg_send_id, ClassType}; -use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; use super::appkit::{NSApp, NSApplication, NSApplicationActivationPolicy, NSEvent, NSWindow}; use crate::{ @@ -89,9 +88,20 @@ impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()) + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::AppKit(rwh_05::AppKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::AppKit( + rwh_06::AppKitDisplayHandle::new(), + )) } pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 0d58a55f7e..be753cb344 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -7,10 +7,6 @@ use std::os::raw::c_void; use std::ptr::NonNull; use std::sync::{Mutex, MutexGuard}; -use raw_window_handle::{ - AppKitDisplayHandle, AppKitWindowHandle, RawDisplayHandle, RawWindowHandle, -}; - use crate::{ dpi::{ LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical, @@ -67,7 +63,7 @@ impl Drop for Window { impl Window { pub(crate) fn new( _window_target: &EventLoopWindowTarget, - attributes: WindowAttributes, + attributes: WindowAttributes<'_>, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let mtm = MainThreadMarker::new() @@ -293,7 +289,7 @@ impl Drop for SharedStateMutexGuard<'_> { impl WinitWindow { #[allow(clippy::type_complexity)] fn new( - attrs: WindowAttributes, + attrs: WindowAttributes<'_>, pl_attrs: PlatformSpecificWindowBuilderAttributes, ) -> Result<(Id, Id), RootOsError> { trace_scope!("WinitWindow::new"); @@ -452,29 +448,28 @@ impl WinitWindow { }) .ok_or_else(|| os_error!(OsError::CreationError("Couldn't create `NSWindow`")))?; - match attrs.parent_window { - Some(RawWindowHandle::AppKit(handle)) => { + #[cfg(feature = "rwh_06")] + match attrs.parent_window.map(|parent| parent.as_raw()) { + Some(rwh_06::RawWindowHandle::AppKit(handle)) => { // SAFETY: Caller ensures the pointer is valid or NULL - let parent: Id = match unsafe { Id::retain(handle.ns_window.cast()) } { - Some(window) => window, - None => { - // SAFETY: Caller ensures the pointer is valid or NULL - let parent_view: Id = - match unsafe { Id::retain(handle.ns_view.cast()) } { - Some(view) => view, - None => { - return Err(os_error!(OsError::CreationError( - "raw window handle should be non-empty" - ))) - } - }; - parent_view.window().ok_or_else(|| { - os_error!(OsError::CreationError( - "parent view should be installed in a window" - )) - })? - } + let parent = { + // SAFETY: Caller ensures the pointer is valid or NULL + let parent_view: Id = + match unsafe { Id::retain(handle.ns_view.as_ptr().cast()) } { + Some(view) => view, + None => { + return Err(os_error!(OsError::CreationError( + "raw window handle should be non-empty" + ))) + } + }; + parent_view.window().ok_or_else(|| { + os_error!(OsError::CreationError( + "parent view should be installed in a window" + )) + })? }; + // SAFETY: We know that there are no parent -> child -> parent cycles since the only place in `winit` // where we allow making a window a child window is right here, just after it's been created. unsafe { parent.addChildWindow(&this, NSWindowOrderingMode::NSWindowAbove) }; @@ -1352,17 +1347,49 @@ impl WinitWindow { Some(monitor) } + #[cfg(feature = "rwh_04")] + #[inline] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::AppKitHandle::empty(); + window_handle.ns_window = self as *const Self as *mut _; + window_handle.ns_view = Id::as_ptr(&self.contentView()) as *mut _; + rwh_04::RawWindowHandle::AppKit(window_handle) + } + + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = AppKitWindowHandle::empty(); + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::AppKitWindowHandle::empty(); window_handle.ns_window = self as *const Self as *mut _; window_handle.ns_view = Id::as_ptr(&self.contentView()) as *mut _; - RawWindowHandle::AppKit(window_handle) + rwh_05::RawWindowHandle::AppKit(window_handle) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()) + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::AppKit(rwh_05::AppKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let window_handle = rwh_06::AppKitWindowHandle::new(unsafe { + // SAFETY: ns_view is never null. + let ptr = Id::as_ptr(&self.contentView()) as *mut _; + std::ptr::NonNull::new_unchecked(ptr) + }); + Ok(rwh_06::RawWindowHandle::AppKit(window_handle)) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::AppKit( + rwh_06::AppKitDisplayHandle::new(), + )) } fn toggle_style_mask(&self, mask: NSWindowStyleMask, on: bool) { From 4a89e321c32d814a4180a87cb6a6051ede462b6c Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 15:39:19 -0700 Subject: [PATCH 03/12] Make the compile errors go away on WIndows Signed-off-by: John Nunley --- src/platform/windows.rs | 36 ++++----- src/platform_impl/windows/event_loop.rs | 20 +++-- src/platform_impl/windows/window.rs | 90 ++++++++++++++++------- src/platform_impl/windows/window_state.rs | 2 +- 4 files changed, 98 insertions(+), 50 deletions(-) diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 0da33468a0..18c7708549 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -163,7 +163,7 @@ impl WindowExtWindows for Window { /// Additional methods on `WindowBuilder` that are specific to Windows. pub trait WindowBuilderExtWindows { /// Set an owner to the window to be created. Can be used to create a dialog box, for example. - /// This only works when [`WindowBuilder::with_parent_window`] isn't called or set to `None`. + /// This only works when [`Self::with_parent_window`] isn't called or set to `None`. /// Can be used in combination with [`WindowExtWindows::set_enable(false)`](WindowExtWindows::set_enable) /// on the owner window to create a modal dialog box. /// @@ -173,7 +173,7 @@ pub trait WindowBuilderExtWindows { /// - An owned window is hidden when its owner is minimized. /// /// For more information, see - fn with_owner_window(self, parent: HWND) -> WindowBuilder; + fn with_owner_window(self, parent: HWND) -> Self; /// Sets a menu on the window to be created. /// @@ -185,13 +185,13 @@ pub trait WindowBuilderExtWindows { /// If you use this, it is recommended that you combine it with `with_theme(Some(Theme::Light))` to avoid a jarring effect. /// /// [`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu - fn with_menu(self, menu: HMENU) -> WindowBuilder; + fn with_menu(self, menu: HMENU) -> Self; /// This sets `ICON_BIG`. A good ceiling here is 256x256. - fn with_taskbar_icon(self, taskbar_icon: Option) -> WindowBuilder; + fn with_taskbar_icon(self, taskbar_icon: Option) -> Self; /// This sets `WS_EX_NOREDIRECTIONBITMAP`. - fn with_no_redirection_bitmap(self, flag: bool) -> WindowBuilder; + fn with_no_redirection_bitmap(self, flag: bool) -> Self; /// Enables or disables drag and drop support (enabled by default). Will interfere with other crates /// that use multi-threaded COM API (`CoInitializeEx` with `COINIT_MULTITHREADED` instead of @@ -199,66 +199,66 @@ pub trait WindowBuilderExtWindows { /// COM API regardless of this option. Currently only fullscreen mode does that, but there may be more in the future. /// If you need COM API with `COINIT_MULTITHREADED` you must initialize it before calling any winit functions. /// See for more information. - fn with_drag_and_drop(self, flag: bool) -> WindowBuilder; + fn with_drag_and_drop(self, flag: bool) -> Self; /// Whether show or hide the window icon in the taskbar. - fn with_skip_taskbar(self, skip: bool) -> WindowBuilder; + fn with_skip_taskbar(self, skip: bool) -> Self; /// Customize the window class name. - fn with_class_name>(self, class_name: S) -> WindowBuilder; + fn with_class_name>(self, class_name: S) -> Self; /// Shows or hides the background drop shadow for undecorated windows. /// /// The shadow is hidden by default. /// Enabling the shadow causes a thin 1px line to appear on the top of the window. - fn with_undecorated_shadow(self, shadow: bool) -> WindowBuilder; + fn with_undecorated_shadow(self, shadow: bool) -> Self; } -impl WindowBuilderExtWindows for WindowBuilder { +impl WindowBuilderExtWindows for WindowBuilder<'_> { #[inline] - fn with_owner_window(mut self, parent: HWND) -> WindowBuilder { + fn with_owner_window(mut self, parent: HWND) -> Self { self.platform_specific.owner = Some(parent); self } #[inline] - fn with_menu(mut self, menu: HMENU) -> WindowBuilder { + fn with_menu(mut self, menu: HMENU) -> Self { self.platform_specific.menu = Some(menu); self } #[inline] - fn with_taskbar_icon(mut self, taskbar_icon: Option) -> WindowBuilder { + fn with_taskbar_icon(mut self, taskbar_icon: Option) -> Self { self.platform_specific.taskbar_icon = taskbar_icon; self } #[inline] - fn with_no_redirection_bitmap(mut self, flag: bool) -> WindowBuilder { + fn with_no_redirection_bitmap(mut self, flag: bool) -> Self { self.platform_specific.no_redirection_bitmap = flag; self } #[inline] - fn with_drag_and_drop(mut self, flag: bool) -> WindowBuilder { + fn with_drag_and_drop(mut self, flag: bool) -> Self { self.platform_specific.drag_and_drop = flag; self } #[inline] - fn with_skip_taskbar(mut self, skip: bool) -> WindowBuilder { + fn with_skip_taskbar(mut self, skip: bool) -> Self { self.platform_specific.skip_taskbar = skip; self } #[inline] - fn with_class_name>(mut self, class_name: S) -> WindowBuilder { + fn with_class_name>(mut self, class_name: S) -> Self { self.platform_specific.class_name = class_name.into(); self } #[inline] - fn with_undecorated_shadow(mut self, shadow: bool) -> WindowBuilder { + fn with_undecorated_shadow(mut self, shadow: bool) -> Self { self.platform_specific.decoration_shadow = shadow; self } diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index a8ed8f2a08..5420106fb2 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -18,7 +18,6 @@ use std::{ }; use once_cell::sync::Lazy; -use raw_window_handle::{RawDisplayHandle, WindowsDisplayHandle}; use windows_sys::Win32::{ Devices::HumanInterfaceDevice::MOUSE_MOVE_RELATIVE, @@ -534,8 +533,18 @@ impl EventLoopWindowTarget { Some(monitor) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Windows(rwh_05::WindowsDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Windows( + rwh_06::WindowsDisplayHandle::new(), + )) } pub fn listen_device_events(&self, allowed: DeviceEvents) { @@ -973,7 +982,8 @@ pub(super) unsafe extern "system" fn public_window_callback( let userdata_ptr = match (userdata, msg) { (0, WM_NCCREATE) => { let createstruct = unsafe { &mut *(lparam as *mut CREATESTRUCTW) }; - let initdata = unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, T>) }; + let initdata = + unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, '_, T>) }; let result = match unsafe { initdata.on_nccreate(window) } { Some(userdata) => unsafe { @@ -991,7 +1001,7 @@ pub(super) unsafe extern "system" fn public_window_callback( (_, WM_CREATE) => unsafe { let createstruct = &mut *(lparam as *mut CREATESTRUCTW); let initdata = createstruct.lpCreateParams; - let initdata = &mut *(initdata as *mut InitData<'_, T>); + let initdata = &mut *(initdata as *mut InitData<'_, '_, T>); initdata.on_create(); return DefWindowProcW(window, msg, wparam, lparam); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index ebfd3b0e5f..fe16040cc0 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -1,8 +1,5 @@ #![cfg(windows_platform)] -use raw_window_handle::{ - RawDisplayHandle, RawWindowHandle, Win32WindowHandle, WindowsDisplayHandle, -}; use std::{ cell::Cell, ffi::c_void, @@ -98,7 +95,7 @@ pub(crate) struct Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - w_attr: WindowAttributes, + w_attr: WindowAttributes<'_>, pl_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { // We dispatch an `init` function because of code style. @@ -337,18 +334,53 @@ impl Window { self.window.0 } + #[cfg(feature = "rwh_04")] + #[inline] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::Win32Handle::empty(); + window_handle.hwnd = self.window.0 as *mut _; + let hinstance = unsafe { super::get_window_long(self.hwnd(), GWLP_HINSTANCE) }; + window_handle.hinstance = hinstance as *mut _; + rwh_04::RawWindowHandle::Win32(window_handle) + } + + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = Win32WindowHandle::empty(); + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::Win32WindowHandle::empty(); window_handle.hwnd = self.window.0 as *mut _; let hinstance = unsafe { super::get_window_long(self.hwnd(), GWLP_HINSTANCE) }; window_handle.hinstance = hinstance as *mut _; - RawWindowHandle::Win32(window_handle) + rwh_05::RawWindowHandle::Win32(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Windows(rwh_05::WindowsDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let mut window_handle = rwh_06::Win32WindowHandle::new(unsafe { + // SAFETY: Handle will never be zero. + let window = self.window.0; + std::num::NonZeroIsize::new_unchecked(window) + }); + let hinstance = unsafe { super::get_window_long(self.hwnd(), GWLP_HINSTANCE) }; + window_handle.hinstance = std::num::NonZeroIsize::new(hinstance); + Ok(rwh_06::RawWindowHandle::Win32(window_handle)) } + #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Windows( + rwh_06::WindowsDisplayHandle::new(), + )) } #[inline] @@ -996,17 +1028,17 @@ pub struct WindowWrapper(HWND); unsafe impl Sync for WindowWrapper {} unsafe impl Send for WindowWrapper {} -pub(super) struct InitData<'a, T: 'static> { +pub(super) struct InitData<'a, 'b, T: 'static> { // inputs pub event_loop: &'a EventLoopWindowTarget, - pub attributes: WindowAttributes, + pub attributes: WindowAttributes<'b>, pub pl_attribs: PlatformSpecificWindowBuilderAttributes, pub window_flags: WindowFlags, // outputs pub window: Option, } -impl<'a, T: 'static> InitData<'a, T> { +impl<'a, T: 'static> InitData<'a, '_, T> { unsafe fn create_window(&self, window: HWND) -> Window { // Register for touch events if applicable { @@ -1190,7 +1222,7 @@ impl<'a, T: 'static> InitData<'a, T> { } } unsafe fn init( - attributes: WindowAttributes, + attributes: WindowAttributes<'_>, pl_attribs: PlatformSpecificWindowBuilderAttributes, event_loop: &EventLoopWindowTarget, ) -> Result @@ -1228,27 +1260,33 @@ where // so the diffing later can work. window_flags.set(WindowFlags::CLOSABLE, true); - let parent = match attributes.parent_window { - Some(RawWindowHandle::Win32(handle)) => { + let mut fallback_parent = || match pl_attribs.owner { + Some(parent) => { + window_flags.set(WindowFlags::POPUP, true); + Some(parent) + } + None => { + window_flags.set(WindowFlags::ON_TASKBAR, true); + None + } + }; + + #[cfg(feature = "rwh_06")] + let parent = match attributes.parent_window.map(|r| r.as_raw()) { + Some(rwh_06::RawWindowHandle::Win32(handle)) => { window_flags.set(WindowFlags::CHILD, true); if pl_attribs.menu.is_some() { warn!("Setting a menu on a child window is unsupported"); } - Some(handle.hwnd as HWND) + Some(handle.hwnd.get() as HWND) } Some(raw) => unreachable!("Invalid raw window handle {raw:?} on Windows"), - None => match pl_attribs.owner { - Some(parent) => { - window_flags.set(WindowFlags::POPUP, true); - Some(parent) - } - None => { - window_flags.set(WindowFlags::ON_TASKBAR, true); - None - } - }, + None => fallback_parent(), }; + #[cfg(not(feature = "rwh_06"))] + let parent = fallback_parent(); + let mut initdata = InitData { event_loop, attributes, diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 233430ab51..67f7e1dc80 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -133,7 +133,7 @@ pub enum ImeState { impl WindowState { pub(crate) fn new( - attributes: &WindowAttributes, + attributes: &WindowAttributes<'_>, scale_factor: f64, current_theme: Theme, preferred_theme: Option, From 3013c3c742d8cc3cb6e0b96592849d69a1fd9341 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 15:44:35 -0700 Subject: [PATCH 04/12] Make the compile errors go away on web Signed-off-by: John Nunley --- src/platform/web.rs | 2 +- .../web/event_loop/window_target.rs | 14 +++++--- src/platform_impl/web/web_sys/canvas.rs | 2 +- src/platform_impl/web/window.rs | 36 +++++++++++++++---- src/window.rs | 6 +--- 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/platform/web.rs b/src/platform/web.rs index 3b721af441..85092ae3be 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -79,7 +79,7 @@ pub trait WindowBuilderExtWebSys { fn with_append(self, append: bool) -> Self; } -impl WindowBuilderExtWebSys for WindowBuilder { +impl WindowBuilderExtWebSys for WindowBuilder<'_> { fn with_canvas(mut self, canvas: Option) -> Self { self.platform_specific.canvas = canvas; diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index b0bfd4755b..76ff66272f 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -6,8 +6,6 @@ use std::marker::PhantomData; use std::rc::Rc; use std::sync::atomic::Ordering; -use raw_window_handle::{RawDisplayHandle, WebDisplayHandle}; - use super::runner::EventWrapper; use super::{ super::{monitor::MonitorHandle, KeyEventExtra}, @@ -672,8 +670,16 @@ impl EventLoopWindowTarget { None } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Web(WebDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Web(rwh_05::WebDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new())) } pub fn listen_device_events(&self, allowed: DeviceEvents) { diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 049c89162f..ff93861a0a 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -61,7 +61,7 @@ impl Canvas { id: WindowId, window: web_sys::Window, document: Document, - attr: &WindowAttributes, + attr: &WindowAttributes<'_>, platform_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { let canvas = match platform_attr.canvas { diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 2285d9f734..aeba04a5b7 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -6,7 +6,6 @@ use crate::window::{ WindowAttributes, WindowButtons, WindowId as RootWI, WindowLevel, }; -use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle}; use web_sys::HtmlCanvasElement; use super::r#async::Dispatcher; @@ -34,7 +33,7 @@ pub struct Inner { impl Window { pub(crate) fn new( target: &EventLoopWindowTarget, - attr: WindowAttributes, + attr: WindowAttributes<'_>, platform_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { let id = target.generate_id(); @@ -358,16 +357,39 @@ impl Inner { self.id } + #[cfg(feature = "rwh_04")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = WebWindowHandle::empty(); + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::WebHandle::empty(); window_handle.id = self.id.0; - RawWindowHandle::Web(window_handle) + rwh_04::RawWindowHandle::Web(window_handle) } + #[cfg(feature = "rwh_05")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Web(WebDisplayHandle::empty()) + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::WebWindowHandle::empty(); + window_handle.id = self.id.0; + rwh_05::RawWindowHandle::Web(window_handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Web(rwh_05::WebDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let window_handle = rwh_06::WebWindowHandle::new(self.id.0); + Ok(rwh_06::RawWindowHandle::Web(window_handle)) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06(&self) -> Result { + Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new())) } #[inline] diff --git a/src/window.rs b/src/window.rs index d599b51cc4..1a76289126 100644 --- a/src/window.rs +++ b/src/window.rs @@ -461,10 +461,6 @@ impl<'a> WindowBuilder<'a> { /// /// The default is `None`. /// - /// ## Safety - /// - /// `parent_window` must be a valid window handle. - /// /// ## Platform-specific /// /// - **Windows** : A child window has the WS_CHILD style and is confined @@ -474,7 +470,7 @@ impl<'a> WindowBuilder<'a> { /// - **Android / iOS / Wayland / Web:** Unsupported. #[cfg(feature = "rwh_06")] #[inline] - pub unsafe fn with_parent_window( + pub fn with_parent_window( self, parent_window: Option>, ) -> WindowBuilder<'_> { From 850915799e6fb3cc98dd6be6bc96333bfdc133f8 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 15:54:04 -0700 Subject: [PATCH 05/12] Make the Android build errors go away Signed-off-by: John Nunley --- src/platform/android.rs | 2 +- src/platform_impl/android/mod.rs | 62 ++++++++++++++++--- .../web/event_loop/window_target.rs | 8 ++- src/platform_impl/web/window.rs | 8 ++- 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/platform/android.rs b/src/platform/android.rs index cb0528ef35..fb174b76e9 100644 --- a/src/platform/android.rs +++ b/src/platform/android.rs @@ -35,7 +35,7 @@ impl EventLoopWindowTargetExtAndroid for EventLoopWindowTarget {} /// Additional methods on [`WindowBuilder`] that are specific to Android. pub trait WindowBuilderExtAndroid {} -impl WindowBuilderExtAndroid for WindowBuilder {} +impl WindowBuilderExtAndroid for WindowBuilder<'_> {} pub trait EventLoopBuilderExtAndroid { /// Associates the `AndroidApp` that was passed to `android_main()` with the event loop diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 10d431c21a..2f10dcbc48 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -16,9 +16,6 @@ use android_activity::{ AndroidApp, AndroidAppWaker, ConfigurationRef, InputStatus, MainEvent, Rect, }; use once_cell::sync::Lazy; -use raw_window_handle::{ - AndroidDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, -}; use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, @@ -688,8 +685,20 @@ impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Android(AndroidDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Android(rwh_05::AndroidDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Android( + rwh_06::AndroidDisplayHandle::new(), + )) } pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { @@ -750,7 +759,7 @@ pub(crate) struct Window { impl Window { pub(crate) fn new( el: &EventLoopWindowTarget, - _window_attrs: window::WindowAttributes, + _window_attrs: window::WindowAttributes<'_>, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { // FIXME this ignores requested window attributes @@ -935,7 +944,21 @@ impl Window { )) } - pub fn raw_window_handle(&self) -> RawWindowHandle { + #[cfg(feature = "rwh_04")] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + if let Some(native_window) = self.app.native_window().as_ref() { + let mut handle = rwh_04::AndroidNdkHandle::empty(); + handle.a_native_window = native_window.ptr().as_ptr() as *mut _; + rwh_04::RawWindowHandle::AndroidNdk(handle) + } else { + panic!("Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events."); + } + } + + #[cfg(feature = "rwh_05")] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + use rwh_05::HasRawWindowHandle; + if let Some(native_window) = self.app.native_window().as_ref() { native_window.raw_window_handle() } else { @@ -943,8 +966,29 @@ impl Window { } } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Android(AndroidDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Android(rwh_05::AndroidDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_window_handle_rwh_06(&self) -> Result { + if let Some(native_window) = self.app.native_window().as_ref() { + let handle = rwh_06::AndroidNdkWindowHandle::new(native_window.ptr().cast()); + Ok(rwh_06::RawWindowHandle::AndroidNdk(handle)) + } else { + log::error!("Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events."); + Err(rwh_06::HandleError::Unavailable) + } + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Android( + rwh_06::AndroidDisplayHandle::new(), + )) } pub fn config(&self) -> ConfigurationRef { diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 76ff66272f..ba1868532d 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -678,8 +678,12 @@ impl EventLoopWindowTarget { #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle_rwh_06(&self) -> Result { - Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new())) + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Web( + rwh_06::WebDisplayHandle::new(), + )) } pub fn listen_device_events(&self, allowed: DeviceEvents) { diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index aeba04a5b7..8099c530e8 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -388,8 +388,12 @@ impl Inner { #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle_rwh_06(&self) -> Result { - Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new())) + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Web( + rwh_06::WebDisplayHandle::new(), + )) } #[inline] From 36439bdb8d2eb4a3251027faab9bb8b13c27acf6 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 16:39:39 -0700 Subject: [PATCH 06/12] Finish the iOS and Orbital backends Signed-off-by: John Nunley --- src/platform/ios.rs | 28 ++++++--------- src/platform_impl/ios/event_loop.rs | 17 +++++++-- src/platform_impl/ios/view.rs | 6 ++-- src/platform_impl/ios/window.rs | 45 +++++++++++++++++++---- src/platform_impl/orbital/event_loop.rs | 17 +++++++-- src/platform_impl/orbital/window.rs | 47 +++++++++++++++++++------ 6 files changed, 117 insertions(+), 43 deletions(-) diff --git a/src/platform/ios.rs b/src/platform/ios.rs index e1a6fa86cd..1c300d6916 100644 --- a/src/platform/ios.rs +++ b/src/platform/ios.rs @@ -118,7 +118,7 @@ pub trait WindowBuilderExtIOS { /// /// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc - fn with_scale_factor(self, scale_factor: f64) -> WindowBuilder; + fn with_scale_factor(self, scale_factor: f64) -> Self; /// Sets the valid orientations for the [`Window`]. /// @@ -126,7 +126,7 @@ pub trait WindowBuilderExtIOS { /// /// This sets the initial value returned by /// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc). - fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder; + fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> Self; /// Sets whether the [`Window`] prefers the home indicator hidden. /// @@ -136,7 +136,7 @@ pub trait WindowBuilderExtIOS { /// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc). /// /// This only has an effect on iOS 11.0+. - fn with_prefers_home_indicator_hidden(self, hidden: bool) -> WindowBuilder; + fn with_prefers_home_indicator_hidden(self, hidden: bool) -> Self; /// Sets the screen edges for which the system gestures will take a lower priority than the /// application's touch handling. @@ -145,10 +145,7 @@ pub trait WindowBuilderExtIOS { /// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc). /// /// This only has an effect on iOS 11.0+. - fn with_preferred_screen_edges_deferring_system_gestures( - self, - edges: ScreenEdge, - ) -> WindowBuilder; + fn with_preferred_screen_edges_deferring_system_gestures(self, edges: ScreenEdge) -> Self; /// Sets whether the [`Window`] prefers the status bar hidden. /// @@ -156,40 +153,37 @@ pub trait WindowBuilderExtIOS { /// /// This sets the initial value returned by /// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc). - fn with_prefers_status_bar_hidden(self, hidden: bool) -> WindowBuilder; + fn with_prefers_status_bar_hidden(self, hidden: bool) -> Self; } -impl WindowBuilderExtIOS for WindowBuilder { +impl WindowBuilderExtIOS for WindowBuilder<'_> { #[inline] - fn with_scale_factor(mut self, scale_factor: f64) -> WindowBuilder { + fn with_scale_factor(mut self, scale_factor: f64) -> Self { self.platform_specific.scale_factor = Some(scale_factor); self } #[inline] - fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> WindowBuilder { + fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self { self.platform_specific.valid_orientations = valid_orientations; self } #[inline] - fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> WindowBuilder { + fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self { self.platform_specific.prefers_home_indicator_hidden = hidden; self } #[inline] - fn with_preferred_screen_edges_deferring_system_gestures( - mut self, - edges: ScreenEdge, - ) -> WindowBuilder { + fn with_preferred_screen_edges_deferring_system_gestures(mut self, edges: ScreenEdge) -> Self { self.platform_specific .preferred_screen_edges_deferring_system_gestures = edges; self } #[inline] - fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> WindowBuilder { + fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self { self.platform_specific.prefers_status_bar_hidden = hidden; self } diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 883acfc8a4..dab69606ee 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -16,7 +16,6 @@ use core_foundation::runloop::{ }; use icrate::Foundation::{MainThreadMarker, NSString}; use objc2::ClassType; -use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; use crate::{ error::EventLoopError, @@ -52,8 +51,20 @@ impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::UiKit(UiKitDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::UiKit(rwh_05::UiKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::UiKit( + rwh_06::UiKitDisplayHandle::new(), + )) } pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { diff --git a/src/platform_impl/ios/view.rs b/src/platform_impl/ios/view.rs index 206e8f5025..4fda797d22 100644 --- a/src/platform_impl/ios/view.rs +++ b/src/platform_impl/ios/view.rs @@ -180,7 +180,7 @@ extern_methods!( impl WinitView { pub(crate) fn new( _mtm: MainThreadMarker, - _window_attributes: &WindowAttributes, + _window_attributes: &WindowAttributes<'_>, platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, ) -> Id { @@ -395,7 +395,7 @@ impl WinitViewController { pub(crate) fn new( mtm: MainThreadMarker, - _window_attributes: &WindowAttributes, + _window_attributes: &WindowAttributes<'_>, platform_attributes: &PlatformSpecificWindowBuilderAttributes, view: &UIView, ) -> Id { @@ -464,7 +464,7 @@ declare_class!( impl WinitUIWindow { pub(crate) fn new( mtm: MainThreadMarker, - window_attributes: &WindowAttributes, + window_attributes: &WindowAttributes<'_>, _platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, view_controller: &UIViewController, diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 46eb6435eb..de84d34ac4 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -6,7 +6,6 @@ use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, Main use objc2::rc::Id; use objc2::runtime::AnyObject; use objc2::{class, msg_send}; -use raw_window_handle::{RawDisplayHandle, RawWindowHandle, UiKitDisplayHandle, UiKitWindowHandle}; use super::app_state::EventWrapper; use super::uikit::{UIApplication, UIScreen, UIScreenOverscanCompensation}; @@ -332,16 +331,48 @@ impl Inner { self.window.id() } - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut window_handle = UiKitWindowHandle::empty(); + #[cfg(feature = "rwh_04")] + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut window_handle = rwh_04::UiKitHandle::empty(); window_handle.ui_window = Id::as_ptr(&self.window) as _; window_handle.ui_view = Id::as_ptr(&self.view) as _; window_handle.ui_view_controller = Id::as_ptr(&self.view_controller) as _; - RawWindowHandle::UiKit(window_handle) + rwh_04::RawWindowHandle::UiKit(window_handle) } - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::UiKit(UiKitDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut window_handle = rwh_05::UiKitWindowHandle::empty(); + window_handle.ui_window = Id::as_ptr(&self.window) as _; + window_handle.ui_view = Id::as_ptr(&self.view) as _; + window_handle.ui_view_controller = Id::as_ptr(&self.view_controller) as _; + rwh_05::RawWindowHandle::UiKit(window_handle) + } + + #[cfg(feature = "rwh_05")] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::UiKit(rwh_05::UiKitDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_window_handle_rwh_06(&self) -> Result { + let mut window_handle = rwh_06::UiKitWindowHandle::new(unsafe { + // SAFETY: ns_view will never be null + let ui_view = Id::as_ptr(&self.view) as _; + std::ptr::NonNull::new_unchecked(ui_view) + }); + window_handle.ui_view_controller = + std::ptr::NonNull::new(Id::as_ptr(&self.view_controller) as _); + Ok(rwh_06::RawWindowHandle::UiKit(window_handle)) + } + + #[cfg(feature = "rwh_06")] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::UiKit( + rwh_06::UiKitDisplayHandle::new(), + )) } pub fn theme(&self) -> Option { @@ -377,7 +408,7 @@ pub struct Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - window_attributes: WindowAttributes, + window_attributes: WindowAttributes<'_>, platform_attributes: PlatformSpecificWindowBuilderAttributes, ) -> Result { let mtm = event_loop.mtm; diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index cd64a9228f..954a2142a1 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -11,7 +11,6 @@ use orbclient::{ ButtonEvent, EventOption, FocusEvent, HoverEvent, KeyEvent, MouseEvent, MoveEvent, QuitEvent, ResizeEvent, ScrollEvent, TextInputEvent, }; -use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle}; use crate::{ error::EventLoopError, @@ -736,8 +735,20 @@ impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Orbital(OrbitalDisplayHandle::empty()) + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Orbital(rwh_05::OrbitalDisplayHandle::empty()) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Orbital( + rwh_06::OrbitalDisplayHandle::new(), + )) } pub fn set_control_flow(&self, control_flow: ControlFlow) { diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index f08df9c8d4..1d10ce6a1c 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -3,10 +3,6 @@ use std::{ sync::{Arc, Mutex}, }; -use raw_window_handle::{ - OrbitalDisplayHandle, OrbitalWindowHandle, RawDisplayHandle, RawWindowHandle, -}; - use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error, @@ -39,7 +35,7 @@ pub struct Window { impl Window { pub(crate) fn new( el: &EventLoopWindowTarget, - attrs: window::WindowAttributes, + attrs: window::WindowAttributes<'_>, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { let scale = MonitorHandle.scale_factor(); @@ -400,16 +396,47 @@ impl Window { )) } + #[cfg(feature = "rwh_04")] #[inline] - pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = OrbitalWindowHandle::empty(); + pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle { + let mut handle = rwh_04::OrbitalHandle::empty(); handle.window = self.window_socket.fd as *mut _; - RawWindowHandle::Orbital(handle) + rwh_04::RawWindowHandle::Orbital(handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle { + let mut handle = rwh_05::OrbitalWindowHandle::empty(); + handle.window = self.window_socket.fd as *mut _; + rwh_05::RawWindowHandle::Orbital(handle) + } + + #[cfg(feature = "rwh_05")] + #[inline] + pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + rwh_05::RawDisplayHandle::Orbital(rwh_05::OrbitalDisplayHandle::empty()) } + #[cfg(feature = "rwh_06")] #[inline] - pub fn raw_display_handle(&self) -> RawDisplayHandle { - RawDisplayHandle::Orbital(OrbitalDisplayHandle::empty()) + pub fn raw_window_handle_rwh_06(&self) -> Result { + let handle = rwh_06::OrbitalWindowHandle::new(unsafe { + // SAFETY: not zero. + let window = self.window_socket.fd as *mut _; + std::ptr::NonNull::new_unchecked(window) + }); + Ok(rwh_06::RawWindowHandle::Orbital(handle)) + } + + #[cfg(feature = "rwh_06")] + #[inline] + pub fn raw_display_handle_rwh_06( + &self, + ) -> Result { + Ok(rwh_06::RawDisplayHandle::Orbital( + rwh_06::OrbitalDisplayHandle::new(), + )) } #[inline] From dee38dfc709eed1736d0c9acd2fa837112c3be2e Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 16:50:11 -0700 Subject: [PATCH 07/12] Fix CI errors Signed-off-by: John Nunley --- deny.toml | 1 + examples/child_window.rs | 9 ++++----- src/platform/windows.rs | 1 + src/window.rs | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/deny.toml b/deny.toml index eb551db8e7..982c4149e2 100644 --- a/deny.toml +++ b/deny.toml @@ -31,6 +31,7 @@ multiple-versions = "deny" wildcards = "allow" # at least until https://github.com/EmbarkStudios/cargo-deny/issues/241 is fixed deny = [] skip = [ + { name = "raw-window-handle" }, # we intentionally have multiple versions of this { name = "bitflags" }, # the ecosystem is in the process of migrating. { name = "nix" }, # differing version - as of 2023-03-02 whis can be solved with `cargo update && cargo update -p calloop --precise 0.10.2` { name = "memoffset"}, # due to different nix versions. diff --git a/examples/child_window.rs b/examples/child_window.rs index 6b30ba6d7a..bfe45ed5f6 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -26,14 +26,13 @@ fn main() -> Result<(), impl std::error::Error> { windows: &mut HashMap, ) { let parent = parent.window_handle().unwrap(); - let mut builder = WindowBuilder::new() + let child_window = WindowBuilder::new() .with_title("child window") .with_inner_size(LogicalSize::new(200.0f32, 200.0f32)) .with_position(Position::Logical(LogicalPosition::new(0.0, 0.0))) - .with_visible(true); - // `with_parent_window` is unsafe. Parent window must be a valid window. - builder = unsafe { builder.with_parent_window(Some(parent)) }; - let child_window = builder.build(event_loop).unwrap(); + .with_visible(true) + .with_parent_window(Some(parent)) + .build(event_loop).unwrap(); let id = child_window.id(); windows.insert(id, child_window); diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 18c7708549..25ad2ca84a 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -161,6 +161,7 @@ impl WindowExtWindows for Window { } /// Additional methods on `WindowBuilder` that are specific to Windows. +#[allow(rustdoc::broken_intra_doc_links)] pub trait WindowBuilderExtWindows { /// Set an owner to the window to be created. Can be used to create a dialog box, for example. /// This only works when [`Self::with_parent_window`] isn't called or set to `None`. diff --git a/src/window.rs b/src/window.rs index 1a76289126..c9caf18c0b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -133,6 +133,7 @@ impl fmt::Debug for WindowBuilder<'_> { /// Attributes to use when creating a window. #[derive(Debug, Clone)] +#[non_exhaustive] pub struct WindowAttributes<'a> { pub inner_size: Option, pub min_inner_size: Option, @@ -155,6 +156,7 @@ pub struct WindowAttributes<'a> { #[cfg(feature = "rwh_06")] pub parent_window: Option>, pub active: bool, + _eat_lifetime: std::marker::PhantomData<&'a ()>, } impl<'a> Default for WindowAttributes<'a> { @@ -181,6 +183,7 @@ impl<'a> Default for WindowAttributes<'a> { content_protected: false, parent_window: None, active: true, + _eat_lifetime: std::marker::PhantomData, } } } @@ -521,6 +524,7 @@ impl<'a> WindowBuilder<'a> { window_level, active, parent_window, + _eat_lifetime: std::marker::PhantomData, }, platform_specific, } From 2cf5efa303f778aa2ceef579e164a9324d5e9062 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 16:56:23 -0700 Subject: [PATCH 08/12] More fixes for CI errors Signed-off-by: John Nunley --- examples/child_window.rs | 3 ++- src/platform_impl/linux/wayland/event_loop/mod.rs | 6 +++++- src/platform_impl/linux/wayland/window/mod.rs | 1 + src/window.rs | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index bfe45ed5f6..ec9af86a22 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -32,7 +32,8 @@ fn main() -> Result<(), impl std::error::Error> { .with_position(Position::Logical(LogicalPosition::new(0.0, 0.0))) .with_visible(true) .with_parent_window(Some(parent)) - .build(event_loop).unwrap(); + .build(event_loop) + .unwrap(); let id = child_window.id(); windows.insert(id, child_window); diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index bb0c52eb34..819c3de867 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -12,7 +12,7 @@ use std::time::{Duration, Instant}; use sctk::reexports::calloop; use sctk::reexports::calloop::Error as CalloopError; use sctk::reexports::client::globals; -use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource}; +use sctk::reexports::client::{Connection, QueueHandle, WaylandSource}; use crate::dpi::{LogicalSize, PhysicalSize}; use crate::error::{EventLoopError, OsError as RootOsError}; @@ -654,6 +654,8 @@ impl EventLoopWindowTarget { #[cfg(feature = "rwh_05")] #[inline] pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle { + use sctk::reexports::client::Proxy; + let mut display_handle = rwh_05::WaylandDisplayHandle::empty(); display_handle.display = self.connection.display().id().as_ptr() as *mut _; rwh_05::RawDisplayHandle::Wayland(display_handle) @@ -664,6 +666,8 @@ impl EventLoopWindowTarget { pub fn raw_display_handle_rwh_06( &self, ) -> Result { + use sctk::reexports::client::Proxy; + Ok(rwh_06::WaylandDisplayHandle::new(unsafe { // SAFETY: The display handle will never be null. let ptr = self.connection.display().id().as_ptr(); diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index f2e08fa9dc..bd3390ba96 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -53,6 +53,7 @@ pub struct Window { compositor: Arc, /// The wayland display used solely for raw window handle. + #[allow(dead_code)] display: WlDisplay, /// Xdg activation to request user attention. diff --git a/src/window.rs b/src/window.rs index c9caf18c0b..86c0f1234c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -181,6 +181,7 @@ impl<'a> Default for WindowAttributes<'a> { preferred_theme: None, resize_increments: None, content_protected: false, + #[cfg(feature = "rwh_06")] parent_window: None, active: true, _eat_lifetime: std::marker::PhantomData, From e2d1301bc3f3d9f1b167b354ebb095918ab585d1 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 1 Oct 2023 17:01:49 -0700 Subject: [PATCH 09/12] Fix X11 CI error Signed-off-by: John Nunley --- src/platform_impl/linux/x11/window.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 5db0fc7fe7..5e12461259 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -119,9 +119,11 @@ unsafe impl Sync for UnownedWindow {} pub(crate) struct UnownedWindow { pub(crate) xconn: Arc, // never changes xwindow: xproto::Window, // never changes - visual: u32, // never changes + #[allow(dead_code)] + visual: u32, // never changes root: xproto::Window, // never changes - screen_id: i32, // never changes + #[allow(dead_code)] + screen_id: i32, // never changes cursor: Mutex, cursor_grabbed_mode: Mutex, #[allow(clippy::mutex_atomic)] @@ -1469,11 +1471,13 @@ impl UnownedWindow { WindowButtons::all() } + #[allow(dead_code)] #[inline] pub fn xlib_display(&self) -> *mut c_void { self.xconn.display as _ } + #[allow(dead_code)] #[inline] pub fn xlib_window(&self) -> c_ulong { self.xwindow as ffi::Window From b20c0ced298707b7a4aa2259a844de846601159a Mon Sep 17 00:00:00 2001 From: John Nunley Date: Mon, 2 Oct 2023 19:47:57 -0700 Subject: [PATCH 10/12] Partially fix review comments Signed-off-by: John Nunley --- examples/util/fill.rs | 2 -- src/platform_impl/ios/window.rs | 5 ++--- src/platform_impl/linux/wayland/event_loop/mod.rs | 5 ++--- src/platform_impl/linux/wayland/window/mod.rs | 10 ++++------ src/platform_impl/linux/x11/mod.rs | 2 +- src/platform_impl/linux/x11/window.rs | 3 +-- src/platform_impl/macos/window.rs | 5 ++--- src/platform_impl/orbital/window.rs | 5 ++--- 8 files changed, 14 insertions(+), 23 deletions(-) diff --git a/examples/util/fill.rs b/examples/util/fill.rs index 36d3c8b087..a47ce95a04 100644 --- a/examples/util/fill.rs +++ b/examples/util/fill.rs @@ -7,8 +7,6 @@ //! The `softbuffer` crate is used, largely because of its ease of use. `glutin` or `wgpu` could //! also be used to fill the window buffer, but they are more complicated to use. -// TODO: Once softbuffer uses rwh_06, use that instead. - use winit::window::Window; #[cfg(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios"))))] diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index de84d34ac4..319a523e1b 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -356,10 +356,9 @@ impl Inner { #[cfg(feature = "rwh_06")] pub fn raw_window_handle_rwh_06(&self) -> Result { - let mut window_handle = rwh_06::UiKitWindowHandle::new(unsafe { - // SAFETY: ns_view will never be null + let mut window_handle = rwh_06::UiKitWindowHandle::new({ let ui_view = Id::as_ptr(&self.view) as _; - std::ptr::NonNull::new_unchecked(ui_view) + std::ptr::NonNull::new(ui_view).expect("Id should never be null") }); window_handle.ui_view_controller = std::ptr::NonNull::new(Id::as_ptr(&self.view_controller) as _); diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 819c3de867..1b84b65fc4 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -668,10 +668,9 @@ impl EventLoopWindowTarget { ) -> Result { use sctk::reexports::client::Proxy; - Ok(rwh_06::WaylandDisplayHandle::new(unsafe { - // SAFETY: The display handle will never be null. + Ok(rwh_06::WaylandDisplayHandle::new({ let ptr = self.connection.display().id().as_ptr(); - std::ptr::NonNull::new_unchecked(ptr as *mut _) + std::ptr::NonNull::new(ptr as *mut _).expect("wl_display should never be null") }) .into()) } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index bd3390ba96..74f00a58e6 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -675,10 +675,9 @@ impl Window { #[cfg(feature = "rwh_06")] #[inline] pub fn raw_window_handle_rwh_06(&self) -> Result { - Ok(rwh_06::WaylandWindowHandle::new(unsafe { - // SAFETY: Surface pointer will never be null. + Ok(rwh_06::WaylandWindowHandle::new({ let ptr = self.window.wl_surface().id().as_ptr(); - std::ptr::NonNull::new_unchecked(ptr as *mut _) + std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null") }) .into()) } @@ -688,10 +687,9 @@ impl Window { pub fn raw_display_handle_rwh_06( &self, ) -> Result { - Ok(rwh_06::WaylandDisplayHandle::new(unsafe { - // SAFETY: Display pointer will never be null. + Ok(rwh_06::WaylandDisplayHandle::new({ let ptr = self.display.id().as_ptr(); - std::ptr::NonNull::new_unchecked(ptr as *mut _) + std::ptr::NonNull::new(ptr as *mut _).expect("wl_proxy should never be null") }) .into()) } diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 8c3d7d1b73..5ffe49a4ab 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -717,7 +717,7 @@ impl EventLoopWindowTarget { ) -> Result { let display_handle = rwh_06::XlibDisplayHandle::new( // SAFETY: display will never be null - Some(unsafe { std::ptr::NonNull::new_unchecked(self.xconn.display as *mut _) }), + Some(std::ptr::NonNull::new(self.xconn.display as *mut _).expect("X11 display should never be null")), self.xconn.default_screen_index() as c_int, ); Ok(display_handle.into()) diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 5e12461259..11e6b17ed2 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -1868,8 +1868,7 @@ impl UnownedWindow { &self, ) -> Result { Ok(rwh_06::XlibDisplayHandle::new( - // SAFETY: The Xlib display pointer will never be null - Some(unsafe { std::ptr::NonNull::new_unchecked(self.xlib_display()) }), + Some(std::ptr::NonNull::new(self.xlib_display()).expect("display pointer should never be null")), self.screen_id, ) .into()) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index be753cb344..2ad130acfd 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -1374,10 +1374,9 @@ impl WinitWindow { #[cfg(feature = "rwh_06")] #[inline] pub fn raw_window_handle_rwh_06(&self) -> Result { - let window_handle = rwh_06::AppKitWindowHandle::new(unsafe { - // SAFETY: ns_view is never null. + let window_handle = rwh_06::AppKitWindowHandle::new({ let ptr = Id::as_ptr(&self.contentView()) as *mut _; - std::ptr::NonNull::new_unchecked(ptr) + std::ptr::NonNull::new(ptr).expect("Id should never be null") }); Ok(rwh_06::RawWindowHandle::AppKit(window_handle)) } diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index 1d10ce6a1c..96e27c2135 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -421,10 +421,9 @@ impl Window { #[cfg(feature = "rwh_06")] #[inline] pub fn raw_window_handle_rwh_06(&self) -> Result { - let handle = rwh_06::OrbitalWindowHandle::new(unsafe { - // SAFETY: not zero. + let handle = rwh_06::OrbitalWindowHandle::new({ let window = self.window_socket.fd as *mut _; - std::ptr::NonNull::new_unchecked(window) + std::ptr::NonNull::new(window).expect("orbital fd shoul never be null") }); Ok(rwh_06::RawWindowHandle::Orbital(handle)) } From 9a861b6b6e02351eff961d4376a63742c97bae41 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Tue, 3 Oct 2023 16:37:55 -0700 Subject: [PATCH 11/12] Remaining review comments Signed-off-by: John Nunley --- examples/child_window.rs | 17 ++-- src/lib.rs | 7 -- src/platform/android.rs | 2 +- src/platform/ios.rs | 2 +- src/platform/macos.rs | 2 +- src/platform/startup_notify.rs | 2 +- src/platform/wayland.rs | 2 +- src/platform/web.rs | 2 +- src/platform/windows.rs | 4 +- src/platform/x11.rs | 2 +- src/platform_impl/android/mod.rs | 2 +- src/platform_impl/ios/view.rs | 6 +- src/platform_impl/ios/window.rs | 2 +- src/platform_impl/linux/mod.rs | 2 +- src/platform_impl/linux/wayland/window/mod.rs | 2 +- src/platform_impl/linux/x11/mod.rs | 7 +- src/platform_impl/linux/x11/window.rs | 14 +-- src/platform_impl/macos/window.rs | 31 +++---- src/platform_impl/orbital/window.rs | 2 +- src/platform_impl/web/web_sys/canvas.rs | 2 +- src/platform_impl/web/window.rs | 2 +- src/platform_impl/windows/window.rs | 6 +- src/platform_impl/windows/window_state.rs | 2 +- src/window.rs | 88 +++++-------------- 24 files changed, 75 insertions(+), 135 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index ec9af86a22..9234d9e4e6 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -9,6 +9,7 @@ mod fill; feature = "rwh_06", any(x11_platform, macos_platform, windows_platform) ))] +#[allow(deprecated)] fn main() -> Result<(), impl std::error::Error> { use std::collections::HashMap; @@ -16,7 +17,7 @@ fn main() -> Result<(), impl std::error::Error> { dpi::{LogicalPosition, LogicalSize, Position}, event::{ElementState, Event, KeyEvent, WindowEvent}, event_loop::{EventLoop, EventLoopWindowTarget}, - raw_window_handle::HasWindowHandle, + raw_window_handle::HasRawWindowHandle, window::{Window, WindowBuilder, WindowId}, }; @@ -25,15 +26,15 @@ fn main() -> Result<(), impl std::error::Error> { event_loop: &EventLoopWindowTarget<()>, windows: &mut HashMap, ) { - let parent = parent.window_handle().unwrap(); - let child_window = WindowBuilder::new() + let parent = parent.raw_window_handle().unwrap(); + let mut builder = WindowBuilder::new() .with_title("child window") .with_inner_size(LogicalSize::new(200.0f32, 200.0f32)) .with_position(Position::Logical(LogicalPosition::new(0.0, 0.0))) - .with_visible(true) - .with_parent_window(Some(parent)) - .build(event_loop) - .unwrap(); + .with_visible(true); + // `with_parent_window` is unsafe. Parent window must be a valid window. + builder = unsafe { builder.with_parent_window(Some(parent)) }; + let child_window = builder.build(event_loop).unwrap(); let id = child_window.id(); windows.insert(id, child_window); @@ -92,5 +93,5 @@ fn main() -> Result<(), impl std::error::Error> { any(x11_platform, macos_platform, windows_platform) )))] fn main() { - panic!("This example is supported only on x11, macOS, and Windows."); + panic!("This example is supported only on x11, macOS, and Windows, with the `rwh_06` feature enabled."); } diff --git a/src/lib.rs b/src/lib.rs index c6fb16d7e3..b505961f30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,14 +139,7 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![allow(clippy::missing_safety_doc)] -#[cfg(all(not(feature = "rwh_06"), not(feature = "rwh_05"), feature = "rwh_04"))] -#[doc(inline)] -pub use rwh_04 as raw_window_handle; -#[cfg(all(not(feature = "rwh_06"), feature = "rwh_05"))] -#[doc(inline)] -pub use rwh_05 as raw_window_handle; #[cfg(feature = "rwh_06")] -#[doc(inline)] pub use rwh_06 as raw_window_handle; #[allow(unused_imports)] diff --git a/src/platform/android.rs b/src/platform/android.rs index fb174b76e9..cb0528ef35 100644 --- a/src/platform/android.rs +++ b/src/platform/android.rs @@ -35,7 +35,7 @@ impl EventLoopWindowTargetExtAndroid for EventLoopWindowTarget {} /// Additional methods on [`WindowBuilder`] that are specific to Android. pub trait WindowBuilderExtAndroid {} -impl WindowBuilderExtAndroid for WindowBuilder<'_> {} +impl WindowBuilderExtAndroid for WindowBuilder {} pub trait EventLoopBuilderExtAndroid { /// Associates the `AndroidApp` that was passed to `android_main()` with the event loop diff --git a/src/platform/ios.rs b/src/platform/ios.rs index 1c300d6916..2097453917 100644 --- a/src/platform/ios.rs +++ b/src/platform/ios.rs @@ -156,7 +156,7 @@ pub trait WindowBuilderExtIOS { fn with_prefers_status_bar_hidden(self, hidden: bool) -> Self; } -impl WindowBuilderExtIOS for WindowBuilder<'_> { +impl WindowBuilderExtIOS for WindowBuilder { #[inline] fn with_scale_factor(mut self, scale_factor: f64) -> Self { self.platform_specific.scale_factor = Some(scale_factor); diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 0fb26716e2..d543c299d8 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -208,7 +208,7 @@ pub trait WindowBuilderExtMacOS { fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self; } -impl WindowBuilderExtMacOS for WindowBuilder<'_> { +impl WindowBuilderExtMacOS for WindowBuilder { #[inline] fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self { self.platform_specific.movable_by_window_background = movable_by_window_background; diff --git a/src/platform/startup_notify.rs b/src/platform/startup_notify.rs index 35bf8d2e57..323c2fe624 100644 --- a/src/platform/startup_notify.rs +++ b/src/platform/startup_notify.rs @@ -74,7 +74,7 @@ impl WindowExtStartupNotify for Window { } } -impl WindowBuilderExtStartupNotify for WindowBuilder<'_> { +impl WindowBuilderExtStartupNotify for WindowBuilder { fn with_activation_token(mut self, token: ActivationToken) -> Self { self.platform_specific.activation_token = Some(token); self diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index abe0dcde26..ba87651858 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -64,7 +64,7 @@ pub trait WindowBuilderExtWayland { fn with_name(self, general: impl Into, instance: impl Into) -> Self; } -impl WindowBuilderExtWayland for WindowBuilder<'_> { +impl WindowBuilderExtWayland for WindowBuilder { #[inline] fn with_name(mut self, general: impl Into, instance: impl Into) -> Self { self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into())); diff --git a/src/platform/web.rs b/src/platform/web.rs index 85092ae3be..3b721af441 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -79,7 +79,7 @@ pub trait WindowBuilderExtWebSys { fn with_append(self, append: bool) -> Self; } -impl WindowBuilderExtWebSys for WindowBuilder<'_> { +impl WindowBuilderExtWebSys for WindowBuilder { fn with_canvas(mut self, canvas: Option) -> Self { self.platform_specific.canvas = canvas; diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 25ad2ca84a..8e10157944 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -164,7 +164,7 @@ impl WindowExtWindows for Window { #[allow(rustdoc::broken_intra_doc_links)] pub trait WindowBuilderExtWindows { /// Set an owner to the window to be created. Can be used to create a dialog box, for example. - /// This only works when [`Self::with_parent_window`] isn't called or set to `None`. + /// This only works when [`WindowBuilder::with_parent_window`] isn't called or set to `None`. /// Can be used in combination with [`WindowExtWindows::set_enable(false)`](WindowExtWindows::set_enable) /// on the owner window to create a modal dialog box. /// @@ -215,7 +215,7 @@ pub trait WindowBuilderExtWindows { fn with_undecorated_shadow(self, shadow: bool) -> Self; } -impl WindowBuilderExtWindows for WindowBuilder<'_> { +impl WindowBuilderExtWindows for WindowBuilder { #[inline] fn with_owner_window(mut self, parent: HWND) -> Self { self.platform_specific.owner = Some(parent); diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 059f644b90..5cbd2fe32a 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -140,7 +140,7 @@ pub trait WindowBuilderExtX11 { fn with_embed_parent_window(self, parent_window_id: XWindow) -> Self; } -impl WindowBuilderExtX11 for WindowBuilder<'_> { +impl WindowBuilderExtX11 for WindowBuilder { #[inline] fn with_x11_visual(mut self, visual_id: XVisualID) -> Self { self.platform_specific.x11.visual_id = Some(visual_id); diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 2f10dcbc48..2c6ef65c38 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -759,7 +759,7 @@ pub(crate) struct Window { impl Window { pub(crate) fn new( el: &EventLoopWindowTarget, - _window_attrs: window::WindowAttributes<'_>, + _window_attrs: window::WindowAttributes, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { // FIXME this ignores requested window attributes diff --git a/src/platform_impl/ios/view.rs b/src/platform_impl/ios/view.rs index 4fda797d22..206e8f5025 100644 --- a/src/platform_impl/ios/view.rs +++ b/src/platform_impl/ios/view.rs @@ -180,7 +180,7 @@ extern_methods!( impl WinitView { pub(crate) fn new( _mtm: MainThreadMarker, - _window_attributes: &WindowAttributes<'_>, + _window_attributes: &WindowAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, ) -> Id { @@ -395,7 +395,7 @@ impl WinitViewController { pub(crate) fn new( mtm: MainThreadMarker, - _window_attributes: &WindowAttributes<'_>, + _window_attributes: &WindowAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes, view: &UIView, ) -> Id { @@ -464,7 +464,7 @@ declare_class!( impl WinitUIWindow { pub(crate) fn new( mtm: MainThreadMarker, - window_attributes: &WindowAttributes<'_>, + window_attributes: &WindowAttributes, _platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, view_controller: &UIViewController, diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 319a523e1b..8864c58b3a 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -407,7 +407,7 @@ pub struct Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - window_attributes: WindowAttributes<'_>, + window_attributes: WindowAttributes, platform_attributes: PlatformSpecificWindowBuilderAttributes, ) -> Result { let mtm = event_loop.mtm; diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index d9b4d88ba5..e7d8be5b75 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -290,7 +290,7 @@ impl Window { #[inline] pub(crate) fn new( window_target: &EventLoopWindowTarget, - attribs: WindowAttributes<'_>, + attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { match *window_target { diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 74f00a58e6..2f79918f48 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -81,7 +81,7 @@ pub struct Window { impl Window { pub(crate) fn new( event_loop_window_target: &EventLoopWindowTarget, - attributes: WindowAttributes<'_>, + attributes: WindowAttributes, platform_attributes: PlatformAttributes, ) -> Result { let queue_handle = event_loop_window_target.queue_handle.clone(); diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 5ffe49a4ab..640b5168d3 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -717,7 +717,10 @@ impl EventLoopWindowTarget { ) -> Result { let display_handle = rwh_06::XlibDisplayHandle::new( // SAFETY: display will never be null - Some(std::ptr::NonNull::new(self.xconn.display as *mut _).expect("X11 display should never be null")), + Some( + std::ptr::NonNull::new(self.xconn.display as *mut _) + .expect("X11 display should never be null"), + ), self.xconn.default_screen_index() as c_int, ); Ok(display_handle.into()) @@ -819,7 +822,7 @@ impl Deref for Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - attribs: WindowAttributes<'_>, + attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let window = Arc::new(UnownedWindow::new(event_loop, attribs, pl_attribs)?); diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 11e6b17ed2..e3ee0e4d77 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -76,10 +76,7 @@ pub enum Visibility { } impl SharedState { - fn new( - last_monitor: X11MonitorHandle, - window_attributes: &WindowAttributes<'_>, - ) -> Mutex { + fn new(last_monitor: X11MonitorHandle, window_attributes: &WindowAttributes) -> Mutex { let visibility = if window_attributes.visible { Visibility::YesWait } else { @@ -147,13 +144,13 @@ impl UnownedWindow { #[allow(clippy::unnecessary_cast)] pub(crate) fn new( event_loop: &EventLoopWindowTarget, - window_attrs: WindowAttributes<'_>, + window_attrs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let xconn = &event_loop.xconn; let atoms = xconn.atoms(); #[cfg(feature = "rwh_06")] - let root = match window_attrs.parent_window.map(|x| x.as_raw()) { + let root = match window_attrs.parent_window { Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window, Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(), Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"), @@ -1868,7 +1865,10 @@ impl UnownedWindow { &self, ) -> Result { Ok(rwh_06::XlibDisplayHandle::new( - Some(std::ptr::NonNull::new(self.xlib_display()).expect("display pointer should never be null")), + Some( + std::ptr::NonNull::new(self.xlib_display()) + .expect("display pointer should never be null"), + ), self.screen_id, ) .into()) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 2ad130acfd..5bb3d04268 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -63,7 +63,7 @@ impl Drop for Window { impl Window { pub(crate) fn new( _window_target: &EventLoopWindowTarget, - attributes: WindowAttributes<'_>, + attributes: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { let mtm = MainThreadMarker::new() @@ -289,7 +289,7 @@ impl Drop for SharedStateMutexGuard<'_> { impl WinitWindow { #[allow(clippy::type_complexity)] fn new( - attrs: WindowAttributes<'_>, + attrs: WindowAttributes, pl_attrs: PlatformSpecificWindowBuilderAttributes, ) -> Result<(Id, Id), RootOsError> { trace_scope!("WinitWindow::new"); @@ -449,26 +449,17 @@ impl WinitWindow { .ok_or_else(|| os_error!(OsError::CreationError("Couldn't create `NSWindow`")))?; #[cfg(feature = "rwh_06")] - match attrs.parent_window.map(|parent| parent.as_raw()) { + match attrs.parent_window { Some(rwh_06::RawWindowHandle::AppKit(handle)) => { // SAFETY: Caller ensures the pointer is valid or NULL - let parent = { - // SAFETY: Caller ensures the pointer is valid or NULL - let parent_view: Id = - match unsafe { Id::retain(handle.ns_view.as_ptr().cast()) } { - Some(view) => view, - None => { - return Err(os_error!(OsError::CreationError( - "raw window handle should be non-empty" - ))) - } - }; - parent_view.window().ok_or_else(|| { - os_error!(OsError::CreationError( - "parent view should be installed in a window" - )) - })? - }; + // Unwrap is fine, since the pointer comes from `NonNull`. + let parent_view: Id = + unsafe { Id::retain(handle.ns_view.as_ptr().cast()) }.unwrap(); + let parent = parent_view.window().ok_or_else(|| { + os_error!(OsError::CreationError( + "parent view should be installed in a window" + )) + })?; // SAFETY: We know that there are no parent -> child -> parent cycles since the only place in `winit` // where we allow making a window a child window is right here, just after it's been created. diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index 96e27c2135..26ab72681a 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -35,7 +35,7 @@ pub struct Window { impl Window { pub(crate) fn new( el: &EventLoopWindowTarget, - attrs: window::WindowAttributes<'_>, + attrs: window::WindowAttributes, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { let scale = MonitorHandle.scale_factor(); diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index ff93861a0a..049c89162f 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -61,7 +61,7 @@ impl Canvas { id: WindowId, window: web_sys::Window, document: Document, - attr: &WindowAttributes<'_>, + attr: &WindowAttributes, platform_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { let canvas = match platform_attr.canvas { diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 8099c530e8..fd6fad4e29 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -33,7 +33,7 @@ pub struct Inner { impl Window { pub(crate) fn new( target: &EventLoopWindowTarget, - attr: WindowAttributes<'_>, + attr: WindowAttributes, platform_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { let id = target.generate_id(); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index fe16040cc0..a643f99d53 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -95,7 +95,7 @@ pub(crate) struct Window { impl Window { pub(crate) fn new( event_loop: &EventLoopWindowTarget, - w_attr: WindowAttributes<'_>, + w_attr: WindowAttributes, pl_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { // We dispatch an `init` function because of code style. @@ -1222,7 +1222,7 @@ impl<'a, T: 'static> InitData<'a, '_, T> { } } unsafe fn init( - attributes: WindowAttributes<'_>, + attributes: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, event_loop: &EventLoopWindowTarget, ) -> Result @@ -1272,7 +1272,7 @@ where }; #[cfg(feature = "rwh_06")] - let parent = match attributes.parent_window.map(|r| r.as_raw()) { + let parent = match attributes.parent_window { Some(rwh_06::RawWindowHandle::Win32(handle)) => { window_flags.set(WindowFlags::CHILD, true); if pl_attribs.menu.is_some() { diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 67f7e1dc80..233430ab51 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -133,7 +133,7 @@ pub enum ImeState { impl WindowState { pub(crate) fn new( - attributes: &WindowAttributes<'_>, + attributes: &WindowAttributes, scale_factor: f64, current_theme: Theme, preferred_theme: Option, diff --git a/src/window.rs b/src/window.rs index 86c0f1234c..4bf90b8413 100644 --- a/src/window.rs +++ b/src/window.rs @@ -115,15 +115,15 @@ impl From for WindowId { /// Object that allows building windows. #[derive(Clone, Default)] #[must_use] -pub struct WindowBuilder<'a> { +pub struct WindowBuilder { /// The attributes to use to create the window. - pub(crate) window: WindowAttributes<'a>, + pub(crate) window: WindowAttributes, // Platform-specific configuration. pub(crate) platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes, } -impl fmt::Debug for WindowBuilder<'_> { +impl fmt::Debug for WindowBuilder { fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result { fmtr.debug_struct("WindowBuilder") .field("window", &self.window) @@ -133,8 +133,7 @@ impl fmt::Debug for WindowBuilder<'_> { /// Attributes to use when creating a window. #[derive(Debug, Clone)] -#[non_exhaustive] -pub struct WindowAttributes<'a> { +pub struct WindowAttributes { pub inner_size: Option, pub min_inner_size: Option, pub max_inner_size: Option, @@ -154,14 +153,13 @@ pub struct WindowAttributes<'a> { pub content_protected: bool, pub window_level: WindowLevel, #[cfg(feature = "rwh_06")] - pub parent_window: Option>, + pub parent_window: Option, pub active: bool, - _eat_lifetime: std::marker::PhantomData<&'a ()>, } -impl<'a> Default for WindowAttributes<'a> { +impl Default for WindowAttributes { #[inline] - fn default() -> WindowAttributes<'a> { + fn default() -> WindowAttributes { WindowAttributes { inner_size: None, min_inner_size: None, @@ -184,12 +182,11 @@ impl<'a> Default for WindowAttributes<'a> { #[cfg(feature = "rwh_06")] parent_window: None, active: true, - _eat_lifetime: std::marker::PhantomData, } } } -impl WindowBuilder<'static> { +impl WindowBuilder { /// Initializes a new builder with default values. #[inline] pub fn new() -> Self { @@ -197,9 +194,9 @@ impl WindowBuilder<'static> { } } -impl<'a> WindowBuilder<'a> { +impl WindowBuilder { /// Get the current window attributes. - pub fn window_attributes(&self) -> &WindowAttributes<'a> { + pub fn window_attributes(&self) -> &WindowAttributes { &self.window } @@ -465,6 +462,10 @@ impl<'a> WindowBuilder<'a> { /// /// The default is `None`. /// + /// ## Safety + /// + /// `parent_window` must be a valid window handle. + /// /// ## Platform-specific /// /// - **Windows** : A child window has the WS_CHILD style and is confined @@ -474,61 +475,12 @@ impl<'a> WindowBuilder<'a> { /// - **Android / iOS / Wayland / Web:** Unsupported. #[cfg(feature = "rwh_06")] #[inline] - pub fn with_parent_window( - self, - parent_window: Option>, - ) -> WindowBuilder<'_> { - let Self { - window: - WindowAttributes { - inner_size, - min_inner_size, - max_inner_size, - position, - resizable, - enabled_buttons, - title, - fullscreen, - maximized, - visible, - transparent, - decorations, - window_icon, - preferred_theme, - resize_increments, - content_protected, - window_level, - active, - .. - }, - platform_specific, - } = self; - - WindowBuilder { - window: WindowAttributes { - inner_size, - min_inner_size, - max_inner_size, - position, - resizable, - enabled_buttons, - title, - fullscreen, - maximized, - visible, - transparent, - decorations, - window_icon, - preferred_theme, - resize_increments, - content_protected, - window_level, - active, - parent_window, - _eat_lifetime: std::marker::PhantomData, - }, - platform_specific, - } + pub unsafe fn with_parent_window( + mut self, + parent_window: Option, + ) -> Self { + self.window.parent_window = parent_window; + self } /// Builds the window. From 2933b0ae032496f000bc13d03a0d9af3404429d1 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Wed, 4 Oct 2023 16:52:16 -0700 Subject: [PATCH 12/12] Fix windows lifetimes Co-Authored-By: TornaxO7 Signed-off-by: John Nunley --- src/platform_impl/windows/event_loop.rs | 5 ++--- src/platform_impl/windows/window.rs | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 5420106fb2..0abd9b1798 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -982,8 +982,7 @@ pub(super) unsafe extern "system" fn public_window_callback( let userdata_ptr = match (userdata, msg) { (0, WM_NCCREATE) => { let createstruct = unsafe { &mut *(lparam as *mut CREATESTRUCTW) }; - let initdata = - unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, '_, T>) }; + let initdata = unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, T>) }; let result = match unsafe { initdata.on_nccreate(window) } { Some(userdata) => unsafe { @@ -1001,7 +1000,7 @@ pub(super) unsafe extern "system" fn public_window_callback( (_, WM_CREATE) => unsafe { let createstruct = &mut *(lparam as *mut CREATESTRUCTW); let initdata = createstruct.lpCreateParams; - let initdata = &mut *(initdata as *mut InitData<'_, '_, T>); + let initdata = &mut *(initdata as *mut InitData<'_, T>); initdata.on_create(); return DefWindowProcW(window, msg, wparam, lparam); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index a643f99d53..ed539c2059 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -1028,17 +1028,17 @@ pub struct WindowWrapper(HWND); unsafe impl Sync for WindowWrapper {} unsafe impl Send for WindowWrapper {} -pub(super) struct InitData<'a, 'b, T: 'static> { +pub(super) struct InitData<'a, T: 'static> { // inputs pub event_loop: &'a EventLoopWindowTarget, - pub attributes: WindowAttributes<'b>, + pub attributes: WindowAttributes, pub pl_attribs: PlatformSpecificWindowBuilderAttributes, pub window_flags: WindowFlags, // outputs pub window: Option, } -impl<'a, T: 'static> InitData<'a, '_, T> { +impl<'a, T: 'static> InitData<'a, T> { unsafe fn create_window(&self, window: HWND) -> Window { // Register for touch events if applicable {