diff --git a/examples/window.rs b/examples/window.rs index 225fd53838..acc8f09dda 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -21,6 +21,7 @@ use winit::error::RequestError; use winit::event::{DeviceEvent, DeviceId, Ime, MouseButton, MouseScrollDelta, WindowEvent}; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::keyboard::{Key, ModifiersState}; +use winit::monitor::Fullscreen; #[cfg(macos_platform)] use winit::platform::macos::{OptionAsAlt, WindowAttributesExtMacOS, WindowExtMacOS}; #[cfg(any(x11_platform, wayland_platform))] @@ -30,8 +31,8 @@ use winit::platform::startup_notify::{ #[cfg(web_platform)] use winit::platform::web::{ActiveEventLoopExtWeb, CustomCursorExtWeb, WindowAttributesExtWeb}; use winit::window::{ - Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, Fullscreen, Icon, ResizeDirection, - Theme, Window, WindowAttributes, WindowId, + Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, Icon, ResizeDirection, Theme, Window, + WindowAttributes, WindowId, }; #[path = "util/tracing.rs"] diff --git a/src/monitor.rs b/src/monitor.rs index 898f9b2003..8105f27091 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -5,90 +5,14 @@ //! methods, which return an iterator of [`MonitorHandle`]: //! - [`ActiveEventLoop::available_monitors`][crate::event_loop::ActiveEventLoop::available_monitors]. //! - [`Window::available_monitors`][crate::window::Window::available_monitors]. -use std::num::{NonZeroU16, NonZeroU32}; +use std::borrow::Cow; +use std::fmt; +use std::num::NonZeroU16; +use std::ops::Deref; +use std::sync::Arc; use crate::dpi::{PhysicalPosition, PhysicalSize}; -use crate::platform_impl; - -/// Describes a fullscreen video mode of a monitor. -/// -/// Can be acquired with [`MonitorHandle::video_modes`]. -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct VideoModeHandle { - pub(crate) video_mode: platform_impl::VideoModeHandle, -} - -impl std::fmt::Debug for VideoModeHandle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.video_mode.fmt(f) - } -} - -impl PartialOrd for VideoModeHandle { - fn partial_cmp(&self, other: &VideoModeHandle) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for VideoModeHandle { - fn cmp(&self, other: &VideoModeHandle) -> std::cmp::Ordering { - self.monitor().cmp(&other.monitor()).then( - self.size() - .cmp(&other.size()) - .then( - self.refresh_rate_millihertz() - .cmp(&other.refresh_rate_millihertz()) - .then(self.bit_depth().cmp(&other.bit_depth())), - ) - .reverse(), - ) - } -} - -impl VideoModeHandle { - /// Returns the resolution of this video mode. This **must not** be used to create your - /// rendering surface. Use [`Window::surface_size()`] instead. - /// - /// [`Window::surface_size()`]: crate::window::Window::surface_size - #[inline] - pub fn size(&self) -> PhysicalSize { - self.video_mode.size() - } - - /// Returns the bit depth of this video mode, as in how many bits you have - /// available per color. This is generally 24 bits or 32 bits on modern - /// systems, depending on whether the alpha channel is counted or not. - #[inline] - pub fn bit_depth(&self) -> Option { - self.video_mode.bit_depth() - } - - /// Returns the refresh rate of this video mode in mHz. - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - self.video_mode.refresh_rate_millihertz() - } - - /// Returns the monitor that this video mode is valid for. Each monitor has - /// a separate set of valid video modes. - #[inline] - pub fn monitor(&self) -> MonitorHandle { - MonitorHandle { inner: self.video_mode.monitor() } - } -} - -impl std::fmt::Display for VideoModeHandle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}x{} {}{}", - self.size().width, - self.size().height, - self.refresh_rate_millihertz().map(|rate| format!("@ {rate} mHz ")).unwrap_or_default(), - self.bit_depth().map(|bit_depth| format!("({bit_depth} bpp)")).unwrap_or_default(), - ) - } -} +use crate::utils::AsAny; /// Handle to a monitor. /// @@ -112,21 +36,33 @@ impl std::fmt::Display for VideoModeHandle { /// to check. /// /// [`Window`]: crate::window::Window -#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct MonitorHandle { - pub(crate) inner: platform_impl::MonitorHandle, +#[derive(Debug, Clone)] +pub struct MonitorHandle(pub(crate) Arc); + +impl Deref for MonitorHandle { + type Target = dyn MonitorHandleProvider; + + fn deref(&self) -> &Self::Target { + self.0.as_ref() + } } -impl std::fmt::Debug for MonitorHandle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.inner.fmt(f) +impl PartialEq for MonitorHandle { + fn eq(&self, other: &Self) -> bool { + self.0.as_ref().eq(other.0.as_ref()) } } -impl MonitorHandle { +impl Eq for MonitorHandle {} + +/// Provider of the [`MonitorHandle`]. +pub trait MonitorHandleProvider: AsAny + fmt::Debug { + /// Native platform identifier of this monitor. + fn native_id(&self) -> u64; + /// Returns a human-readable name of the monitor. /// - /// Returns `None` if the monitor doesn't exist anymore. + /// Returns `None` if the monitor doesn't exist anymore or the name couldn't be obtained. /// /// ## Platform-specific /// @@ -136,10 +72,7 @@ impl MonitorHandle { doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]." )] #[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")] - #[inline] - pub fn name(&self) -> Option { - self.inner.name() - } + fn name(&self) -> Option>; /// Returns the top-left corner position of the monitor relative to the larger full /// screen area. @@ -152,10 +85,7 @@ impl MonitorHandle { doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]." )] #[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")] - #[inline] - pub fn position(&self) -> Option> { - self.inner.position() - } + 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`]. @@ -176,20 +106,73 @@ impl MonitorHandle { /// #[rustfmt::skip] /// [`Window::scale_factor`]: crate::window::Window::scale_factor - #[inline] - pub fn scale_factor(&self) -> f64 { - self.inner.scale_factor() - } + fn scale_factor(&self) -> f64; /// Returns the currently active video mode of this monitor. - #[inline] - pub fn current_video_mode(&self) -> Option { - self.inner.current_video_mode().map(|video_mode| VideoModeHandle { video_mode }) - } + fn current_video_mode(&self) -> Option; /// Returns all fullscreen video modes supported by this monitor. - #[inline] - pub fn video_modes(&self) -> impl Iterator { - self.inner.video_modes().map(|video_mode| VideoModeHandle { video_mode }) + fn video_modes(&self) -> Box>; +} + +impl PartialEq for dyn MonitorHandleProvider + '_ { + fn eq(&self, other: &Self) -> bool { + self.native_id() == other.native_id() + } +} + +impl Eq for dyn MonitorHandleProvider + '_ {} + +/// Describes a fullscreen video mode of a monitor. +/// +/// Can be acquired with [`MonitorHandle::video_modes`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct VideoMode { + pub(crate) size: PhysicalSize, + pub(crate) bit_depth: Option, + pub(crate) refresh_rate_millihertz: Option, +} + +impl VideoMode { + /// Returns the resolution of this video mode. This **must not** be used to create your + /// rendering surface. Use [`Window::surface_size()`] instead. + /// + /// [`Window::surface_size()`]: crate::window::Window::surface_size + pub fn size(&self) -> PhysicalSize { + self.size + } + + /// Returns the bit depth of this video mode, as in how many bits you have + /// available per color. This is generally 24 bits or 32 bits on modern + /// systems, depending on whether the alpha channel is counted or not. + pub fn bit_depth(&self) -> Option { + self.bit_depth + } + + /// Returns the refresh rate of this video mode in mHz. + pub fn refresh_rate_millihertz(&self) -> Option { + self.refresh_rate_millihertz } } + +impl fmt::Display for VideoMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}x{} {}{}", + self.size.width, + self.size.height, + self.refresh_rate_millihertz.map(|rate| format!("@ {rate} mHz ")).unwrap_or_default(), + self.bit_depth.map(|bit_depth| format!("({bit_depth} bpp)")).unwrap_or_default(), + ) + } +} + +/// Fullscreen modes. +#[derive(Clone, Debug)] +pub enum Fullscreen { + Exclusive(MonitorHandle, VideoMode), + + /// Providing `None` to `Borderless` will fullscreen on the current monitor. + Borderless(Option), +} diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index 84af00388b..bcdcccbc46 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -14,7 +14,6 @@ //! * `wayland-csd-adwaita-crossfont`. //! * `wayland-csd-adwaita-notitle`. use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder}; -use crate::monitor::MonitorHandle; pub use crate::window::Theme; use crate::window::{Window as CoreWindow, WindowAttributes}; @@ -97,16 +96,3 @@ impl WindowAttributesExtWayland for WindowAttributes { self } } - -/// Additional methods on `MonitorHandle` that are specific to Wayland. -pub trait MonitorHandleExtWayland { - /// Returns the inner identifier of the monitor. - fn native_id(&self) -> u32; -} - -impl MonitorHandleExtWayland for MonitorHandle { - #[inline] - fn native_id(&self) -> u32 { - self.inner.native_identifier() - } -} diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 589c4753ba..160802e66d 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::dpi::Size; use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder}; -use crate::monitor::MonitorHandle; +use crate::monitor::MonitorHandleProvider; use crate::window::{Window as CoreWindow, WindowAttributes}; /// X window type. Maps directly to @@ -249,7 +249,7 @@ pub trait MonitorHandleExtX11 { fn native_id(&self) -> u32; } -impl MonitorHandleExtX11 for MonitorHandle { +impl MonitorHandleExtX11 for MonitorHandleProvider { #[inline] fn native_id(&self) -> u32 { self.inner.native_identifier() diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index b715e40ac2..2579f76cba 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -4,7 +4,6 @@ compile_error!("Please select a feature to build for unix: `x11`, `wayland`"); use std::env; -use std::num::{NonZeroU16, NonZeroU32}; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::time::Duration; #[cfg(x11_platform)] @@ -19,7 +18,6 @@ use crate::application::ApplicationHandler; pub(crate) use crate::cursor::OnlyCursorImageSource as PlatformCustomCursorSource; #[cfg(x11_platform)] use crate::dpi::Size; -use crate::dpi::{PhysicalPosition, PhysicalSize}; use crate::error::{EventLoopError, NotSupportedError}; use crate::event_loop::ActiveEventLoop; pub(crate) use crate::icon::RgbaIcon as PlatformIcon; @@ -162,14 +160,6 @@ impl FingerId { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum MonitorHandle { - #[cfg(x11_platform)] - X(x11::MonitorHandle), - #[cfg(wayland_platform)] - Wayland(wayland::MonitorHandle), -} - /// `x11_or_wayland!(match expr; Enum(foo) => foo.something())` /// expands to the equivalent of /// ```ignore @@ -198,68 +188,6 @@ macro_rules! x11_or_wayland { }; } -impl MonitorHandle { - #[inline] - pub fn name(&self) -> Option { - x11_or_wayland!(match self; MonitorHandle(m) => m.name()) - } - - #[inline] - pub fn native_identifier(&self) -> u32 { - x11_or_wayland!(match self; MonitorHandle(m) => m.native_identifier()) - } - - #[inline] - pub fn position(&self) -> Option> { - x11_or_wayland!(match self; MonitorHandle(m) => m.position()) - } - - #[inline] - pub fn scale_factor(&self) -> f64 { - x11_or_wayland!(match self; MonitorHandle(m) => m.scale_factor() as _) - } - - #[inline] - pub fn current_video_mode(&self) -> Option { - x11_or_wayland!(match self; MonitorHandle(m) => m.current_video_mode()) - } - - #[inline] - pub fn video_modes(&self) -> Box> { - x11_or_wayland!(match self; MonitorHandle(m) => Box::new(m.video_modes())) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum VideoModeHandle { - #[cfg(x11_platform)] - X(x11::VideoModeHandle), - #[cfg(wayland_platform)] - Wayland(wayland::VideoModeHandle), -} - -impl VideoModeHandle { - #[inline] - pub fn size(&self) -> PhysicalSize { - x11_or_wayland!(match self; VideoModeHandle(m) => m.size()) - } - - #[inline] - pub fn bit_depth(&self) -> Option { - x11_or_wayland!(match self; VideoModeHandle(m) => m.bit_depth()) - } - - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - x11_or_wayland!(match self; VideoModeHandle(m) => m.refresh_rate_millihertz()) - } - - #[inline] - pub fn monitor(&self) -> MonitorHandle { - x11_or_wayland!(match self; VideoModeHandle(m) => m.monitor(); as MonitorHandle) - } -} - #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct KeyEventExtra { pub text_with_all_modifiers: Option, diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 1ba1667e8c..d4d338bb60 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -17,6 +17,7 @@ use crate::dpi::LogicalSize; use crate::error::{EventLoopError, OsError, RequestError}; use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent}; use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; +use crate::monitor::MonitorHandle as CoreMonitorHandle; use crate::platform::pump_events::PumpStatus; use crate::platform_impl::platform::min_timeout; use crate::platform_impl::PlatformCustomCursor; @@ -28,6 +29,7 @@ pub mod sink; pub use proxy::EventLoopProxy; use sink::EventSink; +use super::output::MonitorHandle; use super::state::{WindowCompositorUpdate, WinitState}; use super::window::state::FrameCallbackState; use super::{logical_to_physical_rounded, DeviceId, WindowId}; @@ -618,19 +620,18 @@ impl RootActiveEventLoop for ActiveEventLoop { Ok(Box::new(window)) } - fn available_monitors(&self) -> Box> { + fn available_monitors(&self) -> Box> { Box::new( self.state .borrow() .output_state .outputs() - .map(crate::platform_impl::wayland::output::MonitorHandle::new) - .map(crate::platform_impl::MonitorHandle::Wayland) - .map(|inner| crate::monitor::MonitorHandle { inner }), + .map(MonitorHandle::new) + .map(|inner| CoreMonitorHandle(Arc::new(inner))), ) } - fn primary_monitor(&self) -> Option { + fn primary_monitor(&self) -> Option { // There's no primary monitor on Wayland. None } diff --git a/src/platform_impl/linux/wayland/mod.rs b/src/platform_impl/linux/wayland/mod.rs index 214b4a71d5..bf79400807 100644 --- a/src/platform_impl/linux/wayland/mod.rs +++ b/src/platform_impl/linux/wayland/mod.rs @@ -1,7 +1,6 @@ //! Winit's Wayland backend. pub use event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}; -pub use output::{MonitorHandle, VideoModeHandle}; use sctk::reexports::client::protocol::wl_surface::WlSurface; use sctk::reexports::client::Proxy; pub use window::Window; diff --git a/src/platform_impl/linux/wayland/output.rs b/src/platform_impl/linux/wayland/output.rs index ea5ba083e5..c1081d331f 100644 --- a/src/platform_impl/linux/wayland/output.rs +++ b/src/platform_impl/linux/wayland/output.rs @@ -1,11 +1,12 @@ -use std::num::{NonZeroU16, NonZeroU32}; +use std::borrow::Cow; +use std::num::NonZeroU16; use sctk::output::{Mode, OutputData}; use sctk::reexports::client::protocol::wl_output::WlOutput; use sctk::reexports::client::Proxy; -use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}; -use crate::platform_impl::platform::VideoModeHandle as PlatformVideoModeHandle; +use crate::dpi::{LogicalPosition, PhysicalPosition}; +use crate::monitor::{MonitorHandleProvider as CoreMonitorHandle, VideoMode}; #[derive(Clone, Debug)] pub struct MonitorHandle { @@ -17,21 +18,20 @@ impl MonitorHandle { pub(crate) fn new(proxy: WlOutput) -> Self { Self { proxy } } +} - #[inline] - pub fn name(&self) -> Option { +impl CoreMonitorHandle for MonitorHandle { + fn native_id(&self) -> u64 { let output_data = self.proxy.data::().unwrap(); - output_data.with_output_info(|info| info.name.clone()) + output_data.with_output_info(|info| info.id as u64) } - #[inline] - pub fn native_identifier(&self) -> u32 { + fn name(&self) -> Option> { let output_data = self.proxy.data::().unwrap(); - output_data.with_output_info(|info| info.id) + output_data.with_output_info(|info| info.name.clone().map(Cow::Owned)) } - #[inline] - pub fn position(&self) -> Option> { + fn position(&self) -> Option> { let output_data = self.proxy.data::().unwrap(); Some(output_data.with_output_info(|info| { info.logical_position.map_or_else( @@ -47,95 +47,41 @@ impl MonitorHandle { })) } - #[inline] - pub fn scale_factor(&self) -> i32 { + fn scale_factor(&self) -> f64 { let output_data = self.proxy.data::().unwrap(); - output_data.scale_factor() + output_data.scale_factor() as f64 } - #[inline] - pub fn current_video_mode(&self) -> Option { + fn current_video_mode(&self) -> Option { let output_data = self.proxy.data::().unwrap(); output_data.with_output_info(|info| { let mode = info.modes.iter().find(|mode| mode.current).cloned(); - mode.map(|mode| { - PlatformVideoModeHandle::Wayland(VideoModeHandle::new(self.clone(), mode)) - }) + mode.map(wayland_mode_to_core_mode) }) } - #[inline] - pub fn video_modes(&self) -> impl Iterator { + fn video_modes(&self) -> Box> { let output_data = self.proxy.data::().unwrap(); let modes = output_data.with_output_info(|info| info.modes.clone()); - let monitor = self.clone(); - - modes.into_iter().map(move |mode| { - PlatformVideoModeHandle::Wayland(VideoModeHandle::new(monitor.clone(), mode)) - }) + Box::new(modes.into_iter().map(wayland_mode_to_core_mode)) } } impl PartialEq for MonitorHandle { fn eq(&self, other: &Self) -> bool { - self.native_identifier() == other.native_identifier() + self.native_id() == other.native_id() } } impl Eq for MonitorHandle {} -impl PartialOrd for MonitorHandle { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for MonitorHandle { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.native_identifier().cmp(&other.native_identifier()) - } -} - -impl std::hash::Hash for MonitorHandle { - fn hash(&self, state: &mut H) { - self.native_identifier().hash(state); - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct VideoModeHandle { - pub(crate) size: PhysicalSize, - pub(crate) refresh_rate_millihertz: Option, - pub(crate) monitor: MonitorHandle, -} - -impl VideoModeHandle { - fn new(monitor: MonitorHandle, mode: Mode) -> Self { - VideoModeHandle { - size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(), - refresh_rate_millihertz: NonZeroU32::new(mode.refresh_rate as u32), - monitor: monitor.clone(), - } - } - - #[inline] - pub fn size(&self) -> PhysicalSize { - self.size - } - - #[inline] - pub fn bit_depth(&self) -> Option { - None - } - - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - self.refresh_rate_millihertz - } - - pub fn monitor(&self) -> MonitorHandle { - self.monitor.clone() +/// Convert the wayland's [`Mode`] to winit's [`VideoMode`]. +fn wayland_mode_to_core_mode(mode: Mode) -> VideoMode { + VideoMode { + size: (mode.dimensions.0, mode.dimensions.1).into(), + bit_depth: None, + refresh_rate_millihertz: NonZeroU16::new(mode.refresh_rate as u16), } } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 42f37a0963..ec4ddc1fed 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -21,12 +21,12 @@ use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; use crate::error::{NotSupportedError, RequestError}; use crate::event::{Ime, WindowEvent}; use crate::event_loop::AsyncRequestSerial; -use crate::monitor::MonitorHandle as CoreMonitorHandle; -use crate::platform_impl::{Fullscreen, MonitorHandle as PlatformMonitorHandle}; +use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; +use crate::platform_impl::wayland::output; +use crate::utils::AsAny; use crate::window::{ - Cursor, CursorGrabMode, Fullscreen as CoreFullscreen, ImePurpose, ResizeDirection, Theme, - UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, - WindowId as CoreWindowId, WindowLevel, + Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, + Window as CoreWindow, WindowAttributes, WindowButtons, WindowId as CoreWindowId, WindowLevel, }; pub(crate) mod state; @@ -139,18 +139,19 @@ impl Window { // Set startup mode. match attributes.fullscreen.map(Into::into) { - Some(Fullscreen::Exclusive(_)) => { + Some(Fullscreen::Exclusive(..)) => { warn!("`Fullscreen::Exclusive` is ignored on Wayland"); }, #[cfg_attr(not(x11_platform), allow(clippy::bind_instead_of_map))] Some(Fullscreen::Borderless(monitor)) => { - let output = monitor.and_then(|monitor| match monitor { - PlatformMonitorHandle::Wayland(monitor) => Some(monitor.proxy), - #[cfg(x11_platform)] - PlatformMonitorHandle::X(_) => None, + let output = monitor.as_ref().and_then(|monitor| { + monitor + .as_any() + .downcast_ref::() + .map(|handle| &handle.proxy) }); - window.set_fullscreen(output.as_ref()) + window.set_fullscreen(output) }, _ if attributes.maximized => window.set_maximized(), _ => (), @@ -435,26 +436,27 @@ impl CoreWindow for Window { .unwrap_or_default() } - fn set_fullscreen(&self, fullscreen: Option) { + fn set_fullscreen(&self, fullscreen: Option) { match fullscreen { - Some(CoreFullscreen::Exclusive(_)) => { + Some(Fullscreen::Exclusive(..)) => { warn!("`Fullscreen::Exclusive` is ignored on Wayland"); }, #[cfg_attr(not(x11_platform), allow(clippy::bind_instead_of_map))] - Some(CoreFullscreen::Borderless(monitor)) => { - let output = monitor.and_then(|monitor| match monitor.inner { - PlatformMonitorHandle::Wayland(monitor) => Some(monitor.proxy), - #[cfg(x11_platform)] - PlatformMonitorHandle::X(_) => None, + Some(Fullscreen::Borderless(monitor)) => { + let output = monitor.as_ref().and_then(|monitor| { + monitor + .as_any() + .downcast_ref::() + .map(|handle| &handle.proxy) }); - self.window.set_fullscreen(output.as_ref()) + self.window.set_fullscreen(output) }, None => self.window.unset_fullscreen(), } } - fn fullscreen(&self) -> Option { + fn fullscreen(&self) -> Option { let is_fullscreen = self .window_state .lock() @@ -466,7 +468,7 @@ impl CoreWindow for Window { if is_fullscreen { let current_monitor = self.current_monitor(); - Some(CoreFullscreen::Borderless(current_monitor)) + Some(Fullscreen::Borderless(current_monitor)) } else { None } @@ -626,8 +628,7 @@ impl CoreWindow for Window { data.outputs() .next() .map(MonitorHandle::new) - .map(crate::platform_impl::MonitorHandle::Wayland) - .map(|inner| CoreMonitorHandle { inner }) + .map(|monitor| CoreMonitorHandle(Arc::new(monitor))) } fn available_monitors(&self) -> Box> { @@ -637,8 +638,7 @@ impl CoreWindow for Window { .unwrap() .clone() .into_iter() - .map(crate::platform_impl::MonitorHandle::Wayland) - .map(|inner| CoreMonitorHandle { inner }), + .map(|inner| CoreMonitorHandle(Arc::new(inner))), ) } diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index cada63f42e..0a1656efe1 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -703,23 +703,25 @@ impl RootActiveEventLoop for ActiveEventLoop { }) } - fn available_monitors(&self) -> Box> { + fn available_monitors( + &self, + ) -> Box> { Box::new( self.xconn .available_monitors() .into_iter() .flatten() .map(crate::platform_impl::MonitorHandle::X) - .map(|inner| crate::monitor::MonitorHandle { inner }), + .map(|inner| crate::monitor::MonitorHandleProvider { inner }), ) } - fn primary_monitor(&self) -> Option { + fn primary_monitor(&self) -> Option { self.xconn .primary_monitor() .ok() .map(crate::platform_impl::MonitorHandle::X) - .map(|inner| crate::monitor::MonitorHandle { inner }) + .map(|inner| crate::monitor::MonitorHandleProvider { inner }) } fn system_theme(&self) -> Option { diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index ac5a0bc0d9..e3e4e81758 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -270,28 +270,30 @@ impl CoreWindow for Window { self.0.set_cursor_hittest(hittest) } - fn current_monitor(&self) -> Option { + fn current_monitor(&self) -> Option { self.0 .current_monitor() .map(crate::platform_impl::MonitorHandle::X) - .map(|inner| crate::monitor::MonitorHandle { inner }) + .map(|inner| crate::monitor::MonitorHandleProvider { inner }) } - fn available_monitors(&self) -> Box> { + fn available_monitors( + &self, + ) -> Box> { Box::new( self.0 .available_monitors() .into_iter() .map(crate::platform_impl::MonitorHandle::X) - .map(|inner| crate::monitor::MonitorHandle { inner }), + .map(|inner| crate::monitor::MonitorHandleProvider { inner }), ) } - fn primary_monitor(&self) -> Option { + fn primary_monitor(&self) -> Option { self.0 .primary_monitor() .map(crate::platform_impl::MonitorHandle::X) - .map(|inner| crate::monitor::MonitorHandle { inner }) + .map(|inner| crate::monitor::MonitorHandleProvider { inner }) } #[cfg(feature = "rwh_06")] diff --git a/src/platform_impl/mod.rs b/src/platform_impl/mod.rs index bd55440b89..f521b117a6 100644 --- a/src/platform_impl/mod.rs +++ b/src/platform_impl/mod.rs @@ -1,6 +1,3 @@ -use crate::monitor::{MonitorHandle as RootMonitorHandle, VideoModeHandle as RootVideoModeHandle}; -use crate::window::Fullscreen as RootFullscreen; - #[cfg(android_platform)] mod android; #[cfg(target_vendor = "apple")] @@ -28,38 +25,6 @@ use self::web as platform; #[cfg(windows_platform)] use self::windows as platform; -/// Helper for converting between platform-specific and generic -/// [`VideoModeHandle`]/[`MonitorHandle`] -#[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) enum Fullscreen { - Exclusive(VideoModeHandle), - Borderless(Option), -} - -impl From for Fullscreen { - fn from(f: RootFullscreen) -> Self { - match f { - RootFullscreen::Exclusive(mode) => Self::Exclusive(mode.video_mode), - RootFullscreen::Borderless(Some(handle)) => Self::Borderless(Some(handle.inner)), - RootFullscreen::Borderless(None) => Self::Borderless(None), - } - } -} - -impl From for RootFullscreen { - fn from(f: Fullscreen) -> Self { - match f { - Fullscreen::Exclusive(video_mode) => { - Self::Exclusive(RootVideoModeHandle { video_mode }) - }, - Fullscreen::Borderless(Some(inner)) => { - Self::Borderless(Some(RootMonitorHandle { inner })) - }, - Fullscreen::Borderless(None) => Self::Borderless(None), - } - } -} - #[cfg(all( not(ios_platform), not(windows_platform), diff --git a/src/window.rs b/src/window.rs index 1ded68b146..857583a29b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -10,7 +10,7 @@ pub use crate::cursor::{BadImage, Cursor, CustomCursor, CustomCursorSource, MAX_ use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; use crate::error::RequestError; pub use crate::icon::{BadIcon, Icon}; -use crate::monitor::{MonitorHandle, VideoModeHandle}; +use crate::monitor::{Fullscreen, MonitorHandle}; use crate::platform_impl::{self, PlatformSpecificWindowAttributes}; use crate::utils::AsAny; @@ -55,7 +55,7 @@ impl From for WindowId { } /// Attributes used when creating a window. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct WindowAttributes { pub surface_size: Option, pub min_surface_size: Option, @@ -1392,15 +1392,6 @@ impl From for CursorIcon { } } -/// Fullscreen modes. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum Fullscreen { - Exclusive(VideoModeHandle), - - /// Providing `None` to `Borderless` will fullscreen on the current monitor. - Borderless(Option), -} - /// The theme variant to use. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/tests/send_objects.rs b/tests/send_objects.rs index 9bc4db8eb6..ea0a700868 100644 --- a/tests/send_objects.rs +++ b/tests/send_objects.rs @@ -20,7 +20,7 @@ fn window_builder_send() { fn ids_send() { needs_send::(); needs_send::(); - needs_send::(); + needs_send::(); } #[test]