Skip to content

Commit 6b004f7

Browse files
authored
switch winit size to logical to be dpi independent (#947)
* switch winit size to logical * make scale factor available from bevy_window
1 parent 4cd3dd7 commit 6b004f7

File tree

4 files changed

+67
-32
lines changed

4 files changed

+67
-32
lines changed

crates/bevy_window/src/window.rs

+12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub struct Window {
4646
#[cfg(target_arch = "wasm32")]
4747
pub canvas: Option<String>,
4848
command_queue: Vec<WindowCommand>,
49+
scale_factor: f64,
4950
}
5051

5152
#[derive(Debug)]
@@ -110,6 +111,7 @@ impl Window {
110111
#[cfg(target_arch = "wasm32")]
111112
canvas: window_descriptor.canvas.clone(),
112113
command_queue: Vec::new(),
114+
scale_factor: 1.0,
113115
}
114116
}
115117

@@ -141,6 +143,16 @@ impl Window {
141143
self.height = height;
142144
}
143145

146+
#[doc(hidden)]
147+
pub fn update_scale_factor_from_backend(&mut self, scale_factor: f64) {
148+
self.scale_factor = scale_factor;
149+
}
150+
151+
#[inline]
152+
pub fn scale_factor(&self) -> f64 {
153+
self.scale_factor
154+
}
155+
144156
#[inline]
145157
pub fn title(&self) -> &str {
146158
&self.title

crates/bevy_winit/src/converters.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut
3030
}
3131
}
3232

