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::HasRawWindowHandle;
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 ) -> SurfaceAttributes<WindowSurface>;
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 ) -> SurfaceAttributes<WindowSurface> {
55 let (w: NonZero, h: NonZero) = self.inner_size().non_zero().expect(msg:"invalid zero inner size");
56 builder.build(self.raw_window_handle(), width:w, height:h)
57 }
58
59 fn resize_surface(
60 &self,
61 surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>,
62 context: &PossiblyCurrentContext,
63 ) {
64 if let Some((w: NonZero, h: NonZero)) = self.inner_size().non_zero() {
65 surface.resize(context, width:w, height:h)
66 }
67 }
68}
69
70/// [`winit::dpi::PhysicalSize<u32>`] non-zero extensions.
71trait NonZeroU32PhysicalSize {
72 /// Converts to non-zero `(width, height)`.
73 fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)>;
74}
75impl NonZeroU32PhysicalSize for winit::dpi::PhysicalSize<u32> {
76 fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)> {
77 let w: NonZero = NonZeroU32::new(self.width)?;
78 let h: NonZero = NonZeroU32::new(self.height)?;
79 Some((w, h))
80 }
81}
82