
# Objective - Fixes #19627 - Tackles part of #19644 - Supersedes #19629 - `Window` has become a very very very big component - As such, our change detection does not *really* work on it, as e.g. moving the mouse will cause a change for the entire window - We circumvented this with a cache - But, some things *shouldn't* be cached as they can be changed from outside the user's control, notably the cursor grab mode on web - So, we need to disable the cache for that - But because change detection is broken, that would result in the cursor grab mode being set every frame the mouse is moved - That is usually *not* what a dev wants, as it forces the cursor to be locked even when the end-user is trying to free the cursor on the browser - the cache in this situation is invalid due to #8949 ## Solution - Split `Window` into multiple components, each with working change detection - Disable caching of the cursor grab mode - This will only attempt to force the grab mode when the `CursorOptions` were touched by the user, which is *much* rarer than simply moving the mouse. - If this PR is merged, I'll do the exact same for the other constituents of `Window` as a follow-up ## Testing - Ran all the changed examples
32 lines
826 B
Rust
32 lines
826 B
Rust
//! Demonstrates how to grab and hide the mouse cursor.
|
|
|
|
use bevy::{
|
|
prelude::*,
|
|
window::{CursorGrabMode, CursorOptions},
|
|
};
|
|
|
|
fn main() {
|
|
App::new()
|
|
.add_plugins(DefaultPlugins)
|
|
.add_systems(Update, grab_mouse)
|
|
.run();
|
|
}
|
|
|
|
// This system grabs the mouse when the left mouse button is pressed
|
|
// and releases it when the escape key is pressed
|
|
fn grab_mouse(
|
|
mut cursor_options: Single<&mut CursorOptions>,
|
|
mouse: Res<ButtonInput<MouseButton>>,
|
|
key: Res<ButtonInput<KeyCode>>,
|
|
) {
|
|
if mouse.just_pressed(MouseButton::Left) {
|
|
cursor_options.visible = false;
|
|
cursor_options.grab_mode = CursorGrabMode::Locked;
|
|
}
|
|
|
|
if key.just_pressed(KeyCode::Escape) {
|
|
cursor_options.visible = true;
|
|
cursor_options.grab_mode = CursorGrabMode::None;
|
|
}
|
|
}
|