Add exclusive fullscreen
This commit is contained in:
parent
2a255affe4
commit
b50a60755a
3 changed files with 69 additions and 2 deletions
|
|
@ -58,6 +58,7 @@ impl System for DisplaySettings {
|
||||||
for mode in [
|
for mode in [
|
||||||
WindowMode::Windowed,
|
WindowMode::Windowed,
|
||||||
WindowMode::BorderlessFullscreen,
|
WindowMode::BorderlessFullscreen,
|
||||||
|
WindowMode::ExclusiveFullscreen,
|
||||||
] {
|
] {
|
||||||
ui.selectable_value(
|
ui.selectable_value(
|
||||||
&mut state.selected_fullscreen_mode,
|
&mut state.selected_fullscreen_mode,
|
||||||
|
|
@ -88,5 +89,6 @@ fn window_mode_label(mode: WindowMode) -> &'static str {
|
||||||
match mode {
|
match mode {
|
||||||
WindowMode::Windowed => "Windowed",
|
WindowMode::Windowed => "Windowed",
|
||||||
WindowMode::BorderlessFullscreen => "Borderless Fullscreen",
|
WindowMode::BorderlessFullscreen => "Borderless Fullscreen",
|
||||||
|
WindowMode::ExclusiveFullscreen => "Exclusive Fullscreen",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,5 @@ winit = "0.30.12"
|
||||||
raidillon_core = { path = "../core" }
|
raidillon_core = { path = "../core" }
|
||||||
raidillon_assets = { path = "../asset" }
|
raidillon_assets = { path = "../asset" }
|
||||||
glam = "0.30.5"
|
glam = "0.30.5"
|
||||||
serde = "1.0.228"
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
toml = "0.9.8"
|
toml = "0.9.8"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use winit::dpi::LogicalSize;
|
use winit::monitor::{MonitorHandle, VideoModeHandle};
|
||||||
use winit::window::{Fullscreen, Window};
|
use winit::window::{Fullscreen, Window};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
@ -19,6 +19,7 @@ pub fn default_config_path() -> PathBuf {
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum WindowMode {
|
pub enum WindowMode {
|
||||||
BorderlessFullscreen,
|
BorderlessFullscreen,
|
||||||
|
ExclusiveFullscreen,
|
||||||
#[default]
|
#[default]
|
||||||
Windowed,
|
Windowed,
|
||||||
}
|
}
|
||||||
|
|
@ -93,9 +94,73 @@ impl DisplaySettings {
|
||||||
let monitor = window.current_monitor().or_else(|| window.primary_monitor());
|
let monitor = window.current_monitor().or_else(|| window.primary_monitor());
|
||||||
window.set_fullscreen(Some(Fullscreen::Borderless(monitor)));
|
window.set_fullscreen(Some(Fullscreen::Borderless(monitor)));
|
||||||
}
|
}
|
||||||
|
WindowMode::ExclusiveFullscreen => {
|
||||||
|
let monitor = window.current_monitor().or_else(|| window.primary_monitor());
|
||||||
|
match monitor {
|
||||||
|
Some(monitor) => {
|
||||||
|
if let Some(video_mode) = pick_best_video_mode(&monitor) {
|
||||||
|
window.set_fullscreen(Some(Fullscreen::Exclusive(video_mode)));
|
||||||
|
} else {
|
||||||
|
// fallback to borderless
|
||||||
|
window.set_fullscreen(Some(Fullscreen::Borderless(Some(monitor))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// no monitor info, fallback to windowed
|
||||||
|
window.set_fullscreen(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
WindowMode::Windowed => {
|
WindowMode::Windowed => {
|
||||||
window.set_fullscreen(None);
|
window.set_fullscreen(None);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pick_best_video_mode(monitor: &MonitorHandle) -> Option<VideoModeHandle> {
|
||||||
|
let target_size = monitor.size();
|
||||||
|
|
||||||
|
let mut best_native: Option<VideoModeHandle> = None;
|
||||||
|
let mut best_any: Option<VideoModeHandle> = None;
|
||||||
|
|
||||||
|
for mode in monitor.video_modes() {
|
||||||
|
if mode.size() == target_size {
|
||||||
|
let replace = match best_native.as_ref() {
|
||||||
|
None => true,
|
||||||
|
Some(best) => {
|
||||||
|
(mode.refresh_rate_millihertz(), mode.bit_depth())
|
||||||
|
> (best.refresh_rate_millihertz(), best.bit_depth())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if replace {
|
||||||
|
best_native = Some(mode.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let replace = match best_any.as_ref() {
|
||||||
|
None => true,
|
||||||
|
Some(best) => is_better_video_mode(&mode, best),
|
||||||
|
};
|
||||||
|
if replace {
|
||||||
|
best_any = Some(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
best_native.or(best_any)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_better_video_mode(a: &VideoModeHandle, b: &VideoModeHandle) -> bool {
|
||||||
|
let a_size = a.size();
|
||||||
|
let b_size = b.size();
|
||||||
|
let a_area = u64::from(a_size.width) * u64::from(a_size.height);
|
||||||
|
let b_area = u64::from(b_size.width) * u64::from(b_size.height);
|
||||||
|
|
||||||
|
match a_area.cmp(&b_area) {
|
||||||
|
std::cmp::Ordering::Greater => true,
|
||||||
|
std::cmp::Ordering::Less => false,
|
||||||
|
std::cmp::Ordering::Equal => {
|
||||||
|
(a.refresh_rate_millihertz(), a.bit_depth()) > (b.refresh_rate_millihertz(), b.bit_depth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue