Skip to content

Commit

Permalink
break feedback loop when moving cursor (bevyengine#7298)
Browse files Browse the repository at this point in the history
# Objective

- Fixes bevyengine#7294

## Solution

- Do not trigger change detection when setting the cursor position from winit

When moving the cursor continuously, Winit sends events:
- CursorMoved(0)
- CursorMoved(1)
- => start of Bevy schedule execution
- CursorMoved(2)
- CursorMoved(3)
- <= End of Bevy schedule execution

if Bevy schedule runs after the event 1, events 2 and 3 would happen during the execution but would be read only on the next system run. During the execution, the system would detect a change on cursor position, and send back an order to winit to move it back to 1, so event 2 and 3 would be ignored. By bypassing change detection when setting the cursor from winit event, it doesn't trigger sending back that change to winit out of order.
  • Loading branch information
mockersf authored and ItsDoot committed Feb 1, 2023
1 parent b77b825 commit 4122ff2
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
12 changes: 10 additions & 2 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,11 @@ pub fn winit_runner(mut app: App) {
window.resolution.physical_height() as f64 - position.y,
);

window.set_physical_cursor_position(Some(physical_position));
// bypassing change detection to not trigger feedback loop with system `changed_window`
// this system change the cursor position in winit
window
.bypass_change_detection()
.set_physical_cursor_position(Some(physical_position));

cursor_events.cursor_moved.send(CursorMoved {
window: window_entity,
Expand All @@ -412,7 +416,11 @@ pub fn winit_runner(mut app: App) {
WindowEvent::CursorLeft { .. } => {
// Component
if let Ok((mut window, _)) = window_query.get_mut(window_entity) {
window.set_physical_cursor_position(None);
// bypassing change detection to not trigger feedback loop with system `changed_window`
// this system change the cursor position in winit
window
.bypass_change_detection()
.set_physical_cursor_position(None);
}

cursor_events.cursor_left.send(CursorLeft {
Expand Down
3 changes: 2 additions & 1 deletion examples/tools/scene_viewer/camera_controller_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ fn camera_controller(
for mouse_event in mouse_events.iter() {
mouse_delta += mouse_event.delta;
}
} else {
}
if mouse_button_input.just_released(options.mouse_key_enable_mouse) {
for mut window in &mut windows {
window.cursor.grab_mode = CursorGrabMode::None;
window.cursor.visible = true;
Expand Down

0 comments on commit 4122ff2

Please sign in to comment.