Skip to content

Commit 4122ff2

Browse files
mockersfItsDoot
authored andcommitted
break feedback loop when moving cursor (bevyengine#7298)
# 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.
1 parent b77b825 commit 4122ff2

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

crates/bevy_winit/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,11 @@ pub fn winit_runner(mut app: App) {
396396
window.resolution.physical_height() as f64 - position.y,
397397
);
398398

399-
window.set_physical_cursor_position(Some(physical_position));
399+
// bypassing change detection to not trigger feedback loop with system `changed_window`
400+
// this system change the cursor position in winit
401+
window
402+
.bypass_change_detection()
403+
.set_physical_cursor_position(Some(physical_position));
400404

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

418426
cursor_events.cursor_left.send(CursorLeft {

examples/tools/scene_viewer/camera_controller_plugin.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ fn camera_controller(
177177
for mouse_event in mouse_events.iter() {
178178
mouse_delta += mouse_event.delta;
179179
}
180-
} else {
180+
}
181+
if mouse_button_input.just_released(options.mouse_key_enable_mouse) {
181182
for mut window in &mut windows {
182183
window.cursor.grab_mode = CursorGrabMode::None;
183184
window.cursor.visible = true;

0 commit comments

Comments
 (0)