Wayland `Locked` `CursorMode` causes error with `window.set_cursor_position` claiming the position mode is not `Locked`
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version
16.0 to main
## Relevant system information
Linux kernel 6.15.2 on Wayland (built with `wayland` feature)
## What you did
Assume a standard Linux setup under wayland with the following code. In `Setup`, it sets the cursor mode to `Locked`, and in every `update`, the cursor position is set with `window.set_cursor_position`.
This results in an error:
```
2025-06-25T21:13:38.781498Z ERROR bevy_winit::system: could not set cursor position: os error at /home/doomy/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winit-0.30.11/src/platform_impl/linux/wayland/window/state.rs:901: cursor position can be set only for locked cursor.
```
This is confusing, as the cursor position is set to locked.
```rs
use bevy::{prelude::*, window::CursorGrabMode, window::CursorOptions};
fn main() {
App::new().add_plugins(ClientPlugin).run();
}
pub struct ClientPlugin;
impl Plugin for ClientPlugin {
fn build(&self, app: &mut App) {
// ...
app.add_plugins(DefaultPlugins);
app.add_systems(Startup, setup_cursor);
app.add_systems(Update, recenter_cursor);
}
}
fn setup_cursor(mut windows: Query<(&mut Window, &mut CursorOptions)>) {
let Ok((mut window, mut cursor_options)) = windows.single_mut() else {
panic!();
};
cursor_options.visible = true;
cursor_options.grab_mode = CursorGrabMode::Locked;
let center = Vec2::new(window.width() / 2., window.height() / 2.);
window.set_cursor_position(Some(center));
}
fn recenter_cursor(mut windows: Query<&mut Window>) {
let Ok(mut window) = windows.single_mut() else {
panic!();
};
let center = Vec2::new(window.width() / 2., window.height() / 2.);
window.set_cursor_position(Some(center));
}
```
## What went wrong
Expectation: The cursor should be locked and allowed to be set to a specific position, in this case, the center of the screen.
Actual: The cursor is locked in place, but is not placed in the center, and an error is emitted.
## Additional information
It was suggested that the system [ordering here](https://github.com/bevyengine/bevy/blob/97dcb279fb2a96902bc04286238326b0fa6081ad/crates/bevy_winit/src/lib.rs#L145) may be at fault, as the cursor mode is set after window properties. However, after reordering the systems locally, the same issue persisted.
Contributor guide
Research direction
Start with the cursor-related system ordering in crates/bevy_winit/src/lib.rs, then reproduce the example on Linux with Wayland and the wayland feature enabled. Trace how CursorOptions.grab_mode and set_cursor_position are applied; done means Locked mode permits the requested center position without emitting the reported error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop-dev, game-dev, operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100