Skip to content

Commit be8bb91

Browse files
committed
Implement downcasting function from Surface to Window et al.
1 parent 0cc4d99 commit be8bb91

File tree

6 files changed

+63
-0
lines changed

6 files changed

+63
-0
lines changed

winit-core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod event_loop;
1818
pub mod icon;
1919
pub mod keyboard;
2020
pub mod monitor;
21+
#[macro_use]
2122
pub mod window;
2223

2324
// `Instant` is not actually available on `wasm32-unknown-unknown`, the `std` implementation there

winit-core/src/window.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,12 @@ impl_dyn_casting!(PlatformWindowAttributes);
461461
///
462462
/// The surface is closed when dropped.
463463
pub trait Surface: AsAny + Send + Sync + fmt::Debug {
464+
/// Attempts to downcast this surface to a core surface type, e.g. [`Window`].
465+
fn try_downcast(&self) -> Option<SurfaceDowncastRef<'_>>;
466+
467+
/// Attempts to downcast this surface mutably to a core surface type, e.g. [`Window`].
468+
fn try_downcast_mut(&mut self) -> Option<SurfaceDowncastMut<'_>>;
469+
464470
/// Returns an identifier unique to the window.
465471
fn id(&self) -> SurfaceId;
466472

@@ -1965,3 +1971,47 @@ mod tests {
19651971
.is_some());
19661972
}
19671973
}
1974+
/// Dynamic reference to one of the common surface traits.
1975+
pub enum SurfaceDowncastRef<'a> {
1976+
/// A toplevel window, see [`Window`] for details.
1977+
Window(&'a dyn Window),
1978+
}
1979+
1980+
/// Dynamic mutable reference to one of the common surface traits.
1981+
pub enum SurfaceDowncastMut<'a> {
1982+
/// A toplevel window, see [`Window`] for details.
1983+
Window(&'a mut dyn Window),
1984+
}
1985+
1986+
/// Helper macro for implementing [`Surface::try_downcast`] and [`Surface::try_downcast_mut`].
1987+
/// ## Syntax
1988+
/// Use the names of variants of [`SurfaceDowncastRef`] or [`SurfaceDowncastMut`] to return that type:
1989+
/// ```ignore
1990+
/// impl_surface_downcast!(Window);
1991+
/// ```
1992+
/// You may also use the special identifier `None` to cause the downcast to fail.
1993+
/// ```ignore
1994+
/// impl_surface_downcast!(None);
1995+
/// ```
1996+
#[macro_export]
1997+
macro_rules! impl_surface_downcast {
1998+
(None) => {
1999+
fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> {
2000+
None
2001+
}
2002+
2003+
fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> {
2004+
None
2005+
}
2006+
};
2007+
($variant:ident) => {
2008+
fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> {
2009+
Some($crate::window::SurfaceDowncastRef::$variant(self))
2010+
}
2011+
2012+
fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> {
2013+
Some($crate::window::SurfaceDowncastMut::$variant(self))
2014+
2015+
}
2016+
};
2017+
}

winit-orbital/src/window.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::sync::{Arc, Mutex};
55
use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
66
use winit_core::cursor::Cursor;
77
use winit_core::error::{NotSupportedError, RequestError};
8+
use winit_core::impl_surface_downcast;
89
use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
910
use winit_core::window::{self, Window as CoreWindow, Surface as CoreSurface, SurfaceId};
1011

@@ -157,6 +158,8 @@ impl Window {
157158
}
158159

159160
impl CoreSurface for Window {
161+
impl_surface_downcast!(Window);
162+
160163
fn id(&self) -> SurfaceId {
161164
SurfaceId::from_raw(self.window_socket.fd)
162165
}

winit-wayland/src/window/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use winit_core::cursor::Cursor;
1818
use winit_core::error::{NotSupportedError, RequestError};
1919
use winit_core::event::{Ime, WindowEvent};
2020
use winit_core::event_loop::AsyncRequestSerial;
21+
use winit_core::impl_surface_downcast;
2122
use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
2223
use winit_core::window::{
2324
CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, Theme,
@@ -283,6 +284,8 @@ impl rwh_06::HasDisplayHandle for Window {
283284
}
284285

285286
impl CoreSurface for Window {
287+
impl_surface_downcast!(Window);
288+
286289
fn id(&self) -> SurfaceId {
287290
self.window_id
288291
}

winit-web/src/window.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use web_sys::HtmlCanvasElement;
1010
use winit_core::cursor::Cursor;
1111
use winit_core::error::{NotSupportedError, RequestError};
1212
use winit_core::icon::Icon;
13+
use winit_core::impl_surface_downcast;
1314
use winit_core::monitor::{Fullscreen, MonitorHandle as CoremMonitorHandle};
1415
use winit_core::window::{
1516
CursorGrabMode, ImeRequestError, ResizeDirection, Surface as RootSurface, SurfaceId, Theme,
@@ -103,6 +104,8 @@ impl Window {
103104
}
104105

105106
impl RootSurface for Window {
107+
impl_surface_downcast!(Window);
108+
106109
fn id(&self) -> SurfaceId {
107110
self.inner.queue(|inner| inner.id)
108111
}

winit-x11/src/window.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use winit_core::error::{NotSupportedError, RequestError};
1616
use winit_core::event::{SurfaceSizeWriter, WindowEvent};
1717
use winit_core::event_loop::AsyncRequestSerial;
1818
use winit_core::icon::RgbaIcon;
19+
use winit_core::impl_surface_downcast;
1920
use winit_core::monitor::{
2021
Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider, VideoMode,
2122
};
@@ -67,6 +68,8 @@ impl Window {
6768
}
6869

6970
impl CoreSurface for Window {
71+
impl_surface_downcast!(Window);
72+
7073
fn id(&self) -> SurfaceId {
7174
self.0.id()
7275
}

0 commit comments

Comments
 (0)