fj_window/window.rs
1use std::sync::Arc;
2
3use fj_viewer::{Screen, ScreenSize};
4use winit::{event_loop::EventLoop, window::WindowBuilder};
5
6/// A window that can be used with `fj-viewer`
7pub struct Window {
8 inner: Arc<winit::window::Window>,
9}
10
11impl Window {
12 /// Create an instance of `Window` from the given `EventLoop`
13 pub fn new<T>(event_loop: &EventLoop<T>) -> Result<Self, WindowError> {
14 let window = WindowBuilder::new()
15 .with_title("Fornjot")
16 .with_maximized(true)
17 // When the window decorations are enabled, I'm seeing the following
18 // error on Gnome/Wayland, in response to a `ScaleFactorChange`
19 // event:
20 // ```
21 // wl_surface@24: error 2: Buffer size (1940x45) must be an integer multiple of the buffer_scale (2).
22 // ```
23 //
24 // This is happening most of the time. Very rarely, the window will
25 // open as expected.
26 //
27 // I believe that there is a race condition somewhere low in the
28 // stack, that will cause the buffer size for the window decorations
29 // to not be updated before the check that produces the above error.
30 // I failed to track down where this is happening, so I decided to
31 // deploy this workaround instead of spending more time.
32 //
33 // Window decorations should be re-enabled once possible. This is
34 // being tracked in this issue:
35 // https://github.com/hannobraun/fornjot/issues/1848
36 .with_decorations(false)
37 .with_transparent(false)
38 .build(event_loop)?;
39
40 Ok(Self {
41 inner: Arc::new(window),
42 })
43 }
44}
45
46impl Screen for Window {
47 type Window = winit::window::Window;
48
49 fn size(&self) -> ScreenSize {
50 let size = self.inner.inner_size();
51
52 ScreenSize {
53 width: size.width,
54 height: size.height,
55 }
56 }
57
58 fn window(&self) -> Arc<Self::Window> {
59 self.inner.clone()
60 }
61}
62
63/// Error initializing window
64#[derive(Debug, thiserror::Error)]
65#[error("Error initializing window")]
66pub struct WindowError(#[from] pub winit::error::OsError);