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

Added use_dpi setting to WindowDescriptor #1131

Merged
merged 2 commits into from
Dec 28, 2020
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
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,10 @@ path = "examples/window/clear_color.rs"
name = "multiple_windows"
path = "examples/window/multiple_windows.rs"

[[example]]
name = "scale_factor_override"
path = "examples/window/scale_factor_override.rs"

[[example]]
name = "window_settings"
path = "examples/window/window_settings.rs"
Expand Down
41 changes: 32 additions & 9 deletions crates/bevy_ui/src/flex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
mod convert;

use crate::{Node, Style};
use bevy_ecs::{Changed, Entity, Query, Res, ResMut, With, Without};
use bevy_app::{EventReader, Events};
use bevy_ecs::{Changed, Entity, Local, Query, QueryFilter, Res, ResMut, With, Without};
use bevy_math::Vec2;
use bevy_text::CalculatedSize;
use bevy_transform::prelude::{Children, Parent, Transform};
use bevy_utils::HashMap;
use bevy_window::{Window, WindowId, Windows};
use bevy_window::{Window, WindowId, WindowScaleFactorChanged, Windows};
use std::fmt;
use stretch::{number::Number, Stretch};

Expand Down Expand Up @@ -161,11 +162,15 @@ impl FlexSurface {
unsafe impl Send for FlexSurface {}
unsafe impl Sync for FlexSurface {}

#[allow(clippy::too_many_arguments)]
pub fn flex_node_system(
windows: Res<Windows>,
mut scale_factor_reader: Local<EventReader<WindowScaleFactorChanged>>,
scale_factor_events: Res<Events<WindowScaleFactorChanged>>,
mut flex_surface: ResMut<FlexSurface>,
root_node_query: Query<Entity, (With<Node>, Without<Parent>)>,
node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With<Node>, Changed<Style>)>,
full_node_query: Query<(Entity, &Style, Option<&CalculatedSize>), With<Node>>,
changed_size_query: Query<
(Entity, &Style, &CalculatedSize),
(With<Node>, Changed<CalculatedSize>),
Expand All @@ -185,13 +190,31 @@ pub fn flex_node_system(
1.
};

// update changed nodes
for (entity, style, calculated_size) in node_query.iter() {
// TODO: remove node from old hierarchy if its root has changed
if let Some(calculated_size) = calculated_size {
flex_surface.upsert_leaf(entity, &style, *calculated_size, logical_to_physical_factor);
} else {
flex_surface.upsert_node(entity, &style, logical_to_physical_factor);
if scale_factor_reader.latest(&scale_factor_events).is_some() {
update_changed(
&mut *flex_surface,
logical_to_physical_factor,
full_node_query,
);
} else {
update_changed(&mut *flex_surface, logical_to_physical_factor, node_query);
}

fn update_changed<F>(
flex_surface: &mut FlexSurface,
scaling_factor: f64,
query: Query<(Entity, &Style, Option<&CalculatedSize>), F>,
) where
F: QueryFilter,
{
// update changed nodes
for (entity, style, calculated_size) in query.iter() {
// TODO: remove node from old hierarchy if its root has changed
if let Some(calculated_size) = calculated_size {
flex_surface.upsert_leaf(entity, &style, *calculated_size, scaling_factor);
} else {
flex_surface.upsert_node(entity, &style, scaling_factor);
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions crates/bevy_window/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,16 @@ pub struct WindowFocused {
pub id: WindowId,
pub focused: bool,
}

/// An event that indicates a window's scale factor has changed.
#[derive(Debug, Clone)]
pub struct WindowScaleFactorChanged {
pub id: WindowId,
pub scale_factor: f64,
}
/// An event that indicates a window's OS-reported scale factor has changed.
#[derive(Debug, Clone)]
pub struct WindowBackendScaleFactorChanged {
pub id: WindowId,
pub scale_factor: f64,
}
2 changes: 2 additions & 0 deletions crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ impl Plugin for WindowPlugin {
.add_event::<CursorLeft>()
.add_event::<ReceivedCharacter>()
.add_event::<WindowFocused>()
.add_event::<WindowScaleFactorChanged>()
.add_event::<WindowBackendScaleFactorChanged>()
.init_resource::<Windows>();

if self.add_primary_window {
Expand Down
60 changes: 51 additions & 9 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ pub struct Window {
requested_height: f32,
physical_width: u32,
physical_height: u32,
scale_factor: f64,
scale_factor_override: Option<f64>,
backend_scale_factor: f64,
title: String,
vsync: bool,
resizable: bool,
Expand All @@ -77,8 +78,12 @@ pub enum WindowCommand {
SetTitle {
title: String,
},
SetScaleFactor {
scale_factor: f64,
},
SetResolution {
resolution: (f32, f32),
logical_resolution: (f32, f32),
scale_factor: f64,
},
SetVsync {
vsync: bool,
Expand Down Expand Up @@ -129,7 +134,8 @@ impl Window {
requested_height: window_descriptor.height,
physical_width,
physical_height,
scale_factor,
scale_factor_override: window_descriptor.scale_factor_override,
backend_scale_factor: scale_factor,
title: window_descriptor.title.clone(),
vsync: window_descriptor.vsync,
resizable: window_descriptor.resizable,
Expand All @@ -152,13 +158,13 @@ impl Window {
/// The current logical width of the window's client area.
#[inline]
pub fn width(&self) -> f32 {
(self.physical_width as f64 / self.scale_factor) as f32
(self.physical_width as f64 / self.scale_factor()) as f32
}

/// The current logical height of the window's client area.
#[inline]
pub fn height(&self) -> f32 {
(self.physical_height as f64 / self.scale_factor) as f32
(self.physical_height as f64 / self.scale_factor()) as f32
}

/// The requested window client area width in logical pixels from window
Expand Down Expand Up @@ -201,18 +207,40 @@ impl Window {

/// 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 {
resolution: (self.requested_width, self.requested_height),
logical_resolution: (self.requested_width, self.requested_height),
scale_factor: self.scale_factor(),
});
}

/// Override the os-reported scaling factor
#[allow(clippy::float_cmp)]
pub fn set_scale_factor_override(&mut self, scale_factor: Option<f64>) {
if self.scale_factor_override == scale_factor {
return;
}

self.scale_factor_override = scale_factor;
self.command_queue.push(WindowCommand::SetScaleFactor {
scale_factor: self.scale_factor(),
});
self.command_queue.push(WindowCommand::SetResolution {
logical_resolution: (self.requested_width, self.requested_height),
scale_factor: self.scale_factor(),
});
}

#[allow(missing_docs)]
#[inline]
pub fn update_scale_factor_from_backend(&mut self, scale_factor: f64) {
self.scale_factor = scale_factor;
self.backend_scale_factor = scale_factor;
}

#[allow(missing_docs)]
Expand All @@ -225,9 +253,21 @@ impl Window {
/// The ratio of physical pixels to logical pixels
///
/// `physical_pixels = logical_pixels * scale_factor`
#[inline]
pub fn scale_factor(&self) -> f64 {
self.scale_factor
self.scale_factor_override
.unwrap_or(self.backend_scale_factor)
}

/// The window scale factor as reported by the window backend.
/// This value is unaffected by scale_factor_override.
#[inline]
pub fn backend_scale_factor(&self) -> f64 {
self.backend_scale_factor
}

#[inline]
pub fn scale_factor_override(&self) -> Option<f64> {
self.scale_factor_override
}

#[inline]
Expand Down Expand Up @@ -335,6 +375,7 @@ impl Window {
pub struct WindowDescriptor {
pub width: f32,
pub height: f32,
pub scale_factor_override: Option<f64>,
pub title: String,
pub vsync: bool,
pub resizable: bool,
Expand All @@ -352,6 +393,7 @@ impl Default for WindowDescriptor {
title: "bevy".to_string(),
width: 1280.,
height: 720.,
scale_factor_override: None,
vsync: true,
resizable: true,
decorations: true,
Expand Down
59 changes: 49 additions & 10 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ use bevy_ecs::{IntoSystem, Resources, World};
use bevy_math::Vec2;
use bevy_utils::tracing::{error, trace, warn};
use bevy_window::{
CreateWindow, CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, WindowCloseRequested,
WindowCreated, WindowFocused, WindowResized, Windows,
CreateWindow, CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter,
WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused,
WindowResized, WindowScaleFactorChanged, Windows,
};
use winit::{
event::{self, DeviceEvent, Event, WindowEvent},
Expand Down Expand Up @@ -76,14 +77,21 @@ fn change_window(_: &mut World, resources: &mut Resources) {
let window = winit_windows.get_window(id).unwrap();
window.set_title(&title);
}
bevy_window::WindowCommand::SetScaleFactor { scale_factor } => {
let mut window_dpi_changed_events = resources
.get_mut::<Events<WindowScaleFactorChanged>>()
.unwrap();
window_dpi_changed_events.send(WindowScaleFactorChanged { id, scale_factor });
}
bevy_window::WindowCommand::SetResolution {
resolution: (logical_width, logical_height),
logical_resolution: (width, height),
scale_factor,
} => {
let window = winit_windows.get_window(id).unwrap();
window.set_inner_size(winit::dpi::LogicalSize::new(
logical_width,
logical_height,
));
window.set_inner_size(
winit::dpi::LogicalSize::new(width, height)
.to_physical::<f64>(scale_factor),
);
}
bevy_window::WindowCommand::SetVsync { .. } => (),
bevy_window::WindowCommand::SetResizable { resizable } => {
Expand Down Expand Up @@ -342,13 +350,44 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
scale_factor,
new_inner_size,
} => {
let mut backend_scale_factor_change_events = app
.resources
.get_mut::<Events<WindowBackendScaleFactorChanged>>()
.unwrap();
backend_scale_factor_change_events.send(WindowBackendScaleFactorChanged {
id: window_id,
scale_factor,
});
#[allow(clippy::float_cmp)]
if window.scale_factor() != scale_factor {
let mut scale_factor_change_events = app
.resources
.get_mut::<Events<WindowScaleFactorChanged>>()
.unwrap();

scale_factor_change_events.send(WindowScaleFactorChanged {
id: window_id,
scale_factor,
});
}

window.update_scale_factor_from_backend(scale_factor);

if window.physical_width() != new_inner_size.width
|| window.physical_height() != new_inner_size.height
{
let mut resize_events =
app.resources.get_mut::<Events<WindowResized>>().unwrap();
resize_events.send(WindowResized {
id: window_id,
width: window.width(),
height: window.height(),
});
}
window.update_actual_size_from_backend(
new_inner_size.width,
new_inner_size.height,
);
window.update_scale_factor_from_backend(scale_factor);
// should we send a resize event to indicate the change in
// logical size?
}
WindowEvent::Focused(focused) => {
let mut focused_events =
Expand Down
25 changes: 18 additions & 7 deletions crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,24 @@ impl WinitWindows {
false => get_best_videomode(&event_loop.primary_monitor().unwrap()),
}),
)),
_ => winit_window_builder
.with_inner_size(winit::dpi::LogicalSize::new(
window_descriptor.width,
window_descriptor.height,
))
.with_resizable(window_descriptor.resizable)
.with_decorations(window_descriptor.decorations),
_ => {
let WindowDescriptor {
width,
height,
scale_factor_override,
..
} = window_descriptor;
if let Some(sf) = scale_factor_override {
winit_window_builder.with_inner_size(
winit::dpi::LogicalSize::new(*width, *height).to_physical::<f64>(*sf),
)
} else {
winit_window_builder
.with_inner_size(winit::dpi::LogicalSize::new(*width, *height))
}
}
.with_resizable(window_descriptor.resizable)
.with_decorations(window_descriptor.decorations),
};

#[allow(unused_mut)]
Expand Down
Loading