Skip to content

Remove cursor caching #19629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

Conversation

janhohenheim
Copy link
Member

@janhohenheim janhohenheim commented Jun 13, 2025

Objective

Solution

  • Disable cursor caching.
    • Note that this will tell winit to set the cursor options on every Changed<Window>
    • I think this is fine, as these events are rare and this is not an expensive operation
    • If this ends up causing unexpected trouble, we can trivially revert the PR

Testing

I ran the window_settings.rs, changed the window settings and the cursor capturing to verify that everything still works the same.

@janhohenheim janhohenheim added C-Bug An unexpected or incorrect behavior A-Windowing Platform-agnostic interface layer to run your app in D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 13, 2025
@janhohenheim janhohenheim added this to the 0.17 milestone Jun 13, 2025
Copy link
Contributor

@tbillington tbillington left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important to note Window is modified to set cursor position when a user moves the mouse, so this may be triggered every frame for some kinds of games. I don't know the cost of the calls made here so I can't say if that's a problem or not.

Came up in discord https://discord.com/channels/691052431525675048/1253771396832821270/1383504960469209239

Potential perf aside removing caching looks good

@janhohenheim janhohenheim added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 14, 2025
@janhohenheim
Copy link
Member Author

A more sophisticated version could split the Window struct into multiple components that are connected as relationships. That way, we can have working change detection for all of them. But I'd prefer to get this fix merged first and leave a Window redesign for a dedicated PR :)

@jf908
Copy link
Contributor

jf908 commented Jun 16, 2025

I just realized a side effect of this change is that if you set CursorGrabMode::Locked then any time you mutate the window, it will try to re-lock the cursor. I can't think of a realistic situation where this would break things because its so rare to change window properties on the web but I feel like there are could be edge cases where this would result in something strange. For example resizing the window would spam attempts to lock the cursor but because there aren't triggered by a click, it would probably would just spam console errors but not actually do anything.

@janhohenheim
Copy link
Member Author

@jf908 I can check. I'm planning on splitting the Window struct afterwards anyways, so any issue like that will be addressed by the followup PR :)

@janhohenheim
Copy link
Member Author

Bad news: due to #8949, unlocking your cursor on web now becomes extremely icky, as Bevy just tries and tries again to lock the cursor, resulting in it staying locked even when trying to free it!

Screencast.From.2025-06-16.05-11-26.mp4

This means that for cursor caching to be gone, we really do need working change detection

@janhohenheim janhohenheim removed the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Jun 16, 2025
github-merge-queue bot pushed a commit that referenced this pull request Jun 17, 2025
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bevy caches invalid cursor settings
4 participants