@@ -458,6 +458,12 @@ impl_dyn_casting!(PlatformWindowAttributes);
458458///
459459/// The surface is closed when dropped.
460460pub 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+ }
0 commit comments