Skip to content

Commit d65fbd7

Browse files
Fix scale factor for cursor position (#2932)
# Objective - Fixes #2501 - Builds up on #2639 taking #2639 (comment) into account ## Solution - keep the physical cursor position in `Window`, and expose it. - still convert to logical position in event, and when getting `cursor_position` Co-authored-by: Ahmed Charles <acharles@outlook.com>
1 parent 099386f commit d65fbd7

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

crates/bevy_window/src/window.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_math::{IVec2, Vec2};
1+
use bevy_math::{DVec2, IVec2, Vec2};
22
use bevy_utils::{tracing::warn, Uuid};
33

44
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -122,7 +122,7 @@ pub struct Window {
122122
decorations: bool,
123123
cursor_visible: bool,
124124
cursor_locked: bool,
125-
cursor_position: Option<Vec2>,
125+
physical_cursor_position: Option<DVec2>,
126126
focused: bool,
127127
mode: WindowMode,
128128
#[cfg(target_arch = "wasm32")]
@@ -215,7 +215,7 @@ impl Window {
215215
decorations: window_descriptor.decorations,
216216
cursor_visible: window_descriptor.cursor_visible,
217217
cursor_locked: window_descriptor.cursor_locked,
218-
cursor_position: None,
218+
physical_cursor_position: None,
219219
focused: true,
220220
mode: window_descriptor.mode,
221221
#[cfg(target_arch = "wasm32")]
@@ -466,10 +466,18 @@ impl Window {
466466
});
467467
}
468468

469+
/// The current mouse position, in physical pixels.
470+
#[inline]
471+
pub fn physical_cursor_position(&self) -> Option<DVec2> {
472+
self.physical_cursor_position
473+
}
474+
475+
/// The current mouse position, in logical pixels, taking into account the screen scale factor.
469476
#[inline]
470477
#[doc(alias = "mouse position")]
471478
pub fn cursor_position(&self) -> Option<Vec2> {
472-
self.cursor_position
479+
self.physical_cursor_position
480+
.map(|p| (p / self.scale_factor()).as_vec2())
473481
}
474482

475483
pub fn set_cursor_position(&mut self, position: Vec2) {
@@ -485,8 +493,8 @@ impl Window {
485493

486494
#[allow(missing_docs)]
487495
#[inline]
488-
pub fn update_cursor_position_from_backend(&mut self, cursor_position: Option<Vec2>) {
489-
self.cursor_position = cursor_position;
496+
pub fn update_cursor_physical_position_from_backend(&mut self, cursor_position: Option<DVec2>) {
497+
self.physical_cursor_position = cursor_position;
490498
}
491499

492500
#[inline]

crates/bevy_winit/src/lib.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use winit_windows::*;
1212

1313
use bevy_app::{App, AppExit, CoreStage, Events, ManualEventReader, Plugin};
1414
use bevy_ecs::{system::IntoExclusiveSystem, world::World};
15-
use bevy_math::{ivec2, Vec2};
15+
use bevy_math::{ivec2, DVec2, Vec2};
1616
use bevy_utils::tracing::{error, trace, warn};
1717
use bevy_window::{
1818
CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
@@ -303,20 +303,18 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
303303
let mut cursor_moved_events =
304304
world.get_resource_mut::<Events<CursorMoved>>().unwrap();
305305
let winit_window = winit_windows.get_window(window_id).unwrap();
306-
let position = position.to_logical(winit_window.scale_factor());
307-
let inner_size = winit_window
308-
.inner_size()
309-
.to_logical::<f32>(winit_window.scale_factor());
306+
let inner_size = winit_window.inner_size();
310307

311308
// move origin to bottom left
312-
let y_position = inner_size.height - position.y;
309+
let y_position = inner_size.height as f64 - position.y;
313310

314-
let position = Vec2::new(position.x, y_position);
315-
window.update_cursor_position_from_backend(Some(position));
311+
let physical_position = DVec2::new(position.x, y_position);
312+
window
313+
.update_cursor_physical_position_from_backend(Some(physical_position));
316314

317315
cursor_moved_events.send(CursorMoved {
318316
id: window_id,
319-
position,
317+
position: (physical_position / window.scale_factor()).as_vec2(),
320318
});
321319
}
322320
WindowEvent::CursorEntered { .. } => {
@@ -327,7 +325,7 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
327325
WindowEvent::CursorLeft { .. } => {
328326
let mut cursor_left_events =
329327
world.get_resource_mut::<Events<CursorLeft>>().unwrap();
330-
window.update_cursor_position_from_backend(None);
328+
window.update_cursor_physical_position_from_backend(None);
331329
cursor_left_events.send(CursorLeft { id: window_id });
332330
}
333331
WindowEvent::MouseInput { state, button, .. } => {
@@ -363,8 +361,7 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
363361
let mut touch_input_events =
364362
world.get_resource_mut::<Events<TouchInput>>().unwrap();
365363

366-
let winit_window = winit_windows.get_window(window_id).unwrap();
367-
let mut location = touch.location.to_logical(winit_window.scale_factor());
364+
let mut location = touch.location.to_logical(window.scale_factor());
368365

369366
// On a mobile window, the start is from the top while on PC/Linux/OSX from
370367
// bottom

0 commit comments

Comments
 (0)