Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Add Window Resize Constraints #1409

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 19 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
46 changes: 46 additions & 0 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,31 @@ impl Default for WindowId {
}
}

/// The size limits on a window.
/// These values are measured in logical pixels, so the user's
/// scale factor does affect the size limits on the window.
/// Please note that if the window is resizable, then when the window is
/// maximized it may have a size outside of these limits. The functionality
/// required to disable maximizing is not yet exposed by winit.
#[derive(Debug, Clone, Copy)]
pub struct WindowResizeConstraints {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small documentation comment here would be nice. Just something like

/// The size limits on a `Window`. These values are in logical pixels, so the user's scale
/// factor does affect the size limits on the `Window`
/// Please note that if the window is resizable, then when the window is maximised it 
/// may have a size outside of these limits. The functionality required to disable maximising
/// is not yet exposed by winit

pub min_width: f32,
pub min_height: f32,
pub max_width: f32,
pub max_height: f32,
}

impl Default for WindowResizeConstraints {
fn default() -> Self {
Self {
min_width: 180.,
min_height: 120.,
max_width: f32::INFINITY,
max_height: f32::INFINITY,
}
}
}

/// An operating system window that can present content and receive user input.
///
/// ## Window Sizes
Expand All @@ -54,6 +79,7 @@ pub struct Window {
requested_height: f32,
physical_width: u32,
physical_height: u32,
resize_constraints: WindowResizeConstraints,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no command to change this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove this or create a command?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably add a command to change it

position: Option<IVec2>,
scale_factor_override: Option<f64>,
backend_scale_factor: f64,
Expand Down Expand Up @@ -113,6 +139,9 @@ pub enum WindowCommand {
SetPosition {
position: IVec2,
},
SetResizeConstraints {
resize_constraints: WindowResizeConstraints,
},
}

/// Defines the way a window is displayed
Expand Down Expand Up @@ -143,6 +172,7 @@ impl Window {
position,
physical_width,
physical_height,
resize_constraints: window_descriptor.resize_constraints,
scale_factor_override: window_descriptor.scale_factor_override,
backend_scale_factor: scale_factor,
title: window_descriptor.title.clone(),
Expand Down Expand Up @@ -208,6 +238,12 @@ impl Window {
self.physical_height
}

/// The window's client resize constraint in logical pixels.
#[inline]
pub fn resize_constraints(&self) -> WindowResizeConstraints {
self.resize_constraints
}

/// The window's client position in physical pixels.
#[inline]
pub fn position(&self) -> Option<IVec2> {
Expand Down Expand Up @@ -248,13 +284,21 @@ impl Window {
.push(WindowCommand::SetPosition { position })
}

/// Modifies the minimum and maximum window bounds for resizing in logical pixels.
#[inline]
pub fn set_resize_constraints(&mut self, resize_constraints: WindowResizeConstraints) {
self.command_queue
.push(WindowCommand::SetResizeConstraints { resize_constraints });
}

/// Request the OS to resize the window such the the client area matches the
/// specified width and height.
#[allow(clippy::float_cmp)]
pub fn set_resolution(&mut self, width: f32, height: f32) {
if self.requested_width == width && self.requested_height == height {
return;
}

self.requested_width = width;
self.requested_height = height;
self.command_queue.push(WindowCommand::SetResolution {
Expand Down Expand Up @@ -424,6 +468,7 @@ impl Window {
pub struct WindowDescriptor {
pub width: f32,
pub height: f32,
pub resize_constraints: WindowResizeConstraints,
pub scale_factor_override: Option<f64>,
pub title: String,
pub vsync: bool,
Expand All @@ -442,6 +487,7 @@ impl Default for WindowDescriptor {
title: "bevy".to_string(),
width: 1280.,
height: 720.,
resize_constraints: WindowResizeConstraints::default(),
scale_factor_override: None,
vsync: true,
resizable: true,
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ x11 = ["winit/x11"]
bevy_app = { path = "../bevy_app", version = "0.4.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
bevy_input = { path = "../bevy_input", version = "0.4.0" }
bevy_log = { path = "../bevy_log", version = "0.4.0" }
bevy_math = { path = "../bevy_math", version = "0.4.0" }
bevy_window = { path = "../bevy_window", version = "0.4.0" }
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
Expand Down
28 changes: 27 additions & 1 deletion crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod converters;
mod utils;
mod winit_config;
mod winit_windows;

Expand All @@ -17,14 +18,16 @@ use bevy_utils::tracing::{error, trace, warn};
use bevy_window::{
CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused,
WindowMoved, WindowResized, WindowScaleFactorChanged, Windows,
WindowMoved, WindowResizeConstraints, WindowResized, WindowScaleFactorChanged, Windows,
};
use winit::{
dpi::PhysicalPosition,
event::{self, DeviceEvent, Event, WindowEvent},
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
};

use crate::utils::check_resize_constraints;
use winit::dpi::LogicalSize;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
Expand Down Expand Up @@ -139,6 +142,29 @@ fn change_window(_: &mut World, resources: &mut Resources) {
y: position[1],
});
}
bevy_window::WindowCommand::SetResizeConstraints { resize_constraints } => {
let window = winit_windows.get_window(id).unwrap();
let WindowResizeConstraints {
min_width,
min_height,
max_width,
max_height,
} = check_resize_constraints(resize_constraints);
let min_inner_size = LogicalSize {
width: min_width,
height: min_height,
};
let max_inner_size = LogicalSize {
width: max_width,
height: max_height,
};
if max_width.is_finite() && max_height.is_finite() {
window.set_min_inner_size(Some(min_inner_size));
window.set_max_inner_size(Some(max_inner_size));
} else {
window.set_min_inner_size(Some(min_inner_size));
}
}
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions crates/bevy_winit/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use bevy_log::warn;
use bevy_window::WindowResizeConstraints;

pub(crate) fn check_resize_constraints(
WindowResizeConstraints {
mut min_width,
mut min_height,
mut max_width,
mut max_height,
}: WindowResizeConstraints,
) -> WindowResizeConstraints {
min_width = min_width.max(1.);
min_height = min_height.max(1.);
if max_width < min_width {
warn!(
"The given maximum width {} is smaller than the minimum width {}",
max_width, min_width
);
max_width = min_width;
}
if max_height < min_height {
warn!(
"The given maximum height {} is smaller than the minimum height {}",
max_height, min_height
);
max_height = min_height;
}
WindowResizeConstraints {
min_width,
min_height,
max_width,
max_height,
}
}
27 changes: 26 additions & 1 deletion crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::utils::check_resize_constraints;
use bevy_math::IVec2;
use bevy_utils::HashMap;
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode, WindowResizeConstraints};
use winit::dpi::LogicalSize;

#[derive(Debug, Default)]
pub struct WinitWindows {
Expand Down Expand Up @@ -59,6 +61,29 @@ impl WinitWindows {
.with_decorations(window_descriptor.decorations),
};

let WindowResizeConstraints {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be tempted to use a 4 tuple here, but I do think this is better code 👍

min_width,
min_height,
max_width,
max_height,
} = check_resize_constraints(window_descriptor.resize_constraints);
let min_inner_size = LogicalSize {
width: min_width,
height: min_height,
};
let max_inner_size = LogicalSize {
width: max_width,
height: max_height,
};

let winit_window_builder = if max_width.is_finite() && max_height.is_finite() {
winit_window_builder
.with_min_inner_size(min_inner_size)
.with_max_inner_size(max_inner_size)
} else {
winit_window_builder.with_min_inner_size(min_inner_size)
};

#[allow(unused_mut)]
let mut winit_window_builder = winit_window_builder.with_title(&window_descriptor.title);

Expand Down