Skip to content

Commit 1c4d0ac

Browse files
committed
Implement downcasting function from Surface to Window et al.
1 parent 00abfe1 commit 1c4d0ac

File tree

6 files changed

+65
-2
lines changed

6 files changed

+65
-2
lines changed

winit-core/src/lib.rs

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

winit-core/src/window.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ impl_dyn_casting!(PlatformWindowAttributes);
458458
///
459459
/// The surface is closed when dropped.
460460
pub trait Surface: AsAny + Send + Sync + fmt::Debug {
461+
/// Attempts to downcast this surface to a core surface type, e.g. [`Window`].
462+
fn try_downcast(&self) -> Option<SurfaceDowncastRef<'_>>;
463+
464+
/// Attempts to downcast this surface mutably to a core surface type, e.g. [`Window`].
465+
fn try_downcast_mut(&mut self) -> Option<SurfaceDowncastMut<'_>>;
466+
461467
/// Returns an identifier unique to the window.
462468
fn id(&self) -> SurfaceId;
463469

@@ -1594,3 +1600,48 @@ impl ActivationToken {
15941600
&self.token
15951601
}
15961602
}
1603+
1604+
/// Dynamic reference to one of the common surface traits.
1605+
pub enum SurfaceDowncastRef<'a> {
1606+
/// A toplevel window, see [`Window`] for details.
1607+
Window(&'a dyn Window),
1608+
}
1609+
1610+
/// Dynamic mutable reference to one of the common surface traits.
1611+
pub enum SurfaceDowncastMut<'a> {
1612+
/// A toplevel window, see [`Window`] for details.
1613+
Window(&'a mut dyn Window),
1614+
}
1615+
1616+
/// Helper macro for implementing [`Surface::try_downcast`] and [`Surface::try_downcast_mut`].
1617+
/// ## Syntax
1618+
/// Use the names of variants of [`SurfaceDowncastRef`] or [`SurfaceDowncastMut`] to return that type:
1619+
/// ```ignore
1620+
/// impl_surface_downcast!(Window);
1621+
/// ```
1622+
/// You may also use the special identifier `None` to cause the downcast to fail.
1623+
/// ```ignore
1624+
/// impl_surface_downcast!(None);
1625+
/// ```
1626+
#[macro_export]
1627+
macro_rules! impl_surface_downcast {
1628+
(None) => {
1629+
fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> {
1630+
None
1631+
}
1632+
1633+
fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> {
1634+
None
1635+
}
1636+
};
1637+
($variant:ident) => {
1638+
fn try_downcast(&self) -> Option<$crate::window::SurfaceDowncastRef<'_>> {
1639+
Some($crate::window::SurfaceDowncastRef::$variant(self))
1640+
}
1641+
1642+
fn try_downcast_mut(&mut self) -> Option<$crate::window::SurfaceDowncastMut<'_>> {
1643+
Some($crate::window::SurfaceDowncastMut::$variant(self))
1644+
1645+
}
1646+
};
1647+
}

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, ImePurpose, Surface as CoreSurface, Window as CoreWindow, 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: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ 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::{
23-
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
24-
Surface as CoreSurface, WindowAttributes, WindowButtons, SurfaceId, WindowLevel,
24+
CursorGrabMode, ImePurpose, ResizeDirection, Surface as CoreSurface, SurfaceDowncastMut, SurfaceDowncastRef, SurfaceId, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, WindowLevel
2525
};
2626

2727
use super::event_loop::sink::EventSink;
@@ -280,6 +280,8 @@ impl rwh_06::HasDisplayHandle for Window {
280280
}
281281

282282
impl CoreSurface for Window {
283+
impl_surface_downcast!(Window);
284+
283285
fn id(&self) -> SurfaceId {
284286
self.window_id
285287
}

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, ImePurpose, ResizeDirection, Theme, UserAttentionType, Surface as RootSurface,
@@ -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
};
@@ -66,6 +67,8 @@ impl Window {
6667
}
6768

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

0 commit comments

Comments
 (0)