bevyengine / bevyengine/bevy

X11 Cursor Grab Mode on Window Initialization

Open
#10,084 0 comments 2 reactions 0 assignees View on GitHub
A-Windowing C-Docs C-Usability D-Straightforward O-Linux S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

I believe it is ubiquitous to initialize the primary window by creating a `Window` via the `WindowPlugin`. On X11, setting the `cursor.grab_mode` of the window to `CursorGrabMode::Locked` returns `NotViewable` from the X11 API ([link](https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html#requests:GrabPointer)). Below is the error message and the code that produces it:

Error

```sh
ERROR bevy_winit::winit_windows: Unable to grab cursor: os error at
.../winit-0.28.7/src/platform_impl/linux/x11/window.rs:1400:
Cursor could not be confined: confine location not viewable
```

Code

```rust
use bevy::prelude::*;
use bevy::window::{Cursor, CursorGrabMode};

fn main() {
App::new()
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
cursor: Cursor {
grab_mode: CursorGrabMode::Locked,
..Default::default()
},
..Default::default()
}),
..Default::default()
})
)
.run();
}
```

I'm guessing it would be possible to handle this either in `winit`'s Linux implementation ([link](https://github.com/rust-windowing/winit/blob/2ebbfab6a47f93f76841553dcb3cc53683e4955c/src/platform_impl/linux/x11/window.rs#L1342)) or `bevy_winit::attempt_grab` ([link](https://github.com/bevyengine/bevy/blob/be8ff5d0e1601ad503daad2f3ace59eaa98e7dd0/crates/bevy_winit/src/winit_windows.rs#L294)), but a quicker solution might be to document the below workaround with a startup system. This would be a quick win for people who use Bevy and want Linux support for their games.

Workaround

```rust
use bevy::prelude::*;
use bevy::window::CursorGrabMode;

fn main() {
App::new()
...
.add_systems(Startup, grab_cursor)
...
.run();
}

fn grab_cursor(mut windows: Query<&mut Window>) {
// X11 GrabPointer returns NotViewable error if the
// grab mode is set on window initialization.
let mut window = windows.single_mut();
window.cursor.grab_mode = CursorGrabMode::Locked;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.