33-
pub fn convert_touch_input(touch_input: winit::event::Touch) -> TouchInput {
33+
pub fn convert_touch_input(
34+
touch_input: winit::event::Touch,
35+
location: winit::dpi::LogicalPosition<f32>,
36+
) -> TouchInput {
3437
TouchInput {
3538
phase: match touch_input.phase {
3639
winit::event::TouchPhase::Started => TouchPhase::Started,
3740
winit::event::TouchPhase::Moved => TouchPhase::Moved,
3841
winit::event::TouchPhase::Ended => TouchPhase::Ended,
3942
winit::event::TouchPhase::Cancelled => TouchPhase::Cancelled,
4043
},
41-
position: Vec2::new(touch_input.location.x as f32, touch_input.location.y as f32),
44+
position: Vec2::new(location.x as f32, location.y as f32),
4245
force: touch_input.force.map(|f| match f {
4346
winit::event::Force::Calibrated {
4447
force,

crates/bevy_winit/src/lib.rs

+46-28
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn change_window(_: &mut World, resources: &mut Resources) {
7373
}
7474
bevy_window::WindowCommand::SetResolution { width, height } => {
7575
let window = winit_windows.get_window(id).unwrap();
76-
window.set_inner_size(winit::dpi::PhysicalSize::new(width, height));
76+
window.set_inner_size(winit::dpi::LogicalSize::new(width, height));
7777
}
7878
bevy_window::WindowCommand::SetVsync { .. } => (),
7979
bevy_window::WindowCommand::SetResizable { resizable } => {
@@ -97,7 +97,7 @@ fn change_window(_: &mut World, resources: &mut Resources) {
9797
bevy_window::WindowCommand::SetCursorPosition { x, y } => {
9898
let window = winit_windows.get_window(id).unwrap();
9999
window
100-
.set_cursor_position(winit::dpi::PhysicalPosition::new(x, y))
100+
.set_cursor_position(winit::dpi::LogicalPosition::new(x, y))
101101
.unwrap_or_else(|e| error!("Unable to set cursor position: {}", e));
102102
}
103103
}
@@ -184,29 +184,28 @@ pub fn winit_runner(mut app: App) {
184184
}
185185

186186
match event {
187-
event::Event::WindowEvent {
188-
event: WindowEvent::Resized(size),
189-
window_id: winit_window_id,
190-
..
191-
} => {
192-
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
193-
let mut windows = app.resources.get_mut::<Windows>().unwrap();
194-
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
195-
let window = windows.get_mut(window_id).unwrap();
196-
window.update_resolution_from_backend(size.width, size.height);
197-
198-
let mut resize_events = app.resources.get_mut::<Events<WindowResized>>().unwrap();
199-
resize_events.send(WindowResized {
200-
id: window_id,
201-
height: window.height() as usize,
202-
width: window.width() as usize,
203-
});
204-
}
205187
event::Event::WindowEvent {
206188
event,
207189
window_id: winit_window_id,
208190
..
209191
} => match event {
192+
WindowEvent::Resized(size) => {
193+
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
194+
let mut windows = app.resources.get_mut::<Windows>().unwrap();
195+
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
196+
let winit_window = winit_windows.get_window(window_id).unwrap();
197+
let window = windows.get_mut(window_id).unwrap();
198+
let size = size.to_logical(winit_window.scale_factor());
199+
window.update_resolution_from_backend(size.width, size.height);
200+
201+
let mut resize_events =
202+
app.resources.get_mut::<Events<WindowResized>>().unwrap();
203+
resize_events.send(WindowResized {
204+
id: window_id,
205+
height: window.height() as usize,
206+
width: window.width() as usize,
207+
});
208+
}
210209
WindowEvent::CloseRequested => {
211210
let mut window_close_requested_events = app
212211
.resources
@@ -227,12 +226,13 @@ pub fn winit_runner(mut app: App) {
227226
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
228227
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
229228
let window = winit_windows.get_window(window_id).unwrap();
230-
let inner_size = window.inner_size();
229+
let position = position.to_logical(window.scale_factor());
230+
let inner_size = window.inner_size().to_logical::<f32>(window.scale_factor());
231231
// move origin to bottom left
232-
let y_position = inner_size.height as f32 - position.y as f32;
232+
let y_position = inner_size.height - position.y;
233233
cursor_moved_events.send(CursorMoved {
234234
id: window_id,
235-
position: Vec2::new(position.x as f32, y_position as f32),
235+
position: Vec2::new(position.x, y_position),
236236
});
237237
}
238238
WindowEvent::MouseInput { state, button, .. } => {
@@ -263,16 +263,22 @@ pub fn winit_runner(mut app: App) {
263263
});
264264
}
265265
},
266-
WindowEvent::Touch(mut touch) => {
266+
WindowEvent::Touch(touch) => {
267267
let mut touch_input_events =
268268
app.resources.get_mut::<Events<TouchInput>>().unwrap();
269+
270+
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
269271
let windows = app.resources.get_mut::<Windows>().unwrap();
272+
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
273+
let winit_window = winit_windows.get_window(window_id).unwrap();
274+
let mut location = touch.location.to_logical(winit_window.scale_factor());
275+
270276
// FIXME?: On Android window start is top while on PC/Linux/OSX on bottom
271277
if cfg!(target_os = "android") {
272278
let window_height = windows.get_primary().unwrap().height();
273-
touch.location.y = window_height as f64 - touch.location.y;
279+
location.y = window_height as f32 - location.y;
274280
}
275-
touch_input_events.send(converters::convert_touch_input(touch));
281+
touch_input_events.send(converters::convert_touch_input(touch, location));
276282
}
277283
WindowEvent::ReceivedCharacter(c) => {
278284
let mut char_input_events = app
@@ -288,6 +294,18 @@ pub fn winit_runner(mut app: App) {
288294
char: c,
289295
})
290296
}
297+
WindowEvent::ScaleFactorChanged {
298+
scale_factor,
299+
new_inner_size,
300+
} => {
301+
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
302+
let mut windows = app.resources.get_mut::<Windows>().unwrap();
303+
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
304+
let window = windows.get_mut(window_id).unwrap();
305+
let size = new_inner_size.to_logical(scale_factor);
306+
window.update_scale_factor_from_backend(scale_factor);
307+
window.update_resolution_from_backend(size.width, size.height);
308+
}
291309
_ => {}
292310
},
293311
event::Event::DeviceEvent { ref event, .. } => {
@@ -327,8 +345,8 @@ fn handle_create_window_events(
327345
let create_window_events = resources.get::<Events<CreateWindow>>().unwrap();
328346
let mut window_created_events = resources.get_mut::<Events<WindowCreated>>().unwrap();
329347
for create_window_event in create_window_event_reader.iter(&create_window_events) {
330-
let window = Window::new(create_window_event.id, &create_window_event.descriptor);
331-
winit_windows.create_window(event_loop, &window);
348+
let mut window = Window::new(create_window_event.id, &create_window_event.descriptor);
349+
winit_windows.create_window(event_loop, &mut window);
332350
let window_id = window.id();
333351
windows.add(window);
334352
window_created_events.send(WindowCreated { id: window_id });

crates/bevy_winit/src/winit_windows.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ impl WinitWindows {
1212
pub fn create_window(
1313
&mut self,
1414
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
15-
window: &Window,
15+
window: &mut Window,
1616
) {
1717
#[cfg(target_os = "windows")]
1818
let mut winit_window_builder = {
@@ -38,7 +38,7 @@ impl WinitWindows {
3838
}),
3939
)),
4040
_ => winit_window_builder
41-
.with_inner_size(winit::dpi::PhysicalSize::new(
41+
.with_inner_size(winit::dpi::LogicalSize::new(
4242
window.width(),
4343
window.height(),
4444
))
@@ -100,6 +100,8 @@ impl WinitWindows {
100100
}
101101
}
102102

103+
window.update_scale_factor_from_backend(winit_window.scale_factor());
104+
103105
self.windows.insert(winit_window.id(), winit_window);
104106
}
105107

0 commit comments

Comments
 (0)