Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ pub struct Window {
pub height: u32,
pub title: String,
pub vsync: bool,
pub resizable: bool,
pub mode: WindowMode,
}

/// Defines the way a window is displayed
/// The use_size option that is used in the Fullscreen variant
/// defines whether a videomode is chosen that best fits the width and height
/// in the Window structure, or if these are ignored.
/// E.g. when use_size is set to false the best video mode possible is chosen.
#[derive(Debug, Clone, Copy)]
pub enum WindowMode {
Windowed,
BorderlessFullscreen,
Fullscreen { use_size: bool },
}

impl Window {
Expand All @@ -44,6 +58,8 @@ impl Window {
width: window_descriptor.width,
title: window_descriptor.title.clone(),
vsync: window_descriptor.vsync,
resizable: window_descriptor.resizable,
mode: window_descriptor.mode,
}
}
}
Expand All @@ -54,6 +70,8 @@ pub struct WindowDescriptor {
pub height: u32,
pub title: String,
pub vsync: bool,
pub resizable: bool,
pub mode: WindowMode,
}

impl Default for WindowDescriptor {
Expand All @@ -63,6 +81,8 @@ impl Default for WindowDescriptor {
width: 1280,
height: 720,
vsync: true,
resizable: true,
mode: WindowMode::Windowed,
}
}
}
71 changes: 65 additions & 6 deletions crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_window::{Window, WindowId};
use bevy_window::{Window, WindowId, WindowMode};
use std::collections::HashMap;

#[derive(Default)]
Expand All @@ -15,18 +15,31 @@ impl WinitWindows {
window: &Window,
) {
#[cfg(target_os = "windows")]
let winit_window_builder = {
let mut winit_window_builder = {
use winit::platform::windows::WindowBuilderExtWindows;
winit::window::WindowBuilder::new()
.with_drag_and_drop(false)
winit::window::WindowBuilder::new().with_drag_and_drop(false)
};

#[cfg(not(target_os = "windows"))]
let winit_window_builder = winit::window::WindowBuilder::new();
let mut winit_window_builder = winit::window::WindowBuilder::new();

winit_window_builder = match window.mode {
WindowMode::BorderlessFullscreen => winit_window_builder.with_fullscreen(Some(
winit::window::Fullscreen::Borderless(event_loop.primary_monitor()),
)),
WindowMode::Fullscreen { use_size } => winit_window_builder.with_fullscreen(Some(
winit::window::Fullscreen::Exclusive(match use_size {
true => get_fitting_videomode(&event_loop.primary_monitor(), &window),
false => get_best_videomode(&event_loop.primary_monitor()),
}),
)),
_ => winit_window_builder
.with_inner_size(winit::dpi::PhysicalSize::new(window.width, window.height))
.with_resizable(window.resizable),
};

let winit_window = winit_window_builder
.with_title(&window.title)
.with_inner_size(winit::dpi::PhysicalSize::new(window.width, window.height))
.build(&event_loop)
.unwrap();

Expand All @@ -46,3 +59,49 @@ impl WinitWindows {
self.winit_to_window_id.get(&id).cloned()
}
}
fn get_fitting_videomode(
monitor: &winit::monitor::MonitorHandle,
window: &Window,
) -> winit::monitor::VideoMode {
let mut modes = monitor.video_modes().collect::<Vec<_>>();

fn abs_diff(a: u32, b: u32) -> u32 {
if a > b {
return a - b;
}
b - a
}

modes.sort_by(|a, b| {
use std::cmp::Ordering::*;
match abs_diff(a.size().width, window.width).cmp(&abs_diff(b.size().width, window.width)) {
Equal => {
match abs_diff(a.size().height, window.height)
.cmp(&abs_diff(b.size().height, window.height))
{
Equal => b.refresh_rate().cmp(&a.refresh_rate()),
default => default,
}
}
default => default,
}
});

modes.first().unwrap().clone()
}

fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::monitor::VideoMode {
let mut modes = monitor.video_modes().collect::<Vec<_>>();
modes.sort_by(|a, b| {
use std::cmp::Ordering::*;
match b.size().width.cmp(&a.size().width) {
Equal => match b.size().height.cmp(&a.size().height) {
Equal => b.refresh_rate().cmp(&a.refresh_rate()),
default => default,
},
default => default,
}
});

modes.first().unwrap().clone()
}
1 change: 1 addition & 0 deletions examples/window/multiple_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn setup(
height: 600,
vsync: false,
title: "second window".to_string(),
..Default::default()
},
});

Expand Down
4 changes: 4 additions & 0 deletions examples/window/window_settings.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use bevy::prelude::*;
use bevy_window::WindowMode;

/// This example illustrates how to customize the default window settings
fn main() {
Expand All @@ -8,6 +9,9 @@ fn main() {
width: 300,
height: 300,
vsync: true,
resizable: false,
mode: WindowMode::Fullscreen { use_size: false },
..Default::default()
})
.add_default_plugins()
.run();
Expand Down