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: NonZero, h: NonZero) = self.inner_size().non_zero().expect(msg:"invalid zero inner size");
56 let handle: RawWindowHandle = self.window_handle()?.as_raw();
57 Ok(builder.build(handle, width:w, height:h))
58 }
59
60 fn resize_surface(
61 &self,
62 surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>,
63 context: &PossiblyCurrentContext,
64 ) {
65 if let Some((w: NonZero, h: NonZero)) = self.inner_size().non_zero() {
66 surface.resize(context, width:w, height: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: NonZero = NonZeroU32::new(self.width)?;
79 let h: NonZero = NonZeroU32::new(self.height)?;
80 Some((w, h))
81 }
82}
83