glutin_winit/
window.rs

1use std::num::NonZeroU32;
2
3use glutin::context::PossiblyCurrentContext;
4use glutin::surface::{
5    GlSurface, ResizeableSurface, Surface, SurfaceAttributes, SurfaceAttributesBuilder,
6    SurfaceTypeTrait, WindowSurface,
7};
8use raw_window_handle::{HandleError, HasWindowHandle};
9use winit::window::Window;
10
11/// [`Window`] extensions for working with [`glutin`] surfaces.
12pub trait GlWindow {
13    /// Build the surface attributes suitable to create a window surface.
14    ///
15    /// # Panics
16    /// Panics if either window inner dimension is zero.
17    ///
18    /// # Example
19    /// ```no_run
20    /// use glutin_winit::GlWindow;
21    /// # let winit_window: winit::window::Window = unimplemented!();
22    ///
23    /// let attrs = winit_window.build_surface_attributes(<_>::default());
24    /// ```
25    fn build_surface_attributes(
26        &self,
27        builder: SurfaceAttributesBuilder<WindowSurface>,
28    ) -> Result<SurfaceAttributes<WindowSurface>, HandleError>;
29
30    /// Resize the surface to the window inner size.
31    ///
32    /// No-op if either window size is zero.
33    ///
34    /// # Example
35    /// ```no_run
36    /// use glutin_winit::GlWindow;
37    /// # use glutin::surface::{Surface, WindowSurface};
38    /// # let winit_window: winit::window::Window = unimplemented!();
39    /// # let (gl_surface, gl_context): (Surface<WindowSurface>, _) = unimplemented!();
40    ///
41    /// winit_window.resize_surface(&gl_surface, &gl_context);
42    /// ```
43    fn resize_surface(
44        &self,
45        surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>,
46        context: &PossiblyCurrentContext,
47    );
48}
49
50impl GlWindow for Window {
51    fn build_surface_attributes(
52        &self,
53        builder: SurfaceAttributesBuilder<WindowSurface>,
54    ) -> Result<SurfaceAttributes<WindowSurface>, HandleError> {
55        let (w, h) = self.inner_size().non_zero().expect("invalid zero inner size");
56        let handle = self.window_handle()?.as_raw();
57        Ok(builder.build(handle, w, h))
58    }
59
60    fn resize_surface(
61        &self,
62        surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>,
63        context: &PossiblyCurrentContext,
64    ) {
65        if let Some((w, h)) = self.inner_size().non_zero() {
66            surface.resize(context, w, h)
67        }
68    }
69}
70
71/// [`winit::dpi::PhysicalSize<u32>`] non-zero extensions.
72trait NonZeroU32PhysicalSize {
73    /// Converts to non-zero `(width, height)`.
74    fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)>;
75}
76impl NonZeroU32PhysicalSize for winit::dpi::PhysicalSize<u32> {
77    fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)> {
78        let w = NonZeroU32::new(self.width)?;
79        let h = NonZeroU32::new(self.height)?;
80        Some((w, h))
81    }
82}