demo_vk/app/
fullscreen_toggle.rs

1use {
2    crate::trace,
3    anyhow::{Context, Result},
4    glfw::WindowMode,
5};
6
7/// A helper for toggling fullscreen on a glfw window.
8pub struct FullscreenToggle {
9    pos: (i32, i32),
10    framebuffer_size: (u32, u32),
11    is_fullscreen: bool,
12}
13
14impl FullscreenToggle {
15    /// Create a new fullscreen toggle helper.
16    pub fn new(window: &glfw::Window) -> Self {
17        let pos = window.get_pos();
18        let (w, h) = window.get_framebuffer_size();
19        Self {
20            pos,
21            framebuffer_size: (w as u32, h as u32),
22            is_fullscreen: false,
23        }
24    }
25
26    /// Switch to fullscreen if windowed, switch back to windowed if fullscreen.
27    pub fn toggle_fullscreen(
28        &mut self,
29        window: &mut glfw::Window,
30    ) -> Result<()> {
31        let mut glfw = window.glfw.clone();
32        glfw.with_primary_monitor(|_, monitor_opt| -> Result<()> {
33            let monitor = monitor_opt
34                .with_context(trace!("no primary monitor detected!"))?;
35
36            match self.is_fullscreen {
37                true => {
38                    // then switch to "windowed"
39                    window.set_decorated(true);
40                    window.set_monitor(
41                        WindowMode::Windowed,
42                        self.pos.0,
43                        self.pos.1,
44                        self.framebuffer_size.0,
45                        self.framebuffer_size.1,
46                        None,
47                    );
48                    self.is_fullscreen = false;
49                }
50                false => {
51                    // switch to "borderless fullscreen"
52
53                    // save the current position and size before switching
54                    self.pos = window.get_pos();
55                    let (w, h) = window.get_framebuffer_size();
56                    self.framebuffer_size = (w as u32, h as u32);
57
58                    // switch to fullscreen
59                    let mode = monitor.get_video_mode().with_context(
60                        trace!("Unable to get video mode for primary monitor!"),
61                    )?;
62                    window.set_decorated(false);
63                    window.set_monitor(
64                        WindowMode::Windowed,
65                        0,
66                        0,
67                        mode.width,
68                        mode.height,
69                        Some(mode.refresh_rate),
70                    );
71                    self.is_fullscreen = true;
72                }
73            }
74
75            Ok(())
76        })
77    }
78}