
# Objective - #16883 - Improve the default behaviour of the exclusive fullscreen API. ## Solution This PR changes the exclusive fullscreen window mode to require the type `WindowMode::Fullscreen(MonitorSelection, VideoModeSelection)` and removes `WindowMode::SizedFullscreen`. This API somewhat intentionally more closely resembles Winit 0.31's upcoming fullscreen and video mode API. The new VideoModeSelection enum is specified as follows: ```rust pub enum VideoModeSelection { /// Uses the video mode that the monitor is already in. Current, /// Uses a given [`crate::monitor::VideoMode`]. A list of video modes supported by the monitor /// is supplied by [`crate::monitor::Monitor::video_modes`]. Specific(VideoMode), } ``` ### Changing default behaviour This might be contentious because it removes the previous behaviour of `WindowMode::Fullscreen` which selected the highest resolution possible. While the previous behaviour would be quite easy to re-implement as additional options, or as an impl method on Monitor, I would argue that this isn't an implementation that should be encouraged. From the perspective of a Windows user, I prefer what the majority of modern games do when entering fullscreen which is to preserve the OS's current resolution settings, which allows exclusive fullscreen to be entered faster, and to only have it change if I manually select it in either the options of the game or the OS. The highest resolution available is not necessarily what the user prefers. I am open to changing this if I have just missed a good use case for it. Likewise, the only functionality that `WindowMode::SizedFullscreen` provided was that it selected the resolution closest to the current size of the window so it was removed since this behaviour can be replicated via the new `VideoModeSelection::Specific` if necessary. ## Out of scope WindowResolution and scale factor act strangely in exclusive fullscreen, this PR doesn't address it or regress it. ## Testing - Tested on Windows 11 and macOS 12.7 - Linux untested ## Migration Guide `WindowMode::SizedFullscreen(MonitorSelection)` and `WindowMode::Fullscreen(MonitorSelection)` has become `WindowMode::Fullscreen(MonitorSelection, VideoModeSelection)`. Previously, the VideoMode was selected based on the closest resolution to the current window size for SizedFullscreen and the largest resolution for Fullscreen. It is possible to replicate that behaviour by searching `Monitor::video_modes` and selecting it with `VideoModeSelection::Specific(VideoMode)` but it is recommended to use `VideoModeSelection::Current` as the default video mode when entering fullscreen.
63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
//! a test that confirms that 'bevy' does not panic while changing from Windowed to Fullscreen when viewport is set
|
|
|
|
use bevy::{prelude::*, render::camera::Viewport, window::WindowMode};
|
|
|
|
//Having a viewport set to the same size as a window used to cause panic on some occasions when switching to Fullscreen
|
|
const WINDOW_WIDTH: f32 = 1366.0;
|
|
const WINDOW_HEIGHT: f32 = 768.0;
|
|
|
|
fn main() {
|
|
//Specify Window Size.
|
|
let window = Window {
|
|
resolution: (WINDOW_WIDTH, WINDOW_HEIGHT).into(),
|
|
..default()
|
|
};
|
|
let primary_window = Some(window);
|
|
|
|
App::new()
|
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
|
primary_window,
|
|
..default()
|
|
}))
|
|
.add_systems(Startup, startup)
|
|
.add_systems(Update, toggle_window_mode)
|
|
.run();
|
|
}
|
|
|
|
fn startup(mut cmds: Commands) {
|
|
//Match viewport to Window size.
|
|
let physical_position = UVec2::new(0, 0);
|
|
let physical_size = Vec2::new(WINDOW_WIDTH, WINDOW_HEIGHT).as_uvec2();
|
|
let viewport = Some(Viewport {
|
|
physical_position,
|
|
physical_size,
|
|
..default()
|
|
});
|
|
|
|
cmds.spawn(Camera2d).insert(Camera {
|
|
viewport,
|
|
..default()
|
|
});
|
|
}
|
|
|
|
fn toggle_window_mode(mut qry_window: Query<&mut Window>) {
|
|
let Ok(mut window) = qry_window.single_mut() else {
|
|
return;
|
|
};
|
|
|
|
window.mode = match window.mode {
|
|
WindowMode::Windowed => {
|
|
//it takes a while for the window to change from windowed to fullscreen and back
|
|
std::thread::sleep(std::time::Duration::from_secs(4));
|
|
WindowMode::Fullscreen(
|
|
MonitorSelection::Entity(entity),
|
|
VideoModeSelection::Current,
|
|
)
|
|
}
|
|
_ => {
|
|
std::thread::sleep(std::time::Duration::from_secs(4));
|
|
WindowMode::Windowed
|
|
}
|
|
};
|
|
}
|