From 2bc48254b865d32ffb33344489ec6ce298d56af1 Mon Sep 17 00:00:00 2001 From: Lynn <62256001+solis-lumine-vorago@users.noreply.github.com> Date: Mon, 12 Feb 2024 19:14:22 +0100 Subject: [PATCH] Add delta to CursorMoved event (#11710) # Objective - Fixes #11695 ## Solution - Added `delta: Option` to `bevy_window::CursorMoved`. `delta` is an `Option` because the `CursorMoved` event does get fired when the cursor was outside the window area in the last frame. In that case there is no cursor position from the last frame to compare with the current cursor position. --- ## Changelog - Added `delta: Option` to `bevy_window::CursorMoved`. ## Migration Guide - You need to add `delta` to any manually created `CursorMoved` struct. --------- Co-authored-by: Kanabenki Co-authored-by: James Liu --- crates/bevy_window/src/event.rs | 12 +++++++++++- crates/bevy_winit/src/lib.rs | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index 30402b84db..ad9f7573af 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -115,10 +115,13 @@ pub struct WindowDestroyed { /// An event reporting that the mouse cursor has moved inside a window. /// /// The event is sent only if the cursor is over one of the application's windows. -/// It is the translated version of [`WindowEvent::CursorMoved`] from the `winit` crate. +/// It is the translated version of [`WindowEvent::CursorMoved`] from the `winit` crate with the addition of `delta`. /// /// Not to be confused with the [`MouseMotion`] event from `bevy_input`. /// +/// Because the range of data is limited by the window area and it may have been transformed by the OS to implement certain effects like acceleration, +/// you should not use it for non-cursor-like behaviour such as 3D camera control. Please see [`MouseMotion`] instead. +/// /// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved /// [`MouseMotion`]: bevy_input::mouse::MouseMotion #[derive(Event, Debug, Clone, PartialEq, Reflect)] @@ -133,6 +136,13 @@ pub struct CursorMoved { pub window: Entity, /// The cursor position in logical pixels. pub position: Vec2, + /// The change in the position of the cursor since the last event was sent. + /// This value is `None` if the cursor was outside the window area during the last frame. + // + // Because the range of this data is limited by the display area and it may have been + // transformed by the OS to implement effects such as cursor acceleration, it should + // not be used to implement non-cursor-like interactions such as 3D camera control. + pub delta: Option, } /// An event that is sent whenever the user's cursor enters a window. diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 2ea7736d1c..d778d18162 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -444,10 +444,20 @@ fn handle_winit_event( } WindowEvent::CursorMoved { position, .. } => { let physical_position = DVec2::new(position.x, position.y); + + let last_position = win.physical_cursor_position(); + let delta = last_position.map(|last_pos| { + (physical_position.as_vec2() - last_pos) / win.resolution.scale_factor() + }); + win.set_physical_cursor_position(Some(physical_position)); let position = (physical_position / win.resolution.scale_factor() as f64).as_vec2(); - app.send_event(CursorMoved { window, position }); + app.send_event(CursorMoved { + window, + position, + delta, + }); } WindowEvent::CursorEntered { .. } => { app.send_event(CursorEntered { window });