From 59b1eb54103ace8ed47f41bb2a30d8fccf547c70 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 13 Nov 2024 15:29:05 +0300 Subject: [PATCH] api: make OwnedDisplayHandle wrap an opaque type This will help in case we want to linger the event loop during drop to prevent use after free in the consumers code. --- src/event_loop.rs | 48 ++++++++++------- src/platform_impl/android/mod.rs | 16 +++--- src/platform_impl/apple/appkit/event_loop.rs | 19 ++++--- src/platform_impl/apple/appkit/mod.rs | 2 +- src/platform_impl/apple/uikit/event_loop.rs | 18 +++---- src/platform_impl/apple/uikit/mod.rs | 3 +- src/platform_impl/linux/mod.rs | 52 ------------------- .../linux/wayland/event_loop/mod.rs | 40 ++++++++++---- src/platform_impl/linux/wayland/window/mod.rs | 4 +- .../linux/wayland/window/state.rs | 11 ++-- src/platform_impl/linux/x11/mod.rs | 26 ++-------- src/platform_impl/linux/x11/xdisplay.rs | 22 ++++++++ src/platform_impl/orbital/event_loop.rs | 19 ++++--- src/platform_impl/orbital/mod.rs | 2 +- src/platform_impl/web/event_loop/mod.rs | 2 +- .../web/event_loop/window_target.rs | 18 +++---- src/platform_impl/web/mod.rs | 2 +- src/platform_impl/windows/event_loop.rs | 18 +++---- src/platform_impl/windows/mod.rs | 4 +- 19 files changed, 149 insertions(+), 177 deletions(-) diff --git a/src/event_loop.rs b/src/event_loop.rs index 4241114374..059613459b 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -17,6 +17,7 @@ use std::sync::Arc; #[cfg(not(web_platform))] use std::time::{Duration, Instant}; +use rwh_06::{DisplayHandle, HandleError, HasDisplayHandle}; #[cfg(web_platform)] use web_time::{Duration, Instant}; @@ -274,9 +275,9 @@ impl EventLoop { } } -impl rwh_06::HasDisplayHandle for EventLoop { - fn display_handle(&self) -> Result, rwh_06::HandleError> { - rwh_06::HasDisplayHandle::display_handle(self.event_loop.window_target().rwh_06_handle()) +impl HasDisplayHandle for EventLoop { + fn display_handle(&self) -> Result, HandleError> { + HasDisplayHandle::display_handle(self.event_loop.window_target().rwh_06_handle()) } } @@ -407,11 +408,11 @@ pub trait ActiveEventLoop: AsAny { fn owned_display_handle(&self) -> OwnedDisplayHandle; /// Get the raw-window-handle handle. - fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle; + fn rwh_06_handle(&self) -> &dyn HasDisplayHandle; } -impl rwh_06::HasDisplayHandle for dyn ActiveEventLoop + '_ { - fn display_handle(&self) -> Result, rwh_06::HandleError> { +impl HasDisplayHandle for dyn ActiveEventLoop + '_ { + fn display_handle(&self) -> Result, HandleError> { self.rwh_06_handle().display_handle() } } @@ -428,31 +429,40 @@ impl rwh_06::HasDisplayHandle for dyn ActiveEventLoop + '_ { /// /// - A zero-sized type that is likely optimized out. /// - A reference-counted pointer to the underlying type. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone)] pub struct OwnedDisplayHandle { - #[allow(dead_code)] - pub(crate) platform: platform_impl::OwnedDisplayHandle, + pub(crate) handle: Arc, +} + +impl OwnedDisplayHandle { + pub(crate) fn new(handle: Arc) -> Self { + Self { handle } + } +} + +impl HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, HandleError> { + self.handle.display_handle() + } } impl fmt::Debug for OwnedDisplayHandle { - #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnedDisplayHandle").finish_non_exhaustive() } } -impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { - #[inline] - fn display_handle(&self) -> Result, rwh_06::HandleError> { - let raw = self.platform.raw_display_handle_rwh_06()?; - - // SAFETY: The underlying display handle should be safe. - let handle = unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }; - - Ok(handle) +impl PartialEq for OwnedDisplayHandle { + fn eq(&self, other: &Self) -> bool { + match (self.display_handle(), other.display_handle()) { + (Ok(lhs), Ok(rhs)) => lhs == rhs, + _ => false, + } } } +impl Eq for OwnedDisplayHandle {} + pub(crate) trait EventLoopProxyProvider: Send + Sync { /// See [`EventLoopProxy::wake_up`] for details. fn wake_up(&self); diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index acc52af9ae..713c7cb700 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -19,7 +19,7 @@ use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWrite use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, - OwnedDisplayHandle as RootOwnedDisplayHandle, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::monitor::MonitorHandle as RootMonitorHandle; use crate::platform::pump_events::PumpStatus; @@ -718,8 +718,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.exit.get() } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - RootOwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -737,12 +737,10 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop { #[derive(Clone, PartialEq, Eq)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::AndroidDisplayHandle::new().into()) +impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::AndroidDisplayHandle::new(); + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw.into()) }) } } diff --git a/src/platform_impl/apple/appkit/event_loop.rs b/src/platform_impl/apple/appkit/event_loop.rs index d14fbb8659..4e8648d0f8 100644 --- a/src/platform_impl/apple/appkit/event_loop.rs +++ b/src/platform_impl/apple/appkit/event_loop.rs @@ -5,6 +5,7 @@ use std::panic::{catch_unwind, resume_unwind, RefUnwindSafe, UnwindSafe}; use std::ptr; use std::rc::{Rc, Weak}; use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; +use std::sync::Arc; use std::time::{Duration, Instant}; use core_foundation::base::{CFIndex, CFRelease}; @@ -19,6 +20,7 @@ use objc2_app_kit::{ NSApplicationWillTerminateNotification, NSWindow, }; use objc2_foundation::{MainThreadMarker, NSNotificationCenter, NSObject, NSObjectProtocol}; +use rwh_06::HasDisplayHandle; use super::super::notification_center::create_observer; use super::app::WinitApplication; @@ -32,7 +34,7 @@ use crate::error::{EventLoopError, RequestError}; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, - OwnedDisplayHandle as RootOwnedDisplayHandle, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::monitor::MonitorHandle as RootMonitorHandle; use crate::platform::macos::ActivationPolicy; @@ -150,8 +152,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.app_state.exiting() } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - RootOwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -388,15 +390,12 @@ impl EventLoop { } } -#[derive(Clone, PartialEq, Eq)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::AppKitDisplayHandle::new().into()) +impl HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new()); + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } } } diff --git a/src/platform_impl/apple/appkit/mod.rs b/src/platform_impl/apple/appkit/mod.rs index 3f7e2b9293..4aacb90103 100644 --- a/src/platform_impl/apple/appkit/mod.rs +++ b/src/platform_impl/apple/appkit/mod.rs @@ -17,7 +17,7 @@ mod window_delegate; pub(crate) use self::cursor::CustomCursor as PlatformCustomCursor; pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra}; pub(crate) use self::event_loop::{ - ActiveEventLoop, EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes, }; pub(crate) use self::monitor::{MonitorHandle, VideoModeHandle}; pub(crate) use self::window::Window; diff --git a/src/platform_impl/apple/uikit/event_loop.rs b/src/platform_impl/apple/uikit/event_loop.rs index 22a89800c8..4f93a61d90 100644 --- a/src/platform_impl/apple/uikit/event_loop.rs +++ b/src/platform_impl/apple/uikit/event_loop.rs @@ -1,6 +1,7 @@ use std::ffi::{c_char, c_int, c_void}; use std::ptr::{self, NonNull}; use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; +use std::sync::Arc; use core_foundation::base::{CFIndex, CFRelease}; use core_foundation::runloop::{ @@ -19,6 +20,7 @@ use objc2_ui_kit::{ UIApplicationWillEnterForegroundNotification, UIApplicationWillResignActiveNotification, UIApplicationWillTerminateNotification, UIScreen, }; +use rwh_06::HasDisplayHandle; use super::super::notification_center::create_observer; use super::app_state::{send_occluded_event_for_all_windows, AppState, EventWrapper}; @@ -29,7 +31,7 @@ use crate::event::Event; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, - OwnedDisplayHandle as RootOwnedDisplayHandle, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::monitor::MonitorHandle as RootMonitorHandle; use crate::platform_impl::Window; @@ -93,8 +95,8 @@ impl RootActiveEventLoop for ActiveEventLoop { false } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - RootOwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -112,12 +114,10 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop { #[derive(Clone, PartialEq, Eq)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::UiKitDisplayHandle::new().into()) +impl HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::RawDisplayHandle::UiKit(rwh_06::UiKitDisplayHandle::new()); + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } } } diff --git a/src/platform_impl/apple/uikit/mod.rs b/src/platform_impl/apple/uikit/mod.rs index d000e978f3..d5560c7e73 100644 --- a/src/platform_impl/apple/uikit/mod.rs +++ b/src/platform_impl/apple/uikit/mod.rs @@ -10,8 +10,7 @@ mod window; use std::fmt; pub(crate) use self::event_loop::{ - ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle, - PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, EventLoopProxy, PlatformSpecificEventLoopAttributes, }; pub(crate) use self::monitor::{MonitorHandle, VideoModeHandle}; pub(crate) use self::window::{PlatformSpecificWindowAttributes, Window}; diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index ba8d96d3f1..55ba7e2e02 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -396,58 +396,6 @@ impl AsRawFd for EventLoop { } } -#[derive(Clone)] -#[allow(dead_code)] -pub(crate) enum OwnedDisplayHandle { - #[cfg(x11_platform)] - X(Arc), - #[cfg(wayland_platform)] - Wayland(wayland_client::Connection), -} - -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - use std::ptr::NonNull; - - match self { - #[cfg(x11_platform)] - Self::X(xconn) => Ok(rwh_06::XlibDisplayHandle::new( - NonNull::new(xconn.display.cast()), - xconn.default_screen_index() as _, - ) - .into()), - - #[cfg(wayland_platform)] - Self::Wayland(conn) => { - use sctk::reexports::client::Proxy; - - Ok(rwh_06::WaylandDisplayHandle::new( - NonNull::new(conn.display().id().as_ptr().cast()).unwrap(), - ) - .into()) - }, - } - } -} - -impl PartialEq for OwnedDisplayHandle { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - #[cfg(x11_platform)] - (Self::X(this), Self::X(other)) => Arc::as_ptr(this).eq(&Arc::as_ptr(other)), - #[cfg(wayland_platform)] - (Self::Wayland(this), Self::Wayland(other)) => this.eq(other), - #[cfg(all(x11_platform, wayland_platform))] - _ => false, - } - } -} - -impl Eq for OwnedDisplayHandle {} - /// Returns the minimum `Option`, taking into account that `None` /// equates to an infinite timeout, not a zero timeout (so can't just use /// `Option::min`) diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 986183661c..0ce019f6b1 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -16,7 +16,10 @@ use crate::cursor::OnlyCursorImage; use crate::dpi::LogicalSize; use crate::error::{EventLoopError, OsError, RequestError}; use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent}; -use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; +use crate::event_loop::{ + ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, + OwnedDisplayHandle as CoreOwnedDisplayHandle, +}; use crate::platform::pump_events::PumpStatus; use crate::platform_impl::platform::min_timeout; use crate::platform_impl::PlatformCustomCursor; @@ -49,7 +52,7 @@ pub struct EventLoop { wayland_dispatcher: WaylandDispatcher, /// Connection to the wayland server. - connection: Connection, + handle: Arc, /// Event loop window target. active_event_loop: ActiveEventLoop, @@ -117,8 +120,9 @@ impl EventLoop { }) .map_err(|err| os_error!(err))?; + let handle = Arc::new(OwnedDisplayHandle::new(connection)); let active_event_loop = ActiveEventLoop { - connection: connection.clone(), + handle: handle.clone(), wayland_dispatcher: wayland_dispatcher.clone(), event_loop_awakener, event_loop_proxy: EventLoopProxy::new(ping).into(), @@ -133,7 +137,7 @@ impl EventLoop { compositor_updates: Vec::new(), buffer_sink: EventSink::default(), window_ids: Vec::new(), - connection, + handle, wayland_dispatcher, event_loop, active_event_loop, @@ -227,7 +231,7 @@ impl EventLoop { // // Checking for flush error is essential to perform an exit with error, since // once we have a protocol error, we could get stuck retrying... - if self.connection.flush().is_err() { + if self.handle.connection.flush().is_err() { self.set_exit_code(1); return; } @@ -561,8 +565,8 @@ pub struct ActiveEventLoop { /// Dispatcher of Wayland events. pub wayland_dispatcher: WaylandDispatcher, - /// Connection to the wayland server. - pub connection: Connection, + /// Handle for the underlying event loop. + pub handle: Arc, } impl RootActiveEventLoop for ActiveEventLoop { @@ -628,10 +632,8 @@ impl RootActiveEventLoop for ActiveEventLoop { None } - fn owned_display_handle(&self) -> crate::event_loop::OwnedDisplayHandle { - crate::event_loop::OwnedDisplayHandle { - platform: crate::platform_impl::OwnedDisplayHandle::Wayland(self.connection.clone()), - } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(self.handle.clone()) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -654,6 +656,22 @@ impl ActiveEventLoop { } impl rwh_06::HasDisplayHandle for ActiveEventLoop { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + self.handle.display_handle() + } +} + +pub struct OwnedDisplayHandle { + pub(crate) connection: Connection, +} + +impl OwnedDisplayHandle { + fn new(connection: Connection) -> Self { + Self { connection } + } +} + +impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { fn display_handle(&self) -> Result, rwh_06::HandleError> { use sctk::reexports::client::Proxy; diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 5935011b31..725cb72bcb 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -87,7 +87,7 @@ impl Window { let compositor = state.compositor_state.clone(); let xdg_activation = state.xdg_activation.as_ref().map(|activation_state| activation_state.global().clone()); - let display = event_loop_window_target.connection.display(); + let display = event_loop_window_target.handle.connection.display(); let size: Size = attributes.surface_size.unwrap_or(LogicalSize::new(800., 600.).into()); @@ -103,7 +103,7 @@ impl Window { state.xdg_shell.create_window(surface.clone(), default_decorations, &queue_handle); let mut window_state = WindowState::new( - event_loop_window_target.connection.clone(), + event_loop_window_target.handle.clone(), &event_loop_window_target.queue_handle, &state, size, diff --git a/src/platform_impl/linux/wayland/window/state.rs b/src/platform_impl/linux/wayland/window/state.rs index 8c859edfc1..69430d79b0 100644 --- a/src/platform_impl/linux/wayland/window/state.rs +++ b/src/platform_impl/linux/wayland/window/state.rs @@ -10,7 +10,7 @@ use sctk::reexports::client::backend::ObjectId; use sctk::reexports::client::protocol::wl_seat::WlSeat; use sctk::reexports::client::protocol::wl_shm::WlShm; use sctk::reexports::client::protocol::wl_surface::WlSurface; -use sctk::reexports::client::{Connection, Proxy, QueueHandle}; +use sctk::reexports::client::{Proxy, QueueHandle}; use sctk::reexports::csd_frame::{ DecorationsFrame, FrameAction, FrameClick, ResizeEdge, WindowState as XdgWindowState, }; @@ -31,6 +31,7 @@ use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur; use crate::cursor::CustomCursor as RootCustomCursor; use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize, Size}; use crate::error::{NotSupportedError, RequestError}; +use crate::platform_impl::wayland::event_loop::OwnedDisplayHandle; use crate::platform_impl::wayland::logical_to_physical_rounded; use crate::platform_impl::wayland::seat::{ PointerConstraintsState, WinitPointerData, WinitPointerDataExt, ZwpTextInputV3Ext, @@ -52,7 +53,7 @@ const MIN_WINDOW_SIZE: LogicalSize = LogicalSize::new(2, 1); /// The state of the window which is being updated from the [`WinitState`]. pub struct WindowState { /// The connection to Wayland server. - pub connection: Connection, + pub handle: Arc, /// The `Shm` to set cursor. pub shm: WlShm, @@ -161,7 +162,7 @@ pub struct WindowState { impl WindowState { /// Create new window state. pub fn new( - connection: Connection, + handle: Arc, queue_handle: &QueueHandle, winit_state: &WinitState, initial_size: Size, @@ -183,7 +184,7 @@ impl WindowState { blur: None, blur_manager: winit_state.kwin_blur_manager.clone(), compositor, - connection, + handle, csd_fails: false, cursor_grab_mode: GrabState::new(), selected_cursor: Default::default(), @@ -693,7 +694,7 @@ impl WindowState { } self.apply_on_pointer(|pointer, _| { - if pointer.set_cursor(&self.connection, cursor_icon).is_err() { + if pointer.set_cursor(&self.handle.connection, cursor_icon).is_err() { warn!("Failed to set cursor to {:?}", cursor_icon); } }) diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 3ed6135303..6f1dae2aa2 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -28,13 +28,13 @@ use crate::event::{DeviceId, Event, StartCause, WindowEvent}; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, - OwnedDisplayHandle as RootOwnedDisplayHandle, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::platform::pump_events::PumpStatus; use crate::platform_impl::common::xkb::Context; use crate::platform_impl::platform::min_timeout; use crate::platform_impl::x11::window::Window; -use crate::platform_impl::{OwnedDisplayHandle, PlatformCustomCursor}; +use crate::platform_impl::PlatformCustomCursor; use crate::window::{ CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowAttributes, WindowId, @@ -648,20 +648,6 @@ impl ActiveEventLoop { .expect_then_ignore_error("Failed to update device event filter"); } - pub fn raw_display_handle_rwh_06( - &self, - ) -> 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"), - ), - self.xconn.default_screen_index() as c_int, - ); - Ok(display_handle.into()) - } - pub(crate) fn clear_exit(&self) { self.exit.set(None) } @@ -739,9 +725,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.exit.get().is_some() } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - let handle = OwnedDisplayHandle::X(self.x_connection().clone()); - RootOwnedDisplayHandle { platform: handle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(self.x_connection().clone()) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -751,8 +736,7 @@ impl RootActiveEventLoop for ActiveEventLoop { impl rwh_06::HasDisplayHandle for ActiveEventLoop { fn display_handle(&self) -> Result, rwh_06::HandleError> { - let raw = self.raw_display_handle_rwh_06()?; - unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } + self.xconn.display_handle() } } diff --git a/src/platform_impl/linux/x11/xdisplay.rs b/src/platform_impl/linux/x11/xdisplay.rs index 9494ce633f..abce8eb59f 100644 --- a/src/platform_impl/linux/x11/xdisplay.rs +++ b/src/platform_impl/linux/x11/xdisplay.rs @@ -1,9 +1,11 @@ use std::collections::HashMap; use std::error::Error; +use std::ffi::c_int; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard}; use std::{fmt, ptr}; +use rwh_06::HasDisplayHandle; use x11rb::connection::Connection; use x11rb::protocol::randr::ConnectionExt as _; use x11rb::protocol::render; @@ -62,6 +64,13 @@ pub struct XConnection { pub cursor_cache: Mutex, xproto::Cursor>>, } +impl HasDisplayHandle for XConnection { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.raw_display_handle()?; + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } + } +} + unsafe impl Send for XConnection {} unsafe impl Sync for XConnection {} @@ -284,6 +293,19 @@ impl XConnection { self.xcb_connection().setup().image_byte_order != endian } + + pub fn raw_display_handle(&self) -> Result { + let display_handle = rwh_06::XlibDisplayHandle::new( + // SAFETY: display will never be null + Some( + std::ptr::NonNull::new(self.display as *mut _) + .expect("X11 display should never be null"), + ), + self.default_screen_index() as c_int, + ); + + Ok(display_handle.into()) + } } impl fmt::Debug for XConnection { diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index d7fe7c8e18..1b9cc6042c 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -19,8 +19,9 @@ use crate::application::ApplicationHandler; use crate::error::{EventLoopError, NotSupportedError, RequestError}; use crate::event::{self, Ime, Modifiers, StartCause}; use crate::event_loop::{ - self, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, + ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::keyboard::{ Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode, @@ -741,8 +742,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.exit.get() } - fn owned_display_handle(&self) -> event_loop::OwnedDisplayHandle { - event_loop::OwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -757,14 +758,12 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop { } } -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::OrbitalDisplayHandle::new().into()) +impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new()); + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } } } diff --git a/src/platform_impl/orbital/mod.rs b/src/platform_impl/orbital/mod.rs index de729875ac..593e1e5215 100644 --- a/src/platform_impl/orbital/mod.rs +++ b/src/platform_impl/orbital/mod.rs @@ -5,7 +5,7 @@ use std::{fmt, str}; use smol_str::SmolStr; -pub(crate) use self::event_loop::{ActiveEventLoop, EventLoop, OwnedDisplayHandle}; +pub(crate) use self::event_loop::{ActiveEventLoop, EventLoop}; use crate::dpi::{PhysicalPosition, PhysicalSize}; use crate::keyboard::Key; mod event_loop; diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index 560200b2ad..f42baf5728 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -10,7 +10,7 @@ pub(crate) mod runner; mod state; mod window_target; -pub(crate) use window_target::{ActiveEventLoop, OwnedDisplayHandle}; +pub(crate) use window_target::ActiveEventLoop; pub struct EventLoop { elw: ActiveEventLoop, diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index d4e4059f88..2ab0e78f8c 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -14,7 +14,7 @@ use crate::error::{NotSupportedError, RequestError}; use crate::event::{ElementState, Event, KeyEvent, TouchPhase, WindowEvent}; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, - EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle, + EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::keyboard::ModifiersState; use crate::monitor::MonitorHandle as RootMonitorHandle; @@ -547,8 +547,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.runner.exiting() } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - RootOwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -563,14 +563,12 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop { } } -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::WebDisplayHandle::new().into()) +impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new()); + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } } } diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs index 158445ffee..e7f8f9d644 100644 --- a/src/platform_impl/web/mod.rs +++ b/src/platform_impl/web/mod.rs @@ -38,7 +38,7 @@ pub(crate) use cursor::{ }; pub(crate) use self::event_loop::{ - ActiveEventLoop, EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes, }; pub(crate) use self::keyboard::KeyEventExtra; pub(crate) use self::monitor::{ diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 1d1531ae16..874ae06a8c 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -70,7 +70,7 @@ use crate::event::{ use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProxy as RootEventLoopProxy, EventLoopProxyProvider, - OwnedDisplayHandle as RootOwnedDisplayHandle, + OwnedDisplayHandle as CoreOwnedDisplayHandle, }; use crate::keyboard::ModifiersState; use crate::monitor::MonitorHandle as RootMonitorHandle; @@ -516,8 +516,8 @@ impl RootActiveEventLoop for ActiveEventLoop { self.runner_shared.set_exit_code(0) } - fn owned_display_handle(&self) -> RootOwnedDisplayHandle { - RootOwnedDisplayHandle { platform: OwnedDisplayHandle } + fn owned_display_handle(&self) -> CoreOwnedDisplayHandle { + CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle)) } fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle { @@ -532,15 +532,13 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop { } } -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone)] pub(crate) struct OwnedDisplayHandle; -impl OwnedDisplayHandle { - #[inline] - pub fn raw_display_handle_rwh_06( - &self, - ) -> Result { - Ok(rwh_06::WindowsDisplayHandle::new().into()) +impl rwh_06::HasDisplayHandle for OwnedDisplayHandle { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = rwh_06::RawDisplayHandle::Windows(rwh_06::WindowsDisplayHandle::new()); + unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) } } } diff --git a/src/platform_impl/windows/mod.rs b/src/platform_impl/windows/mod.rs index ebc5fecc63..0bf9fe8660 100644 --- a/src/platform_impl/windows/mod.rs +++ b/src/platform_impl/windows/mod.rs @@ -2,9 +2,7 @@ use smol_str::SmolStr; use windows_sys::Win32::Foundation::HWND; use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX}; -pub(crate) use self::event_loop::{ - EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes, -}; +pub(crate) use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes}; pub use self::icon::WinIcon as PlatformIcon; pub(crate) use self::icon::{SelectedCursor, WinCursor as PlatformCustomCursor, WinIcon}; pub(crate) use self::keyboard::{physicalkey_to_scancode, scancode_to_physicalkey};