diff --git a/examples/application.rs b/examples/application.rs index 75d936e505..00a77db2f2 100644 --- a/examples/application.rs +++ b/examples/application.rs @@ -41,7 +41,7 @@ use winit::platform::web::{ActiveEventLoopExtWeb, WindowAttributesWeb}; use winit::platform::x11::{ActiveEventLoopExtX11, WindowAttributesX11}; use winit::window::{ CursorGrabMode, ImeCapabilities, ImeEnableRequest, ImePurpose, ImeRequestData, ResizeDirection, - Theme, Window, WindowAttributes, WindowId, + WindowId, Theme, Window, WindowAttributes, }; use winit_core::application::macos::ApplicationHandlerExtMacOS; use winit_core::window::ImeRequest; diff --git a/examples/child_window.rs b/examples/child_window.rs index e87207828b..1e70f68675 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -8,7 +8,7 @@ fn main() -> Result<(), impl std::error::Error> { use winit::event::{ElementState, KeyEvent, WindowEvent}; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::raw_window_handle::HasRawWindowHandle; - use winit::window::{Window, WindowAttributes, WindowId}; + use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 8fb09bb3f0..bbd4475be6 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -11,7 +11,7 @@ use winit::application::ApplicationHandler; use winit::event::{ElementState, KeyEvent, StartCause, WindowEvent}; use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::{Window, WindowAttributes, WindowId}; +use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/dnd.rs b/examples/dnd.rs index 8b21743bb1..5d674bb02c 100644 --- a/examples/dnd.rs +++ b/examples/dnd.rs @@ -3,7 +3,7 @@ use std::error::Error; use winit::application::ApplicationHandler; use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, EventLoop}; -use winit::window::{Window, WindowAttributes, WindowId}; +use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/pump_events.rs b/examples/pump_events.rs index 4de531ac80..5cce9f0785 100644 --- a/examples/pump_events.rs +++ b/examples/pump_events.rs @@ -11,7 +11,7 @@ fn main() -> std::process::ExitCode { use winit::event::WindowEvent; use winit::event_loop::pump_events::{EventLoopExtPumpEvents, PumpStatus}; use winit::event_loop::{ActiveEventLoop, EventLoop}; - use winit::window::{Window, WindowAttributes, WindowId}; + use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/run_on_demand.rs b/examples/run_on_demand.rs index f076b43b87..8bd86cd58a 100644 --- a/examples/run_on_demand.rs +++ b/examples/run_on_demand.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), Box> { use winit::event::WindowEvent; use winit::event_loop::run_on_demand::EventLoopExtRunOnDemand; use winit::event_loop::{ActiveEventLoop, EventLoop}; - use winit::window::{Window, WindowAttributes, WindowId}; + use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/util/fill.rs b/examples/util/fill.rs index 0b1a4fb06a..22423ac74b 100644 --- a/examples/util/fill.rs +++ b/examples/util/fill.rs @@ -29,7 +29,7 @@ mod platform { use softbuffer::{Context, Surface}; #[cfg(all(web_platform, not(android_platform)))] use web_time::Instant; - use winit::window::{Window, WindowId}; + use winit::window::{WindowId, Window}; thread_local! { // NOTE: You should never do things like that, create context and drop it before diff --git a/examples/window.rs b/examples/window.rs index 76c60c39e8..c92593648d 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -7,7 +7,7 @@ use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, EventLoop}; #[cfg(web_platform)] use winit::platform::web::WindowAttributesWeb; -use winit::window::{Window, WindowAttributes, WindowId}; +use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/examples/x11_embed.rs b/examples/x11_embed.rs index c047f71ef4..54ca5933a4 100644 --- a/examples/x11_embed.rs +++ b/examples/x11_embed.rs @@ -7,7 +7,7 @@ fn main() -> Result<(), Box> { use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::platform::x11::WindowAttributesX11; - use winit::window::{Window, WindowAttributes, WindowId}; + use winit::window::{WindowId, Window, WindowAttributes}; #[path = "util/fill.rs"] mod fill; diff --git a/winit-android/src/event_loop.rs b/winit-android/src/event_loop.rs index 1396574cbc..54ce00b403 100644 --- a/winit-android/src/event_loop.rs +++ b/winit-android/src/event_loop.rs @@ -21,11 +21,12 @@ use winit_core::event_loop::{ EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, OwnedDisplayHandle as CoreOwnedDisplayHandle, }; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; use winit_core::window::{ self, CursorGrabMode, ImeCapabilities, ImePurpose, ImeRequest, ImeRequestError, - ResizeDirection, Theme, Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, - WindowLevel, + ResizeDirection, Surface as CoreSurface, Theme, Window as CoreWindow, WindowAttributes, + WindowButtons, WindowId, WindowLevel, }; use crate::keycodes; @@ -821,7 +822,9 @@ impl rwh_06::HasWindowHandle for Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> WindowId { GLOBAL_WINDOW } @@ -848,6 +851,42 @@ impl CoreWindow for Window { fn pre_present_notify(&self) {} + fn surface_size(&self) -> PhysicalSize { + self.outer_size() + } + + fn request_surface_size(&self, _size: Size) -> Option> { + Some(self.surface_size()) + } + + fn set_transparent(&self, _transparent: bool) {} + + fn set_cursor(&self, _: Cursor) {} + + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) + } + + fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_grab is not supported").into()) + } + + fn set_cursor_visible(&self, _: bool) {} + + fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl CoreWindow for Window { fn surface_position(&self) -> PhysicalPosition { (0, 0).into() } @@ -859,15 +898,6 @@ impl CoreWindow for Window { fn set_outer_position(&self, _position: Position) { // no effect } - - fn surface_size(&self) -> PhysicalSize { - self.outer_size() - } - - fn request_surface_size(&self, _size: Size) -> Option> { - Some(self.surface_size()) - } - fn outer_size(&self) -> PhysicalSize { screen_size(&self.app) } @@ -888,8 +918,6 @@ impl CoreWindow for Window { fn set_title(&self, _title: &str) {} - fn set_transparent(&self, _transparent: bool) {} - fn set_blur(&self, _blur: bool) {} fn set_visible(&self, _visibility: bool) {} @@ -977,18 +1005,6 @@ impl CoreWindow for Window { fn request_user_attention(&self, _request_type: Option) {} - fn set_cursor(&self, _: Cursor) {} - - fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_position is not supported").into()) - } - - fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_grab is not supported").into()) - } - - fn set_cursor_visible(&self, _: bool) {} - fn drag_window(&self) -> Result<(), RequestError> { Err(NotSupportedError::new("drag_window is not supported").into()) } @@ -1000,10 +1016,6 @@ impl CoreWindow for Window { #[inline] fn show_window_menu(&self, _position: Position) {} - fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) - } - fn set_theme(&self, _theme: Option) {} fn theme(&self) -> Option { @@ -1021,14 +1033,6 @@ impl CoreWindow for Window { } fn reset_dead_keys(&self) {} - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } fn screen_size(app: &AndroidApp) -> PhysicalSize { diff --git a/winit-appkit/src/lib.rs b/winit-appkit/src/lib.rs index 546e768c99..cb606eff1a 100644 --- a/winit-appkit/src/lib.rs +++ b/winit-appkit/src/lib.rs @@ -324,7 +324,7 @@ pub enum ActivationPolicy { /// - `with_titlebar_buttons_hidden` /// - `with_fullsize_content_view` /// -/// [`WindowAttributes::with_decorations`]: crate::window::WindowAttributes::with_decorations +/// [`WindowAttributes::with_decorations`]: winit_core::window::WindowAttributes::with_decorations #[derive(Clone, Debug, PartialEq)] pub struct WindowAttributesMacOS { pub(crate) movable_by_window_background: bool, diff --git a/winit-appkit/src/window.rs b/winit-appkit/src/window.rs index 515ac55f78..54cdab5226 100644 --- a/winit-appkit/src/window.rs +++ b/winit-appkit/src/window.rs @@ -11,10 +11,11 @@ use objc2_foundation::NSObject; use winit_core::cursor::Cursor; use winit_core::error::RequestError; use winit_core::icon::Icon; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; use winit_core::window::{ - ImeCapabilities, ImeRequest, ImeRequestError, Theme, UserAttentionType, Window as CoreWindow, - WindowAttributes, WindowButtons, WindowId, WindowLevel, + ImeCapabilities, ImeRequest, ImeRequestError, Surface as CoreSurface, Theme, UserAttentionType, + Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel, }; use super::event_loop::ActiveEventLoop; @@ -92,7 +93,9 @@ impl rwh_06::HasWindowHandle for Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> winit_core::window::WindowId { self.maybe_wait_on_main(|delegate| delegate.id()) } @@ -109,6 +112,75 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.pre_present_notify()); } + fn surface_size(&self) -> dpi::PhysicalSize { + self.maybe_wait_on_main(|delegate| delegate.surface_size()) + } + + fn request_surface_size(&self, size: Size) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.request_surface_size(size)) + } + + fn set_transparent(&self, transparent: bool) { + self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); + } + + fn set_cursor(&self, cursor: Cursor) { + self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); + } + + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position)) + } + + fn set_cursor_grab( + &self, + mode: winit_core::window::CursorGrabMode, + ) -> Result<(), RequestError> { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode)) + } + + fn set_cursor_visible(&self, visible: bool) { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) + } + + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest)); + Ok(()) + } + + fn current_monitor(&self) -> Option { + self.maybe_wait_on_main(|delegate| { + delegate.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + }) + } + + fn available_monitors(&self) -> Box> { + self.maybe_wait_on_main(|delegate| { + Box::new( + delegate + .available_monitors() + .into_iter() + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), + ) + }) + } + + fn primary_monitor(&self) -> Option { + self.maybe_wait_on_main(|delegate| { + delegate.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + }) + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl CoreWindow for Window { fn reset_dead_keys(&self) { self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys()); } @@ -125,14 +197,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_outer_position(position)); } - fn surface_size(&self) -> dpi::PhysicalSize { - self.maybe_wait_on_main(|delegate| delegate.surface_size()) - } - - fn request_surface_size(&self, size: Size) -> Option> { - self.maybe_wait_on_main(|delegate| delegate.request_surface_size(size)) - } - fn outer_size(&self) -> dpi::PhysicalSize { self.maybe_wait_on_main(|delegate| delegate.outer_size()) } @@ -161,10 +225,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_title(title)); } - fn set_transparent(&self, transparent: bool) { - self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); - } - fn set_blur(&self, blur: bool) { self.maybe_wait_on_main(|delegate| delegate.set_blur(blur)); } @@ -269,25 +329,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.title()) } - fn set_cursor(&self, cursor: Cursor) { - self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); - } - - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position)) - } - - fn set_cursor_grab( - &self, - mode: winit_core::window::CursorGrabMode, - ) -> Result<(), RequestError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode)) - } - - fn set_cursor_visible(&self, visible: bool) { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) - } - fn drag_window(&self) -> Result<(), RequestError> { self.maybe_wait_on_main(|delegate| delegate.drag_window()) } @@ -302,42 +343,6 @@ impl CoreWindow for Window { fn show_window_menu(&self, position: Position) { self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position)) } - - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest)); - Ok(()) - } - - fn current_monitor(&self) -> Option { - self.maybe_wait_on_main(|delegate| { - delegate.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - }) - } - - fn available_monitors(&self) -> Box> { - self.maybe_wait_on_main(|delegate| { - Box::new( - delegate - .available_monitors() - .into_iter() - .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), - ) - }) - } - - fn primary_monitor(&self) -> Option { - self.maybe_wait_on_main(|delegate| { - delegate.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - }) - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } define_class!( diff --git a/winit-core/src/cursor.rs b/winit-core/src/cursor.rs index 9acebd4095..45aebb1b6c 100644 --- a/winit-core/src/cursor.rs +++ b/winit-core/src/cursor.rs @@ -15,7 +15,7 @@ pub const MAX_CURSOR_SIZE: u16 = 2048; const PIXEL_SIZE: usize = 4; -/// See [`Window::set_cursor()`][crate::window::Window::set_cursor] for more details. +/// See [`Surface::set_cursor()`][crate::window::Surface::set_cursor] for more details. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Cursor { Icon(CursorIcon), diff --git a/winit-core/src/event.rs b/winit-core/src/event.rs index 42c37c8d1c..9c0aea9fd7 100644 --- a/winit-core/src/event.rs +++ b/winit-core/src/event.rs @@ -10,9 +10,9 @@ use smol_str::SmolStr; use crate::error::RequestError; use crate::event_loop::AsyncRequestSerial; use crate::keyboard::{self, ModifiersKeyState, ModifiersKeys, ModifiersState}; -#[cfg(doc)] -use crate::window::Window; use crate::window::{ActivationToken, Theme}; +#[cfg(doc)] +use crate::window::{Surface, Window}; use crate::Instant; /// Describes the reason the event loop is resuming. @@ -48,12 +48,12 @@ pub enum WindowEvent { /// The size of the window's surface has changed. /// /// Contains the new dimensions of the surface (can also be retrieved with - /// [`Window::surface_size`]). + /// [`Surface::surface_size`]). /// /// This event will not necessarily be emitted upon window creation, query - /// [`Window::surface_size`] if you need to determine the surface's initial size. + /// [`Surface::surface_size`] if you need to determine the surface's initial size. /// - /// [`Window::surface_size`]: crate::window::Window::surface_size + /// [`Surface::surface_size`]: crate::window::Surface::surface_size SurfaceResized(PhysicalSize), /// The position of the window has changed. @@ -352,11 +352,11 @@ pub enum WindowEvent { /// window is resized to the value suggested by the OS, but it can be changed to any value. /// /// This event will not necessarily be emitted upon window creation, query - /// [`Window::scale_factor`] if you need to determine the window's initial scale factor. + /// [`Surface::scale_factor`] if you need to determine the window's initial scale factor. /// /// For more information about DPI in general, see the [`dpi`] crate. /// - /// [`Window::scale_factor`]: crate::window::Window::scale_factor + /// [`Surface::scale_factor`]: crate::window::Surface::scale_factor ScaleFactorChanged { scale_factor: f64, /// Handle to update surface size during scale changes. @@ -411,7 +411,7 @@ pub enum WindowEvent { /// This gets triggered in a few scenarios: /// - The OS has performed an operation that's invalidated the window's contents (such as /// resizing the window, or changing [the safe area]). - /// - The application has explicitly requested a redraw via [`Window::request_redraw`]. + /// - The application has explicitly requested a redraw via [`Surface::request_redraw`]. /// /// Winit will aggregate duplicate redraw requests into a single event, to /// help avoid duplicating rendering work. diff --git a/winit-core/src/lib.rs b/winit-core/src/lib.rs index 89bc682164..1136b97bc2 100644 --- a/winit-core/src/lib.rs +++ b/winit-core/src/lib.rs @@ -18,6 +18,7 @@ pub mod event_loop; pub mod icon; pub mod keyboard; pub mod monitor; +#[macro_use] pub mod window; // `Instant` is not actually available on `wasm32-unknown-unknown`, the `std` implementation there diff --git a/winit-core/src/monitor.rs b/winit-core/src/monitor.rs index f24e388825..eff9b16c26 100644 --- a/winit-core/src/monitor.rs +++ b/winit-core/src/monitor.rs @@ -4,7 +4,7 @@ //! [`MonitorHandle`] type. This is retrieved from one of the following //! methods, which return an iterator of [`MonitorHandle`]: //! - [`ActiveEventLoop::available_monitors`][crate::event_loop::ActiveEventLoop::available_monitors]. -//! - [`Window::available_monitors`][crate::window::Window::available_monitors]. +//! - [`Surface::available_monitors`][crate::window::Surface::available_monitors]. use std::borrow::Cow; use std::fmt; use std::num::{NonZeroU16, NonZeroU32}; @@ -25,7 +25,7 @@ use crate::as_any::{impl_dyn_casting, AsAny}; /// This can be retrieved from one of the following methods, which return an /// iterator of [`MonitorHandle`]s: /// - [`ActiveEventLoop::available_monitors`](crate::event_loop::ActiveEventLoop::available_monitors). -/// - [`Window::available_monitors`](crate::window::Window::available_monitors). +/// - [`Surface::available_monitors`](crate::window::Surface::available_monitors). /// /// ## Platform-specific /// @@ -95,14 +95,14 @@ pub trait MonitorHandleProvider: AsAny + fmt::Debug + Send + Sync { fn position(&self) -> Option>; /// Returns the scale factor of the underlying monitor. To map logical pixels to physical - /// pixels and vice versa, use [`Window::scale_factor`]. + /// pixels and vice versa, use [`Surface::scale_factor`]. /// /// See the [`dpi`] module for more information. /// - /// - **Wayland:** May differ from [`Window::scale_factor`]. + /// - **Wayland:** May differ from [`Surface::scale_factor`]. /// - **Web:** Always returns `0.0` without `detailed_monitor_permissions`. /// - /// [`Window::scale_factor`]: crate::window::Window::scale_factor + /// [`Surface::scale_factor`]: crate::window::Surface::scale_factor fn scale_factor(&self) -> f64; fn current_video_mode(&self) -> Option; @@ -141,9 +141,9 @@ impl VideoMode { } /// Returns the resolution of this video mode. This **must not** be used to create your - /// rendering surface. Use [`Window::surface_size()`] instead. + /// rendering surface. Use [`Surface::surface_size()`] instead. /// - /// [`Window::surface_size()`]: crate::window::Window::surface_size + /// [`Surface::surface_size()`]: crate::window::Surface::surface_size pub fn size(&self) -> PhysicalSize { self.size } diff --git a/winit-core/src/window.rs b/winit-core/src/window.rs index bea235eeb0..aa6481c5b2 100644 --- a/winit-core/src/window.rs +++ b/winit-core/src/window.rs @@ -15,15 +15,19 @@ use crate::error::RequestError; use crate::icon::Icon; use crate::monitor::{Fullscreen, MonitorHandle}; -/// Identifier of a window. Unique for each window. +/// Identifier of a surface. Unique for each surface. +/// The name has been kept as `WindowId` for backwards compatibility. /// -/// Can be obtained with [`window.id()`][`Window::id`]. +/// Can be obtained with [`surface.id()`][`Surface::id`]. /// -/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you +/// Whenever you receive an event specific to a surface, this event contains a `WindowId` which you /// can then compare to the ids of your windows. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(usize); +// TODO: possible name change of WindowId for consistency +// pub type WindowId = WindowId; + impl WindowId { /// Convert the `WindowId` into the underlying integer. /// @@ -84,7 +88,7 @@ impl WindowAttributes { /// /// If this is not set, some platform-specific dimensions will be used. /// - /// See [`Window::request_surface_size`] for details. + /// See [`Surface::request_surface_size`] for details. #[inline] pub fn with_surface_size>(mut self, size: S) -> Self { self.surface_size = Some(size.into()); @@ -223,7 +227,7 @@ impl WindowAttributes { /// If this is `true`, writing colors with alpha values different than /// `1.0` will produce a transparent window. On some platforms this /// is more of a hint for the system and you'd still have the alpha - /// buffer. To control it see [`Window::set_transparent`]. + /// buffer. To control it see [`Surface::set_transparent`]. /// /// The default is `false`. #[inline] @@ -339,7 +343,7 @@ impl WindowAttributes { /// /// The default is [`CursorIcon::Default`]. /// - /// See [`Window::set_cursor()`] for more details. + /// See [`Surface::set_cursor()`] for more details. #[inline] pub fn with_cursor(mut self, cursor: impl Into) -> Self { self.cursor = cursor.into(); @@ -457,25 +461,16 @@ pub trait PlatformWindowAttributes: AsAny + std::fmt::Debug + Send + Sync { impl_dyn_casting!(PlatformWindowAttributes); -/// Represents a window. -/// -/// The window is closed when dropped. -/// -/// ## Threading -/// -/// This is `Send + Sync`, meaning that it can be freely used from other -/// threads. -/// -/// However, some platforms (macOS, Web and iOS) only allow user interface -/// interactions on the main thread, so on those platforms, if you use the -/// window from a thread other than the main, the code is scheduled to run on -/// the main thread, and your thread may be blocked until that completes. -/// -/// ## Platform-specific +/// Represents a drawable, resizable surface that is visible on-screen. /// -/// **Web:** The [`Window`], which is represented by a `HTMLElementCanvas`, can -/// not be closed by dropping the [`Window`]. -pub trait Window: AsAny + Send + Sync + fmt::Debug { +/// The surface is closed when dropped. +pub trait Surface: AsAny + Send + Sync + fmt::Debug { + /// Attempts to downcast this surface to a core surface type, e.g. [`Window`]. + fn try_downcast(&self) -> Option>; + + /// Attempts to downcast this surface mutably to a core surface type, e.g. [`Window`]. + fn try_downcast_mut(&mut self) -> Option>; + /// Returns an identifier unique to the window. fn id(&self) -> WindowId; @@ -548,7 +543,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// /// This is the **strongly encouraged** method of redrawing windows, as it can integrate with /// OS-requested redraws (e.g. when a window gets resized). To improve the event delivery - /// consider using [`Window::pre_present_notify`] as described in docs. + /// consider using [`Surface::pre_present_notify`] as described in docs. /// /// Applications should always aim to redraw whenever they receive a `RedrawRequested` event. /// @@ -564,7 +559,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Windows** This API uses `RedrawWindow` to request a `WM_PAINT` message and /// `RedrawRequested` is emitted in sync with any `WM_PAINT` messages. /// - **Wayland:** The events are aligned with the frame callbacks when - /// [`Window::pre_present_notify`] is used. + /// [`Surface::pre_present_notify`] is used. /// - **Web:** [`WindowEvent::RedrawRequested`] will be aligned with the /// `requestAnimationFrame`. /// @@ -605,6 +600,230 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// [`WindowEvent::RedrawRequested`]: crate::event::WindowEvent::RedrawRequested fn pre_present_notify(&self); + /// Returns the size of the window's render-able surface. + /// + /// This is the dimensions you should pass to things like Wgpu or Glutin when configuring the + /// surface for drawing. See [`WindowEvent::SurfaceResized`] for listening to changes to this + /// field. + /// + /// Note that to ensure that your content is not obscured by things such as notches or the title + /// bar, you will likely want to only draw important content inside a specific area of the + /// surface, see [`safe_area()`] for details. + /// + /// ## Platform-specific + /// + /// - **Web:** Returns the size of the canvas element. Doesn't account for CSS [`transform`]. + /// + /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform + /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized + /// [`safe_area()`]: Window::safe_area + fn surface_size(&self) -> PhysicalSize; + + /// Request the new size for the surface. + /// + /// On platforms where the size is entirely controlled by the user the + /// applied size will be returned immediately, resize event in such case + /// may not be generated. + /// + /// On platforms where resizing is disallowed by the windowing system, the current surface size + /// is returned immediately, and the user one is ignored. + /// + /// When `None` is returned, it means that the request went to the display system, + /// and the actual size will be delivered later with the [`WindowEvent::SurfaceResized`]. + /// + /// See [`Surface::surface_size`] for more information about the values. + /// + /// The request could automatically un-maximize the window if it's maximized. + /// + /// ```no_run + /// # use dpi::{LogicalSize, PhysicalSize}; + /// # use winit_core::window::Window; + /// # fn scope(window: &dyn Window) { + /// // Specify the size in logical dimensions like this: + /// let _ = window.request_surface_size(LogicalSize::new(400.0, 200.0).into()); + /// + /// // Or specify the size in physical dimensions like this: + /// let _ = window.request_surface_size(PhysicalSize::new(400, 200).into()); + /// # } + /// ``` + /// + /// ## Platform-specific + /// + /// - **Web:** Sets the size of the canvas element. Doesn't account for CSS [`transform`]. + /// + /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized + /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform + #[must_use] + fn request_surface_size(&self, size: Size) -> Option>; + + /// Change the window transparency state. + /// + /// This is just a hint that may not change anything about + /// the window transparency, however doing a mismatch between + /// the content of your window and this hint may result in + /// visual artifacts. + /// + /// The default value follows the [`WindowAttributes::with_transparent`]. + /// + /// ## Platform-specific + /// + /// - **macOS:** This will reset the window's background color. + /// - **Web / iOS / Android:** Unsupported. + /// - **X11:** Can only be set while building the window, with + /// [`WindowAttributes::with_transparent`]. + fn set_transparent(&self, transparent: bool); + + /// Modifies the cursor icon of the window. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Orbital:** Unsupported. + /// - **Web:** Custom cursors have to be loaded and decoded first, until then the previous + /// cursor is shown. + fn set_cursor(&self, cursor: Cursor); // * + + /// Changes the position of the cursor in window coordinates. + /// + /// ```no_run + /// # use dpi::{LogicalPosition, PhysicalPosition}; + /// # use winit_core::window::Window; + /// # fn scope(window: &dyn Window) { + /// // Specify the position in logical dimensions like this: + /// window.set_cursor_position(LogicalPosition::new(400.0, 200.0).into()); + /// + /// // Or specify the position in physical dimensions like this: + /// window.set_cursor_position(PhysicalPosition::new(400, 200).into()); + /// # } + /// ``` + /// + /// ## Platform-specific + /// + /// - **Wayland**: Cursor must be in [`CursorGrabMode::Locked`]. + /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError>; // * + + /// Set grabbing [mode][CursorGrabMode] on the cursor preventing it from leaving the window. + /// + /// # Example + /// + /// First try confining the cursor, and if that fails, try locking it instead. + /// + /// ```no_run + /// # use winit_core::window::{CursorGrabMode, Window}; + /// # fn scope(window: &dyn Window) { + /// window + /// .set_cursor_grab(CursorGrabMode::Confined) + /// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked)) + /// .unwrap(); + /// # } + /// ``` + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError>; // * + + /// Modifies the cursor's visibility. + /// + /// If `false`, this will hide the cursor. If `true`, this will show the cursor. + /// + /// ## Platform-specific + /// + /// - **Windows:** The cursor is only hidden within the confines of the window. + /// - **X11:** The cursor is only hidden within the confines of the window. + /// - **Wayland:** The cursor is only hidden within the confines of the window. + /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor + /// is outside of the window. + /// - **iOS / Android:** Unsupported. + fn set_cursor_visible(&self, visible: bool); // * + + /// Modifies whether the window catches cursor events. + /// + /// If `true`, the window will catch the cursor events. If `false`, events are passed through + /// the window such that any other window behind it receives them. By default hittest is + /// enabled. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError>; + + /// Returns the monitor on which the window currently resides. + /// + /// Returns `None` if current monitor can't be detected. + fn current_monitor(&self) -> Option; + + /// Returns the list of all the monitors available on the system. + /// + /// This is the same as [`ActiveEventLoop::available_monitors`], and is provided for + /// convenience. + /// + /// [`ActiveEventLoop::available_monitors`]: crate::event_loop::ActiveEventLoop::available_monitors + fn available_monitors(&self) -> Box>; + + /// Returns the primary monitor of the system. + /// + /// Returns `None` if it can't identify any monitor as a primary one. + /// + /// This is the same as [`ActiveEventLoop::primary_monitor`], and is provided for convenience. + /// + /// ## Platform-specific + /// + /// - **Wayland:** Always returns `None`. + /// + /// [`ActiveEventLoop::primary_monitor`]: crate::event_loop::ActiveEventLoop::primary_monitor + fn primary_monitor(&self) -> Option; + + /// Get the raw-window-handle v0.6 display handle. + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle; + + /// Get the raw-window-handle v0.6 window handle. + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle; +} + +impl_dyn_casting!(Surface); + +impl PartialEq for dyn Surface + '_ { + fn eq(&self, other: &dyn Surface) -> bool { + self.id().eq(&other.id()) + } +} + +impl Eq for dyn Surface + '_ {} + +impl std::hash::Hash for dyn Surface + '_ { + fn hash(&self, state: &mut H) { + self.id().hash(state); + } +} + +impl rwh_06::HasDisplayHandle for dyn Surface + '_ { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + self.rwh_06_display_handle().display_handle() + } +} + +impl rwh_06::HasWindowHandle for dyn Surface + '_ { + fn window_handle(&self) -> Result, rwh_06::HandleError> { + self.rwh_06_window_handle().window_handle() + } +} + +/// Represents a toplevel window. +/// +/// The window is closed when dropped. +/// +/// ## Threading +/// +/// This is `Send + Sync`, meaning that it can be freely used from other +/// threads. +/// +/// However, some platforms (macOS, Web and iOS) only allow user interface +/// interactions on the main thread, so on those platforms, if you use the +/// window from a thread other than the main, the code is scheduled to run on +/// the main thread, and your thread may be blocked until that completes. +/// +/// ## Platform-specific +/// +/// **Web:** The [`Window`], which is represented by a `HTMLElementCanvas`, can +/// not be closed by dropping the [`Window`]. +pub trait Window: AsSurface { /// Reset the dead key state of the keyboard. /// /// This is useful when a dead key is bound to trigger an action. Then @@ -682,71 +901,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform fn set_outer_position(&self, position: Position); - /// Returns the size of the window's render-able surface. - /// - /// This is the dimensions you should pass to things like Wgpu or Glutin when configuring the - /// surface for drawing. See [`WindowEvent::SurfaceResized`] for listening to changes to this - /// field. - /// - /// Note that to ensure that your content is not obscured by things such as notches or the title - /// bar, you will likely want to only draw important content inside a specific area of the - /// surface, see [`safe_area()`] for details. - /// - /// ## Platform-specific - /// - /// - **Web:** Returns the size of the canvas element. Doesn't account for CSS [`transform`]. - /// - /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform - /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized - /// [`safe_area()`]: Window::safe_area - fn surface_size(&self) -> PhysicalSize; - - /// Request the new size for the surface. - /// - /// On platforms where the size is entirely controlled by the user the - /// applied size will be returned immediately, resize event in such case - /// may not be generated. - /// - /// On platforms where resizing is disallowed by the windowing system, the current surface size - /// is returned immediately, and the user one is ignored. - /// - /// When `None` is returned, it means that the request went to the display system, - /// and the actual size will be delivered later with the [`WindowEvent::SurfaceResized`]. - /// - /// See [`Window::surface_size`] for more information about the values. - /// - /// The request could automatically un-maximize the window if it's maximized. - /// - /// ```no_run - /// # use dpi::{LogicalSize, PhysicalSize}; - /// # use winit_core::window::Window; - /// # fn scope(window: &dyn Window) { - /// // Specify the size in logical dimensions like this: - /// let _ = window.request_surface_size(LogicalSize::new(400.0, 200.0).into()); - /// - /// // Or specify the size in physical dimensions like this: - /// let _ = window.request_surface_size(PhysicalSize::new(400, 200).into()); - /// # } - /// ``` - /// - /// ## Platform-specific - /// - /// - **Web:** Sets the size of the canvas element. Doesn't account for CSS [`transform`]. - /// - /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized - /// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform - #[must_use] - fn request_surface_size(&self, size: Size) -> Option>; - /// Returns the size of the entire window. /// /// These dimensions include window decorations like the title bar and borders. If you don't - /// want that (and you usually don't), use [`Window::surface_size`] instead. + /// want that (and you usually don't), use [`Surface::surface_size`] instead. /// /// ## Platform-specific /// /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as - /// [`Window::surface_size`]._ + /// [`Surface::surface_size`]._ fn outer_size(&self) -> PhysicalSize; /// The inset area of the surface that is unobstructed. @@ -759,7 +922,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// /// The safe area is a rectangle that is defined relative to the origin at the top-left corner /// of the surface, and the size extending downwards to the right. The area will not extend - /// beyond [the bounds of the surface][Window::surface_size]. + /// beyond [the bounds of the surface][Surface::surface_size]. /// /// Note that the safe area does not take occlusion from other windows into account; in a way, /// it is only a "hardware"-level occlusion. @@ -857,23 +1020,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android:** Unsupported. fn set_title(&self, title: &str); - /// Change the window transparency state. - /// - /// This is just a hint that may not change anything about - /// the window transparency, however doing a mismatch between - /// the content of your window and this hint may result in - /// visual artifacts. - /// - /// The default value follows the [`WindowAttributes::with_transparent`]. - /// - /// ## Platform-specific - /// - /// - **macOS:** This will reset the window's background color. - /// - **Web / iOS / Android:** Unsupported. - /// - **X11:** Can only be set while building the window, with - /// [`WindowAttributes::with_transparent`]. - fn set_transparent(&self, transparent: bool); - /// Change the window blur state. /// /// If `true`, this will make the transparent window background blurry. @@ -909,7 +1055,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// Note that making the window unresizable doesn't exempt you from handling /// [`WindowEvent::SurfaceResized`], as that event can still be triggered by DPI scaling, /// entering fullscreen mode, etc. Also, the window could still be resized by calling - /// [`Window::request_surface_size`]. + /// [`Surface::request_surface_size`]. /// /// ## Platform-specific /// @@ -1297,66 +1443,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / x11 / Wayland / Web:** Unsupported. Always returns an empty string. fn title(&self) -> String; - /// Modifies the cursor icon of the window. - /// - /// ## Platform-specific - /// - /// - **iOS / Android / Orbital:** Unsupported. - /// - **Web:** Custom cursors have to be loaded and decoded first, until then the previous - /// cursor is shown. - fn set_cursor(&self, cursor: Cursor); - - /// Changes the position of the cursor in window coordinates. - /// - /// ```no_run - /// # use dpi::{LogicalPosition, PhysicalPosition}; - /// # use winit_core::window::Window; - /// # fn scope(window: &dyn Window) { - /// // Specify the position in logical dimensions like this: - /// window.set_cursor_position(LogicalPosition::new(400.0, 200.0).into()); - /// - /// // Or specify the position in physical dimensions like this: - /// window.set_cursor_position(PhysicalPosition::new(400, 200).into()); - /// # } - /// ``` - /// - /// ## Platform-specific - /// - /// - **Wayland**: Cursor must be in [`CursorGrabMode::Locked`]. - /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError>; - - /// Set grabbing [mode][CursorGrabMode] on the cursor preventing it from leaving the window. - /// - /// ## Example - /// - /// First try confining the cursor, and if that fails, try locking it instead. - /// - /// ```no_run - /// # use winit_core::window::{CursorGrabMode, Window}; - /// # fn scope(window: &dyn Window) { - /// window - /// .set_cursor_grab(CursorGrabMode::Confined) - /// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked)) - /// .unwrap(); - /// # } - /// ``` - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError>; - - /// Modifies the cursor's visibility. - /// - /// If `false`, this will hide the cursor. If `true`, this will show the cursor. - /// - /// ## Platform-specific - /// - /// - **Windows:** The cursor is only hidden within the confines of the window. - /// - **X11:** The cursor is only hidden within the confines of the window. - /// - **Wayland:** The cursor is only hidden within the confines of the window. - /// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor - /// is outside of the window. - /// - **iOS / Android:** Unsupported. - fn set_cursor_visible(&self, visible: bool); - /// Moves the window with the left mouse button until the button is released. /// /// There's no guarantee that this will work unless the left mouse button was pressed @@ -1391,49 +1477,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// /// [window menu]: https://en.wikipedia.org/wiki/Common_menus_in_Microsoft_Windows#System_menu fn show_window_menu(&self, position: Position); - - /// Modifies whether the window catches cursor events. - /// - /// If `true`, the window will catch the cursor events. If `false`, events are passed through - /// the window such that any other window behind it receives them. By default hittest is - /// enabled. - /// - /// ## Platform-specific - /// - /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError>; - - /// Returns the monitor on which the window currently resides. - /// - /// Returns `None` if current monitor can't be detected. - fn current_monitor(&self) -> Option; - - /// Returns the list of all the monitors available on the system. - /// - /// This is the same as [`ActiveEventLoop::available_monitors`], and is provided for - /// convenience. - /// - /// [`ActiveEventLoop::available_monitors`]: crate::event_loop::ActiveEventLoop::available_monitors - fn available_monitors(&self) -> Box>; - - /// Returns the primary monitor of the system. - /// - /// Returns `None` if it can't identify any monitor as a primary one. - /// - /// This is the same as [`ActiveEventLoop::primary_monitor`], and is provided for convenience. - /// - /// ## Platform-specific - /// - /// - **Wayland:** Always returns `None`. - /// - /// [`ActiveEventLoop::primary_monitor`]: crate::event_loop::ActiveEventLoop::primary_monitor - fn primary_monitor(&self) -> Option; - - /// Get the raw-window-handle v0.6 display handle. - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle; - - /// Get the raw-window-handle v0.6 window handle. - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle; } impl_dyn_casting!(Window); @@ -1466,7 +1509,7 @@ impl rwh_06::HasWindowHandle for dyn Window + '_ { /// The behavior of cursor grabbing. /// -/// Use this enum with [`Window::set_cursor_grab`] to grab the cursor. +/// Use this enum with [`Surface::set_cursor_grab`] to grab the cursor. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum CursorGrabMode { @@ -1752,11 +1795,11 @@ bitflags! { pub struct ImeRequestData { /// Text input purpose. /// - /// To support updating it, enable [`ImeCapabilities::PURPOSE`]. + /// To support updating it, call [`ImeCapabilities::with_purpose`]. pub purpose: Option, /// The IME cursor area which should not be covered by the input method popup. /// - /// To support updating it, enable [`ImeCapabilities::CURSOR_AREA`]. + /// To support updating it, call [`ImeCapabilities::with_cursor_area`]. pub cursor_area: Option<(Position, Size)>, } @@ -1932,3 +1975,94 @@ mod tests { .is_some()); } } +// Implementation trait to allow upcasting to [`Surface`]. +// This trait can be safely removed once MSRV hits Rust 1.86, similar to `AsAny`. +#[doc(hidden)] +pub trait AsSurface: Surface { + #[doc(hidden)] + fn __as_surface(&self) -> &dyn Surface; + #[doc(hidden)] + fn __as_surface_mut(&mut self) -> &mut dyn Surface; + #[doc(hidden)] + fn __into_surface(self: Box) -> Box; +} + +impl AsSurface for T { + fn __as_surface(&self) -> &dyn Surface { + self + } + + fn __as_surface_mut(&mut self) -> &mut dyn Surface { + self + } + + fn __into_surface(self: Box) -> Box { + self + } +} + +/// Dynamic reference to one of the common surface traits. +#[non_exhaustive] +pub enum SurfaceDowncastRef<'a> { + /// A toplevel window, see [`Window`] for details. + Window(&'a dyn Window), +} + +impl SurfaceDowncastRef<'_> { + /// Tries to cast this reference into a [`Window`]. + pub fn as_window(&self) -> Option<&'_ dyn Window> { + match self { + Self::Window(window) => Some(*window), + // _ => None, + } + } +} + +/// Dynamic mutable reference to one of the common surface traits. +pub enum SurfaceDowncastMut<'a> { + /// A toplevel window, see [`Window`] for details. + Window(&'a mut dyn Window), +} + +impl SurfaceDowncastMut<'_> { + /// Tries to cast this reference into a [`Window`]. + pub fn as_window(&mut self) -> Option<&'_ mut dyn Window> { + match self { + Self::Window(window) => Some(*window), + // _ => None, + } + } +} + +/// Helper macro for implementing [`Surface::try_downcast`] and [`Surface::try_downcast_mut`]. +/// ## Syntax +/// Use the names of variants of [`SurfaceDowncastRef`] or [`SurfaceDowncastMut`] to return that +/// type: +/// ```ignore +/// impl_surface_downcast!(Window); +/// `````` +/// You may also use the special identifier `None` to cause the downcast to fail. +/// ```ignore +/// impl_surface_downcast!(None); +/// ``` +#[macro_export] +macro_rules! impl_surface_downcast { + (None) => { + fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> { + None + } + + fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> { + None + } + }; + ($variant:ident) => { + fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> { + Some($crate::window::SurfaceDowncastRef::$variant(self)) + } + + fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> { + Some($crate::window::SurfaceDowncastMut::$variant(self)) + } + }; +} diff --git a/winit-orbital/src/window.rs b/winit-orbital/src/window.rs index 7f3918f7a9..fabdc38296 100644 --- a/winit-orbital/src/window.rs +++ b/winit-orbital/src/window.rs @@ -5,8 +5,9 @@ use std::sync::{Arc, Mutex}; use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size}; use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; -use winit_core::window::{self, Window as CoreWindow, WindowId}; +use winit_core::window::{self, Surface as CoreSurface, Window as CoreWindow, WindowId}; use crate::event_loop::{ActiveEventLoop, EventLoopProxy}; use crate::{RedoxSocket, WindowProperties}; @@ -156,15 +157,13 @@ impl Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> WindowId { WindowId::from_raw(self.window_socket.fd) } - fn ime_capabilities(&self) -> Option { - None - } - #[inline] fn primary_monitor(&self) -> Option { None @@ -199,11 +198,79 @@ impl CoreWindow for Window { #[inline] fn pre_present_notify(&self) {} + #[inline] + fn surface_size(&self) -> PhysicalSize { + let mut buf: [u8; 4096] = [0; 4096]; + let path = self.window_socket.fpath(&mut buf).expect("failed to read properties"); + let properties = WindowProperties::new(path); + (properties.w, properties.h).into() + } + + #[inline] + fn request_surface_size(&self, size: Size) -> Option> { + let (w, h): (u32, u32) = size.to_physical::(self.scale_factor()).into(); + self.window_socket.write(format!("S,{w},{h}").as_bytes()).expect("failed to set size"); + None + } + + #[inline] + fn set_transparent(&self, transparent: bool) { + let _ = self.set_flag(ORBITAL_FLAG_TRANSPARENT, transparent); + } + + #[inline] + fn set_cursor(&self, _: Cursor) {} + + #[inline] + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) + } + + #[inline] + fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), RequestError> { + let (grab, relative) = match mode { + window::CursorGrabMode::None => (false, false), + window::CursorGrabMode::Confined => (true, false), + window::CursorGrabMode::Locked => (true, true), + }; + self.window_socket + .write(format!("M,G,{}", if grab { 1 } else { 0 }).as_bytes()) + .map_err(|err| os_error!(format!("{err}")))?; + self.window_socket + .write(format!("M,R,{}", if relative { 1 } else { 0 }).as_bytes()) + .map_err(|err| os_error!(format!("{err}")))?; + Ok(()) + } + + #[inline] + fn set_cursor_visible(&self, visible: bool) { + let _ = self.window_socket.write(format!("M,C,{}", if visible { 1 } else { 0 }).as_bytes()); + } + + #[inline] + fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } +} + +impl CoreWindow for Window { #[inline] fn reset_dead_keys(&self) { // TODO? } + fn ime_capabilities(&self) -> Option { + None + } + #[inline] fn surface_position(&self) -> PhysicalPosition { // TODO: adjust for window decorations @@ -225,21 +292,6 @@ impl CoreWindow for Window { self.window_socket.write(format!("P,{x},{y}").as_bytes()).expect("failed to set position"); } - #[inline] - fn surface_size(&self) -> PhysicalSize { - let mut buf: [u8; 4096] = [0; 4096]; - let path = self.window_socket.fpath(&mut buf).expect("failed to read properties"); - let properties = WindowProperties::new(path); - (properties.w, properties.h).into() - } - - #[inline] - fn request_surface_size(&self, size: Size) -> Option> { - let (w, h): (u32, u32) = size.to_physical::(self.scale_factor()).into(); - self.window_socket.write(format!("S,{w},{h}").as_bytes()).expect("failed to set size"); - None - } - #[inline] fn outer_size(&self) -> PhysicalSize { // TODO: adjust for window decorations @@ -269,11 +321,6 @@ impl CoreWindow for Window { self.window_socket.write(format!("T,{title}").as_bytes()).expect("failed to set title"); } - #[inline] - fn set_transparent(&self, transparent: bool) { - let _ = self.set_flag(ORBITAL_FLAG_TRANSPARENT, transparent); - } - #[inline] fn set_blur(&self, _blur: bool) {} @@ -368,35 +415,6 @@ impl CoreWindow for Window { #[inline] fn request_user_attention(&self, _request_type: Option) {} - #[inline] - fn set_cursor(&self, _: Cursor) {} - - #[inline] - fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_position is not supported").into()) - } - - #[inline] - fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), RequestError> { - let (grab, relative) = match mode { - window::CursorGrabMode::None => (false, false), - window::CursorGrabMode::Confined => (true, false), - window::CursorGrabMode::Locked => (true, true), - }; - self.window_socket - .write(format!("M,G,{}", if grab { 1 } else { 0 }).as_bytes()) - .map_err(|err| os_error!(format!("{err}")))?; - self.window_socket - .write(format!("M,R,{}", if relative { 1 } else { 0 }).as_bytes()) - .map_err(|err| os_error!(format!("{err}")))?; - Ok(()) - } - - #[inline] - fn set_cursor_visible(&self, visible: bool) { - let _ = self.window_socket.write(format!("M,C,{}", if visible { 1 } else { 0 }).as_bytes()); - } - #[inline] fn drag_window(&self) -> Result<(), RequestError> { self.window_socket.write(b"D").map_err(|err| os_error!(format!("{err}")))?; @@ -424,11 +442,6 @@ impl CoreWindow for Window { #[inline] fn show_window_menu(&self, _position: Position) {} - #[inline] - fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) - } - #[inline] fn set_enabled_buttons(&self, _buttons: window::WindowButtons) {} @@ -451,14 +464,6 @@ impl CoreWindow for Window { fn set_theme(&self, _theme: Option) {} fn set_content_protected(&self, _protected: bool) {} - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } } impl rwh_06::HasWindowHandle for Window { diff --git a/winit-uikit/src/window.rs b/winit-uikit/src/window.rs index 52acb038f1..9c48469089 100644 --- a/winit-uikit/src/window.rs +++ b/winit-uikit/src/window.rs @@ -21,11 +21,12 @@ use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; use winit_core::event::WindowEvent; use winit_core::icon::Icon; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; use winit_core::window::{ - CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, Theme, - UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, - WindowLevel, + CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, + Surface as CoreSurface, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, + WindowButtons, WindowId, WindowLevel, }; use super::app_state::EventWrapper; @@ -123,7 +124,7 @@ impl Inner { } pub fn set_transparent(&self, _transparent: bool) { - debug!("`Window::set_transparent` is ignored on iOS") + debug!("`Surface::set_transparent` is ignored on iOS") } pub fn set_blur(&self, _blur: bool) { @@ -258,7 +259,7 @@ impl Inner { } pub fn set_cursor(&self, _cursor: Cursor) { - debug!("`Window::set_cursor` ignored on iOS") + debug!("`Surface::set_cursor` ignored on iOS") } pub fn set_cursor_position(&self, _position: Position) -> Result<(), NotSupportedError> { @@ -270,7 +271,7 @@ impl Inner { } pub fn set_cursor_visible(&self, _visible: bool) { - debug!("`Window::set_cursor_visible` is ignored on iOS") + debug!("`Surface::set_cursor_visible` is ignored on iOS") } pub fn drag_window(&self) -> Result<(), NotSupportedError> { @@ -592,7 +593,9 @@ impl rwh_06::HasWindowHandle for Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> winit_core::window::WindowId { self.maybe_wait_on_main(|delegate| delegate.id()) } @@ -609,6 +612,74 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.pre_present_notify()); } + fn surface_size(&self) -> PhysicalSize { + self.maybe_wait_on_main(|delegate| delegate.surface_size()) + } + + fn request_surface_size(&self, size: Size) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.request_surface_size(size)) + } + + fn set_transparent(&self, transparent: bool) { + self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); + } + + fn set_cursor(&self, cursor: Cursor) { + self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); + } + + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position))?) + } + + fn set_cursor_grab( + &self, + mode: winit_core::window::CursorGrabMode, + ) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode))?) + } + + fn set_cursor_visible(&self, visible: bool) { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) + } + + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest))?) + } + + fn current_monitor(&self) -> Option { + self.maybe_wait_on_main(|delegate| { + delegate.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + }) + } + + fn available_monitors(&self) -> Box> { + self.maybe_wait_on_main(|delegate| { + Box::new( + delegate + .available_monitors() + .into_iter() + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), + ) + }) + } + + fn primary_monitor(&self) -> Option { + self.maybe_wait_on_main(|delegate| { + delegate.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + }) + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl CoreWindow for Window { fn reset_dead_keys(&self) { self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys()); } @@ -625,14 +696,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_outer_position(position)); } - fn surface_size(&self) -> PhysicalSize { - self.maybe_wait_on_main(|delegate| delegate.surface_size()) - } - - fn request_surface_size(&self, size: Size) -> Option> { - self.maybe_wait_on_main(|delegate| delegate.request_surface_size(size)) - } - fn outer_size(&self) -> PhysicalSize { self.maybe_wait_on_main(|delegate| delegate.outer_size()) } @@ -661,10 +724,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_title(title)); } - fn set_transparent(&self, transparent: bool) { - self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); - } - fn set_blur(&self, blur: bool) { self.maybe_wait_on_main(|delegate| delegate.set_blur(blur)); } @@ -769,25 +828,6 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.title()) } - fn set_cursor(&self, cursor: Cursor) { - self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); - } - - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { - Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position))?) - } - - fn set_cursor_grab( - &self, - mode: winit_core::window::CursorGrabMode, - ) -> Result<(), RequestError> { - Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode))?) - } - - fn set_cursor_visible(&self, visible: bool) { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) - } - fn drag_window(&self) -> Result<(), RequestError> { Ok(self.maybe_wait_on_main(|delegate| delegate.drag_window())?) } @@ -802,41 +842,6 @@ impl CoreWindow for Window { fn show_window_menu(&self, position: Position) { self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position)) } - - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { - Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest))?) - } - - fn current_monitor(&self) -> Option { - self.maybe_wait_on_main(|delegate| { - delegate.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - }) - } - - fn available_monitors(&self) -> Box> { - self.maybe_wait_on_main(|delegate| { - Box::new( - delegate - .available_monitors() - .into_iter() - .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), - ) - }) - } - - fn primary_monitor(&self) -> Option { - self.maybe_wait_on_main(|delegate| { - delegate.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - }) - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } // WindowExtIOS diff --git a/winit-wayland/src/lib.rs b/winit-wayland/src/lib.rs index 1a35a3de22..0c238a9050 100644 --- a/winit-wayland/src/lib.rs +++ b/winit-wayland/src/lib.rs @@ -61,7 +61,7 @@ pub trait EventLoopExtWayland { fn is_wayland(&self) -> bool; } -/// Additional methods on [`EventLoopBuilder`] that are specific to Wayland. +/// Additional methods on `winit::EventLoopBuilder` that are specific to Wayland. pub trait EventLoopBuilderExtWayland { /// Force using Wayland. fn with_wayland(&mut self) -> &mut Self; diff --git a/winit-wayland/src/seat/pointer/relative_pointer.rs b/winit-wayland/src/seat/pointer/relative_pointer.rs index 8465b720d6..1b3135ea85 100644 --- a/winit-wayland/src/seat/pointer/relative_pointer.rs +++ b/winit-wayland/src/seat/pointer/relative_pointer.rs @@ -12,8 +12,8 @@ use sctk::reexports::protocols::wp::relative_pointer::zv1::{ use sctk::globals::GlobalData; -use winit_core::event::DeviceEvent; use crate::state::WinitState; +use winit_core::event::DeviceEvent; /// Wrapper around the relative pointer. #[derive(Debug)] diff --git a/winit-wayland/src/window/mod.rs b/winit-wayland/src/window/mod.rs index fb5f22fea8..f85d782128 100644 --- a/winit-wayland/src/window/mod.rs +++ b/winit-wayland/src/window/mod.rs @@ -18,11 +18,12 @@ use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; use winit_core::event::{Ime, WindowEvent}; use winit_core::event_loop::AsyncRequestSerial; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; use winit_core::window::{ - CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, Theme, - UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, - WindowLevel, + CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, + Surface as CoreSurface, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, + WindowButtons, WindowId, WindowLevel, }; use super::event_loop::sink::EventSink; @@ -282,7 +283,9 @@ impl rwh_06::HasDisplayHandle for Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> WindowId { self.window_id } @@ -302,13 +305,114 @@ impl CoreWindow for Window { } } + fn pre_present_notify(&self) { + self.window_state.lock().unwrap().request_frame_callback(); + } + + fn surface_size(&self) -> PhysicalSize { + let window_state = self.window_state.lock().unwrap(); + let scale_factor = window_state.scale_factor(); + super::logical_to_physical_rounded(window_state.surface_size(), scale_factor) + } + + fn request_surface_size(&self, size: Size) -> Option> { + let mut window_state = self.window_state.lock().unwrap(); + let new_size = window_state.request_surface_size(size); + self.request_redraw(); + Some(new_size) + } + #[inline] - fn title(&self) -> String { - self.window_state.lock().unwrap().title().to_owned() + fn set_transparent(&self, transparent: bool) { + self.window_state.lock().unwrap().set_transparent(transparent); } - fn pre_present_notify(&self) { - self.window_state.lock().unwrap().request_frame_callback(); + #[inline] + fn scale_factor(&self) -> f64 { + self.window_state.lock().unwrap().scale_factor() + } + + fn set_cursor(&self, cursor: Cursor) { + let window_state = &mut self.window_state.lock().unwrap(); + + match cursor { + Cursor::Icon(icon) => window_state.set_cursor(icon), + Cursor::Custom(cursor) => window_state.set_custom_cursor(cursor), + } + } + + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + let scale_factor = self.scale_factor(); + let position = position.to_logical(scale_factor); + self.window_state + .lock() + .unwrap() + .set_cursor_position(position) + // Request redraw on success, since the state is double buffered. + .map(|_| self.request_redraw()) + } + + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { + self.window_state.lock().unwrap().set_cursor_grab(mode) + } + + fn set_cursor_visible(&self, visible: bool) { + self.window_state.lock().unwrap().set_cursor_visible(visible); + } + + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + let surface = self.window.wl_surface(); + + if hittest { + surface.set_input_region(None); + Ok(()) + } else { + let region = Region::new(&*self.compositor).map_err(|err| os_error!(err))?; + region.add(0, 0, 0, 0); + surface.set_input_region(Some(region.wl_region())); + Ok(()) + } + } + + fn current_monitor(&self) -> Option { + let data = self.window.wl_surface().data::()?; + data.outputs() + .next() + .map(MonitorHandle::new) + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + } + + fn available_monitors(&self) -> Box> { + Box::new( + self.monitors + .lock() + .unwrap() + .clone() + .into_iter() + .map(|inner| CoreMonitorHandle(Arc::new(inner))), + ) + } + + fn primary_monitor(&self) -> Option { + // NOTE: There's no such concept on Wayland. + None + } + + /// Get the raw-window-handle v0.6 display handle. + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + /// Get the raw-window-handle v0.6 window handle. + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl CoreWindow for Window { + #[inline] + fn title(&self) -> String { + self.window_state.lock().unwrap().title().to_owned() } fn reset_dead_keys(&self) { @@ -328,19 +432,6 @@ impl CoreWindow for Window { // Not possible. } - fn surface_size(&self) -> PhysicalSize { - let window_state = self.window_state.lock().unwrap(); - let scale_factor = window_state.scale_factor(); - super::logical_to_physical_rounded(window_state.surface_size(), scale_factor) - } - - fn request_surface_size(&self, size: Size) -> Option> { - let mut window_state = self.window_state.lock().unwrap(); - let new_size = window_state.request_surface_size(size); - self.request_redraw(); - Some(new_size) - } - fn outer_size(&self) -> PhysicalSize { let window_state = self.window_state.lock().unwrap(); let scale_factor = window_state.scale_factor(); @@ -382,11 +473,6 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().set_title(new_title); } - #[inline] - fn set_transparent(&self, transparent: bool) { - self.window_state.lock().unwrap().set_transparent(transparent); - } - fn set_visible(&self, _visible: bool) { // Not possible on Wayland. } @@ -482,11 +568,6 @@ impl CoreWindow for Window { } } - #[inline] - fn scale_factor(&self) -> f64 { - self.window_state.lock().unwrap().scale_factor() - } - #[inline] fn set_blur(&self, blur: bool) { self.window_state.lock().unwrap().set_blur(blur); @@ -568,34 +649,6 @@ impl CoreWindow for Window { fn set_content_protected(&self, _protected: bool) {} - fn set_cursor(&self, cursor: Cursor) { - let window_state = &mut self.window_state.lock().unwrap(); - - match cursor { - Cursor::Icon(icon) => window_state.set_cursor(icon), - Cursor::Custom(cursor) => window_state.set_custom_cursor(cursor), - } - } - - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { - let scale_factor = self.scale_factor(); - let position = position.to_logical(scale_factor); - self.window_state - .lock() - .unwrap() - .set_cursor_position(position) - // Request redraw on success, since the state is double buffered. - .map(|_| self.request_redraw()) - } - - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { - self.window_state.lock().unwrap().set_cursor_grab(mode) - } - - fn set_cursor_visible(&self, visible: bool) { - self.window_state.lock().unwrap().set_cursor_visible(visible); - } - fn drag_window(&self) -> Result<(), RequestError> { self.window_state.lock().unwrap().drag_window() } @@ -609,54 +662,6 @@ impl CoreWindow for Window { let position = position.to_logical(scale_factor); self.window_state.lock().unwrap().show_window_menu(position); } - - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { - let surface = self.window.wl_surface(); - - if hittest { - surface.set_input_region(None); - Ok(()) - } else { - let region = Region::new(&*self.compositor).map_err(|err| os_error!(err))?; - region.add(0, 0, 0, 0); - surface.set_input_region(Some(region.wl_region())); - Ok(()) - } - } - - fn current_monitor(&self) -> Option { - let data = self.window.wl_surface().data::()?; - data.outputs() - .next() - .map(MonitorHandle::new) - .map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - } - - fn available_monitors(&self) -> Box> { - Box::new( - self.monitors - .lock() - .unwrap() - .clone() - .into_iter() - .map(|inner| CoreMonitorHandle(Arc::new(inner))), - ) - } - - fn primary_monitor(&self) -> Option { - // NOTE: There's no such concept on Wayland. - None - } - - /// Get the raw-window-handle v0.6 display handle. - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - /// Get the raw-window-handle v0.6 window handle. - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } /// The request from the window to the event loop. diff --git a/winit-web/src/lib.rs b/winit-web/src/lib.rs index 3ea383c7fc..d0fd616cf4 100644 --- a/winit-web/src/lib.rs +++ b/winit-web/src/lib.rs @@ -34,7 +34,7 @@ //! - [`Window::set_outer_position()`] //! //! [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized -//! [`Window::(set_)surface_size()`]: crate::window::Window::surface_size +//! [`Window::(set_)surface_size()`]: crate::window::Surface::surface_size //! [`WindowEvent::Occluded`]: crate::event::WindowEvent::Occluded //! [`WindowEvent::PointerMoved`]: crate::event::WindowEvent::PointerMoved //! [`WindowEvent::PointerEntered`]: crate::event::WindowEvent::PointerEntered diff --git a/winit-web/src/window.rs b/winit-web/src/window.rs index a3579a33bf..3fcbb92504 100644 --- a/winit-web/src/window.rs +++ b/winit-web/src/window.rs @@ -10,10 +10,12 @@ use web_sys::HtmlCanvasElement; use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; use winit_core::icon::Icon; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoremMonitorHandle}; use winit_core::window::{ - CursorGrabMode, ImeRequestError, ResizeDirection, Theme, UserAttentionType, - Window as RootWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel, + CursorGrabMode, ImeRequestError, ResizeDirection, Surface as RootSurface, Theme, + UserAttentionType, Window as RootWindow, WindowAttributes, WindowButtons, WindowId, + WindowLevel, }; use crate::event_loop::ActiveEventLoop; @@ -102,7 +104,9 @@ impl Window { } } -impl RootWindow for Window { +impl RootSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> WindowId { self.inner.queue(|inner| inner.id) } @@ -117,6 +121,86 @@ impl RootWindow for Window { fn pre_present_notify(&self) {} + fn surface_size(&self) -> PhysicalSize { + self.inner.queue(|inner| inner.canvas.surface_size()) + } + + fn request_surface_size(&self, size: Size) -> Option> { + self.inner.queue(|inner| { + let size = size.to_logical(self.scale_factor()); + backend::set_canvas_size( + inner.canvas.document(), + inner.canvas.raw(), + inner.canvas.style(), + size, + ); + None + }) + } + + fn set_transparent(&self, _: bool) {} + + fn set_cursor(&self, cursor: Cursor) { + self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor(cursor)) + } + + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) + } + + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { + Ok(self.inner.queue(|inner| { + match mode { + CursorGrabMode::None => inner.canvas.document().exit_pointer_lock(), + CursorGrabMode::Locked => lock::request_pointer_lock( + inner.canvas.navigator(), + inner.canvas.document(), + inner.canvas.raw(), + ), + CursorGrabMode::Confined => { + return Err(NotSupportedError::new("confined cursor mode is not supported")) + }, + } + + Ok(()) + })?) + } + + fn set_cursor_visible(&self, visible: bool) { + self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor_visible(visible)) + } + + fn set_cursor_hittest(&self, _: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) + } + + fn current_monitor(&self) -> Option { + Some(self.inner.queue(|inner| inner.monitor.current_monitor()).into()) + } + + fn available_monitors(&self) -> Box> { + Box::new( + self.inner + .queue(|inner| inner.monitor.available_monitors()) + .into_iter() + .map(CoremMonitorHandle::from), + ) + } + + fn primary_monitor(&self) -> Option { + self.inner.queue(|inner| inner.monitor.primary_monitor()).map(CoremMonitorHandle::from) + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl RootWindow for Window { fn reset_dead_keys(&self) { // Not supported } @@ -142,23 +226,6 @@ impl RootWindow for Window { }) } - fn surface_size(&self) -> PhysicalSize { - self.inner.queue(|inner| inner.canvas.surface_size()) - } - - fn request_surface_size(&self, size: Size) -> Option> { - self.inner.queue(|inner| { - let size = size.to_logical(self.scale_factor()); - backend::set_canvas_size( - inner.canvas.document(), - inner.canvas.raw(), - inner.canvas.style(), - size, - ); - None - }) - } - fn outer_size(&self) -> PhysicalSize { // Note: the canvas element has no window decorations, so this is equal to `surface_size`. self.surface_size() @@ -228,8 +295,6 @@ impl RootWindow for Window { self.inner.queue(|inner| inner.canvas.set_attribute("alt", title)) } - fn set_transparent(&self, _: bool) {} - fn set_blur(&self, _: bool) {} fn set_visible(&self, _: bool) { @@ -350,36 +415,6 @@ impl RootWindow for Window { String::new() } - fn set_cursor(&self, cursor: Cursor) { - self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor(cursor)) - } - - fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_position is not supported").into()) - } - - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { - Ok(self.inner.queue(|inner| { - match mode { - CursorGrabMode::None => inner.canvas.document().exit_pointer_lock(), - CursorGrabMode::Locked => lock::request_pointer_lock( - inner.canvas.navigator(), - inner.canvas.document(), - inner.canvas.raw(), - ), - CursorGrabMode::Confined => { - return Err(NotSupportedError::new("confined cursor mode is not supported")) - }, - } - - Ok(()) - })?) - } - - fn set_cursor_visible(&self, visible: bool) { - self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor_visible(visible)) - } - fn drag_window(&self) -> Result<(), RequestError> { Err(NotSupportedError::new("drag_window is not supported").into()) } @@ -389,35 +424,6 @@ impl RootWindow for Window { } fn show_window_menu(&self, _: Position) {} - - fn set_cursor_hittest(&self, _: bool) -> Result<(), RequestError> { - Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) - } - - fn current_monitor(&self) -> Option { - Some(self.inner.queue(|inner| inner.monitor.current_monitor()).into()) - } - - fn available_monitors(&self) -> Box> { - Box::new( - self.inner - .queue(|inner| inner.monitor.available_monitors()) - .into_iter() - .map(CoremMonitorHandle::from), - ) - } - - fn primary_monitor(&self) -> Option { - self.inner.queue(|inner| inner.monitor.primary_monitor()).map(CoremMonitorHandle::from) - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } impl rwh_06::HasWindowHandle for Window { diff --git a/winit-win32/src/window.rs b/winit-win32/src/window.rs index 4b1d455139..eb11b1ba17 100644 --- a/winit-win32/src/window.rs +++ b/winit-win32/src/window.rs @@ -49,11 +49,12 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{ use winit_core::cursor::Cursor; use winit_core::error::RequestError; use winit_core::icon::{Icon, RgbaIcon}; +use winit_core::impl_surface_downcast; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider}; use winit_core::window::{ - CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, Theme, - UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, - WindowLevel, + CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, + Surface as CoreSurface, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, + WindowButtons, WindowId, WindowLevel, }; use crate::dark_mode::try_theme; @@ -413,23 +414,193 @@ impl rwh_06::HasWindowHandle for Window { } } -impl CoreWindow for Window { - fn set_title(&self, text: &str) { - let wide_text = util::encode_wide(text); +impl CoreSurface for Window { + impl_surface_downcast!(Window); + + fn set_transparent(&self, transparent: bool) { + let window = self.window; + let window_state = Arc::clone(&self.window_state); + self.thread_executor.execute_in_thread(move || { + let _ = &window; + WindowState::set_window_flags(window_state.lock().unwrap(), window.hwnd(), |f| { + f.set(WindowFlags::TRANSPARENT, transparent) + }); + }); + } + + fn request_redraw(&self) { + // NOTE: mark that we requested a redraw to handle requests during `WM_PAINT` handling. + self.window_state.lock().unwrap().redraw_requested = true; unsafe { - SetWindowTextW(self.hwnd(), wide_text.as_ptr()); + RedrawWindow(self.hwnd(), ptr::null(), ptr::null_mut(), RDW_INTERNALPAINT); } } - fn set_transparent(&self, transparent: bool) { + fn pre_present_notify(&self) {} + + fn surface_size(&self) -> PhysicalSize { + let mut rect: RECT = unsafe { mem::zeroed() }; + if unsafe { GetClientRect(self.hwnd(), &mut rect) } == false.into() { + panic!( + "Unexpected GetClientRect failure: please report this error to \ + rust-windowing/winit" + ) + } + PhysicalSize::new((rect.right - rect.left) as u32, (rect.bottom - rect.top) as u32) + } + + fn request_surface_size(&self, size: Size) -> Option> { + let scale_factor = self.scale_factor(); + let physical_size = size.to_physical::(scale_factor); + + let window_flags = self.window_state_lock().window_flags; + window_flags.set_size(self.hwnd(), physical_size); + + if physical_size != self.surface_size() { + let window_state = Arc::clone(&self.window_state); + let window = self.window; + self.thread_executor.execute_in_thread(move || { + let _ = &window; + WindowState::set_window_flags(window_state.lock().unwrap(), window.hwnd(), |f| { + f.set(WindowFlags::MAXIMIZED, false) + }); + }); + } + + None + } + + fn set_cursor(&self, cursor: Cursor) { + match cursor { + Cursor::Icon(icon) => { + self.window_state_lock().mouse.selected_cursor = SelectedCursor::Named(icon); + self.thread_executor.execute_in_thread(move || unsafe { + let cursor = LoadCursorW(ptr::null_mut(), util::to_windows_cursor(icon)); + SetCursor(cursor); + }); + }, + Cursor::Custom(cursor) => { + let cursor = match cursor.cast_ref::() { + Some(cursor) => cursor, + None => return, + }; + self.window_state_lock().mouse.selected_cursor = + SelectedCursor::Custom(cursor.0.clone()); + let handle = cursor.0.clone(); + self.thread_executor.execute_in_thread(move || unsafe { + SetCursor(handle.as_raw_handle()); + }); + }, + } + } + + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { let window = self.window; let window_state = Arc::clone(&self.window_state); + let (tx, rx) = channel(); + self.thread_executor.execute_in_thread(move || { let _ = &window; + let result = window_state + .lock() + .unwrap() + .mouse + .set_cursor_flags(window.hwnd(), |f| { + f.set(CursorFlags::GRABBED, mode != CursorGrabMode::None); + f.set(CursorFlags::LOCKED, mode == CursorGrabMode::Locked); + }) + .map_err(|err| os_error!(err).into()); + let _ = tx.send(result); + }); + + rx.recv().unwrap() + } + + fn set_cursor_visible(&self, visible: bool) { + let window = self.window; + let window_state = Arc::clone(&self.window_state); + let (tx, rx) = channel(); + + self.thread_executor.execute_in_thread(move || { + let _ = &window; + let result = window_state + .lock() + .unwrap() + .mouse + .set_cursor_flags(window.hwnd(), |f| f.set(CursorFlags::HIDDEN, !visible)) + .map_err(|e| e.to_string()); + let _ = tx.send(result); + }); + rx.recv().unwrap().ok(); + } + + fn scale_factor(&self) -> f64 { + self.window_state_lock().scale_factor + } + + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + let scale_factor = self.scale_factor(); + let (x, y) = position.to_physical::(scale_factor).into(); + + let mut point = POINT { x, y }; + unsafe { + if ClientToScreen(self.hwnd(), &mut point) == false.into() { + return Err(os_error!(io::Error::last_os_error()).into()); + } + if SetCursorPos(point.x, point.y) == false.into() { + return Err(os_error!(io::Error::last_os_error()).into()); + } + } + Ok(()) + } + + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + let window = self.window; + let window_state = Arc::clone(&self.window_state); + self.thread_executor.execute_in_thread(move || { WindowState::set_window_flags(window_state.lock().unwrap(), window.hwnd(), |f| { - f.set(WindowFlags::TRANSPARENT, transparent) + f.set(WindowFlags::IGNORE_CURSOR_EVENT, !hittest) }); }); + + Ok(()) + } + + fn id(&self) -> WindowId { + WindowId::from_raw(self.hwnd() as usize) + } + + fn current_monitor(&self) -> Option { + Some(CoreMonitorHandle(Arc::new(monitor::current_monitor(self.hwnd())))) + } + + fn available_monitors(&self) -> Box> { + Box::new( + monitor::available_monitors() + .into_iter() + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), + ) + } + + fn primary_monitor(&self) -> Option { + Some(CoreMonitorHandle(Arc::new(monitor::primary_monitor()))) + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } +} + +impl CoreWindow for Window { + fn set_title(&self, text: &str) { + let wide_text = util::encode_wide(text); + unsafe { + SetWindowTextW(self.hwnd(), wide_text.as_ptr()); + } } fn set_blur(&self, _blur: bool) {} @@ -449,16 +620,6 @@ impl CoreWindow for Window { Some(unsafe { IsWindowVisible(self.window.hwnd()) == 1 }) } - fn request_redraw(&self) { - // NOTE: mark that we requested a redraw to handle requests during `WM_PAINT` handling. - self.window_state.lock().unwrap().redraw_requested = true; - unsafe { - RedrawWindow(self.hwnd(), ptr::null(), ptr::null_mut(), RDW_INTERNALPAINT); - } - } - - fn pre_present_notify(&self) {} - fn outer_position(&self) -> Result, RequestError> { util::WindowArea::Outer .get_rect(self.hwnd()) @@ -506,17 +667,6 @@ impl CoreWindow for Window { } } - fn surface_size(&self) -> PhysicalSize { - let mut rect: RECT = unsafe { mem::zeroed() }; - if unsafe { GetClientRect(self.hwnd(), &mut rect) } == false.into() { - panic!( - "Unexpected GetClientRect failure: please report this error to \ - rust-windowing/winit" - ) - } - PhysicalSize::new((rect.right - rect.left) as u32, (rect.bottom - rect.top) as u32) - } - fn outer_size(&self) -> PhysicalSize { util::WindowArea::Outer .get_rect(self.hwnd()) @@ -526,27 +676,6 @@ impl CoreWindow for Window { .unwrap() } - fn request_surface_size(&self, size: Size) -> Option> { - let scale_factor = self.scale_factor(); - let physical_size = size.to_physical::(scale_factor); - - let window_flags = self.window_state_lock().window_flags; - window_flags.set_size(self.hwnd(), physical_size); - - if physical_size != self.surface_size() { - let window_state = Arc::clone(&self.window_state); - let window = self.window; - self.thread_executor.execute_in_thread(move || { - let _ = &window; - WindowState::set_window_flags(window_state.lock().unwrap(), window.hwnd(), |f| { - f.set(WindowFlags::MAXIMIZED, false) - }); - }); - } - - None - } - fn safe_area(&self) -> PhysicalInsets { PhysicalInsets::new(0, 0, 0, 0) } @@ -621,90 +750,6 @@ impl CoreWindow for Window { buttons } - fn set_cursor(&self, cursor: Cursor) { - match cursor { - Cursor::Icon(icon) => { - self.window_state_lock().mouse.selected_cursor = SelectedCursor::Named(icon); - self.thread_executor.execute_in_thread(move || unsafe { - let cursor = LoadCursorW(ptr::null_mut(), util::to_windows_cursor(icon)); - SetCursor(cursor); - }); - }, - Cursor::Custom(cursor) => { - let cursor = match cursor.cast_ref::() { - Some(cursor) => cursor, - None => return, - }; - self.window_state_lock().mouse.selected_cursor = - SelectedCursor::Custom(cursor.0.clone()); - let handle = cursor.0.clone(); - self.thread_executor.execute_in_thread(move || unsafe { - SetCursor(handle.as_raw_handle()); - }); - }, - } - } - - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { - let window = self.window; - let window_state = Arc::clone(&self.window_state); - let (tx, rx) = channel(); - - self.thread_executor.execute_in_thread(move || { - let _ = &window; - let result = window_state - .lock() - .unwrap() - .mouse - .set_cursor_flags(window.hwnd(), |f| { - f.set(CursorFlags::GRABBED, mode != CursorGrabMode::None); - f.set(CursorFlags::LOCKED, mode == CursorGrabMode::Locked); - }) - .map_err(|err| os_error!(err).into()); - let _ = tx.send(result); - }); - - rx.recv().unwrap() - } - - fn set_cursor_visible(&self, visible: bool) { - let window = self.window; - let window_state = Arc::clone(&self.window_state); - let (tx, rx) = channel(); - - self.thread_executor.execute_in_thread(move || { - let _ = &window; - let result = window_state - .lock() - .unwrap() - .mouse - .set_cursor_flags(window.hwnd(), |f| f.set(CursorFlags::HIDDEN, !visible)) - .map_err(|e| e.to_string()); - let _ = tx.send(result); - }); - rx.recv().unwrap().ok(); - } - - fn scale_factor(&self) -> f64 { - self.window_state_lock().scale_factor - } - - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { - let scale_factor = self.scale_factor(); - let (x, y) = position.to_physical::(scale_factor).into(); - - let mut point = POINT { x, y }; - unsafe { - if ClientToScreen(self.hwnd(), &mut point) == false.into() { - return Err(os_error!(io::Error::last_os_error()).into()); - } - if SetCursorPos(point.x, point.y) == false.into() { - return Err(os_error!(io::Error::last_os_error()).into()); - } - } - Ok(()) - } - fn drag_window(&self) -> Result<(), RequestError> { unsafe { self.handle_os_dragging(HTCAPTION as WPARAM); @@ -736,22 +781,6 @@ impl CoreWindow for Window { } } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { - let window = self.window; - let window_state = Arc::clone(&self.window_state); - self.thread_executor.execute_in_thread(move || { - WindowState::set_window_flags(window_state.lock().unwrap(), window.hwnd(), |f| { - f.set(WindowFlags::IGNORE_CURSOR_EVENT, !hittest) - }); - }); - - Ok(()) - } - - fn id(&self) -> WindowId { - WindowId::from_raw(self.hwnd() as usize) - } - fn set_minimized(&self, minimized: bool) { let window = self.window; let window_state = Arc::clone(&self.window_state); @@ -985,22 +1014,6 @@ impl CoreWindow for Window { }); } - fn current_monitor(&self) -> Option { - Some(CoreMonitorHandle(Arc::new(monitor::current_monitor(self.hwnd())))) - } - - fn available_monitors(&self) -> Box> { - Box::new( - monitor::available_monitors() - .into_iter() - .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), - ) - } - - fn primary_monitor(&self) -> Option { - Some(CoreMonitorHandle(Arc::new(monitor::primary_monitor()))) - } - fn set_window_icon(&self, window_icon: Option) { if let Some(window_icon) = window_icon { self.set_icon(window_icon, IconType::Small); @@ -1155,14 +1168,6 @@ impl CoreWindow for Window { ); } } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } } pub(super) struct InitData<'a> { diff --git a/winit-x11/src/lib.rs b/winit-x11/src/lib.rs index 545e7a225c..8f3da9279e 100644 --- a/winit-x11/src/lib.rs +++ b/winit-x11/src/lib.rs @@ -125,7 +125,7 @@ pub trait EventLoopExtX11 { fn is_x11(&self) -> bool; } -/// Additional methods on [`EventLoopBuilder`] that are specific to X11. +/// Additional methods on `winit::EventLoopBuilder` that are specific to X11. pub trait EventLoopBuilderExtX11 { /// Force using X11. fn with_x11(&mut self) -> &mut Self; diff --git a/winit-x11/src/window.rs b/winit-x11/src/window.rs index 7dacfcd665..68a8e4d7a3 100644 --- a/winit-x11/src/window.rs +++ b/winit-x11/src/window.rs @@ -16,13 +16,14 @@ use winit_core::error::{NotSupportedError, RequestError}; use winit_core::event::{SurfaceSizeWriter, WindowEvent}; use winit_core::event_loop::AsyncRequestSerial; use winit_core::icon::RgbaIcon; +use winit_core::impl_surface_downcast; use winit_core::monitor::{ Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider, VideoMode, }; use winit_core::window::{ CursorGrabMode, ImeCapabilities, ImeRequest as CoreImeRequest, ImeRequestError, - ResizeDirection, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, - WindowButtons, WindowId, WindowLevel, + ResizeDirection, Surface as CoreSurface, Theme, UserAttentionType, Window as CoreWindow, + WindowAttributes, WindowButtons, WindowId, WindowLevel, }; use x11rb::connection::{Connection, RequestConnection}; use x11rb::properties::{WmHints, WmSizeHints, WmSizeHintsSpecification}; @@ -66,7 +67,9 @@ impl Window { } } -impl CoreWindow for Window { +impl CoreSurface for Window { + impl_surface_downcast!(Window); + fn id(&self) -> WindowId { self.0.id() } @@ -83,6 +86,65 @@ impl CoreWindow for Window { self.0.pre_present_notify() } + fn surface_size(&self) -> PhysicalSize { + self.0.surface_size() + } + + fn request_surface_size(&self, size: Size) -> Option> { + self.0.request_surface_size(size) + } + + fn set_transparent(&self, transparent: bool) { + self.0.set_transparent(transparent); + } + + fn set_cursor(&self, cursor: Cursor) { + self.0.set_cursor(cursor); + } + + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + self.0.set_cursor_position(position) + } + + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { + self.0.set_cursor_grab(mode) + } + + fn set_cursor_visible(&self, visible: bool) { + self.0.set_cursor_visible(visible); + } + + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + self.0.set_cursor_hittest(hittest) + } + + fn current_monitor(&self) -> Option { + self.0.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + } + + fn available_monitors(&self) -> Box> { + Box::new( + self.0 + .available_monitors() + .into_iter() + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), + ) + } + + fn primary_monitor(&self) -> Option { + self.0.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) + } + + fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { + self + } + + fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { + self + } +} + +impl CoreWindow for Window { fn reset_dead_keys(&self) { winit_common::xkb::reset_dead_keys(); } @@ -99,14 +161,6 @@ impl CoreWindow for Window { self.0.set_outer_position(position) } - fn surface_size(&self) -> PhysicalSize { - self.0.surface_size() - } - - fn request_surface_size(&self, size: Size) -> Option> { - self.0.request_surface_size(size) - } - fn outer_size(&self) -> PhysicalSize { self.0.outer_size() } @@ -135,10 +189,6 @@ impl CoreWindow for Window { self.0.set_title(title); } - fn set_transparent(&self, transparent: bool) { - self.0.set_transparent(transparent); - } - fn set_blur(&self, blur: bool) { self.0.set_blur(blur); } @@ -247,22 +297,6 @@ impl CoreWindow for Window { self.0.title() } - fn set_cursor(&self, cursor: Cursor) { - self.0.set_cursor(cursor); - } - - fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { - self.0.set_cursor_position(position) - } - - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { - self.0.set_cursor_grab(mode) - } - - fn set_cursor_visible(&self, visible: bool) { - self.0.set_cursor_visible(visible); - } - fn drag_window(&self) -> Result<(), RequestError> { self.0.drag_window() } @@ -274,35 +308,6 @@ impl CoreWindow for Window { fn show_window_menu(&self, position: Position) { self.0.show_window_menu(position); } - - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { - self.0.set_cursor_hittest(hittest) - } - - fn current_monitor(&self) -> Option { - self.0.current_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - } - - fn available_monitors(&self) -> Box> { - Box::new( - self.0 - .available_monitors() - .into_iter() - .map(|monitor| CoreMonitorHandle(Arc::new(monitor))), - ) - } - - fn primary_monitor(&self) -> Option { - self.0.primary_monitor().map(|monitor| CoreMonitorHandle(Arc::new(monitor))) - } - - fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle { - self - } - - fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { - self - } } impl rwh_06::HasDisplayHandle for Window { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index a10da9addb..7ab8b4fa02 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -112,7 +112,7 @@ //! ``` //! //! [`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be -//! compared to the value returned by [`Window::id()`] to determine which [`Window`] +//! compared to the value returned by [`Surface::id()`] to determine which [`Window`] //! dispatched the event. //! //! # Drawing on the window @@ -147,7 +147,7 @@ //! //! Most of the functionality in Winit works with surface coordinates, so usually you only need to //! concern yourself with those. In case you need to convert to some other coordinate system, Winit -//! provides [`Window::surface_position`] and [`Window::surface_size`] to describe the surface's +//! provides [`Window::surface_position`] and [`Surface::surface_size`] to describe the surface's //! location in window coordinates, and Winit provides [`Window::outer_position`] and //! [`Window::outer_size`] to describe the window's location in desktop coordinates. Using these //! methods, you should be able to convert a position in one coordinate system to another. @@ -163,7 +163,7 @@ //! mobile. #![doc = concat!("\n\n", include_str!("../docs/res/coordinate-systems-mobile.svg"), "\n\n")] // Rustfmt removes \n, adding them like this works around that. //! [`Window::surface_position`]: crate::window::Window::surface_position -//! [`Window::surface_size`]: crate::window::Window::surface_size +//! [`Surface::surface_size`]: crate::window::Surface::surface_size //! [`Window::outer_position`]: crate::window::Window::outer_position //! [`Window::outer_size`]: crate::window::Window::outer_size //! @@ -184,7 +184,7 @@ //! can be found by calling [`window.scale_factor()`]. //! //! [`ScaleFactorChanged`]: event::WindowEvent::ScaleFactorChanged -//! [`window.scale_factor()`]: window::Window::scale_factor +//! [`window.scale_factor()`]: window::Surface::scale_factor //! //! # Cargo Features //! @@ -263,7 +263,7 @@ //! [`WindowId`]: window::WindowId //! [`WindowAttributes`]: window::WindowAttributes //! [`create_window`]: event_loop::ActiveEventLoop::create_window -//! [`Window::id()`]: window::Window::id +//! [`Surface::id()`]: window::Surface::id //! [`WindowEvent`]: event::WindowEvent //! [`DeviceEvent`]: event::DeviceEvent //! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle