Fix set_cursor_grab_mode to try an alternative mode before giving an error (#6599)

# Objective

- Closes https://github.com/bevyengine/bevy/issues/6590
- The grab mode is platform dependent, this is problematic for bevy users since we can't easily use the recommended way to detect if the feature works like the winit docs recommend https://docs.rs/winit/0.27.5/winit/window/struct.Window.html#method.set_cursor_grab

## Solution

Try to use the grab mode that was requested, if it fails use the other one. Only then log an error if it fails after this step.
This commit is contained in:
IceSentry 2022-11-26 13:10:11 +00:00
parent 03bde74766
commit 17b7025a78
2 changed files with 25 additions and 10 deletions

View File

@ -711,8 +711,11 @@ impl Window {
///
/// ## Platform-specific
///
/// - **`macOS`** doesn't support cursor grab, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information.
/// - **`Windows`** doesn't support [`CursorGrabMode::Locked`]
/// - **`macOS`** doesn't support [`CursorGrabMode::Confined`]
/// - **`iOS/Android`** don't have cursors.
///
/// Since `Windows` and `macOS` have different [`CursorGrabMode`] support, it's possible the value returned here is not the same as the one actually sent to winit.
#[inline]
pub fn cursor_grab_mode(&self) -> CursorGrabMode {
self.cursor_grab_mode
@ -723,8 +726,11 @@ impl Window {
///
/// ## Platform-specific
///
/// - **`macOS`** doesn't support cursor grab, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information.
/// - **`Windows`** doesn't support [`CursorGrabMode::Locked`]
/// - **`macOS`** doesn't support [`CursorGrabMode::Confined`]
/// - **`iOS/Android`** don't have cursors.
///
/// Since `Windows` and `macOS` have different [`CursorGrabMode`] support, we first try to set the grab mode that was asked for. If it doesn't work then use the alternate grab mode.
pub fn set_cursor_grab_mode(&mut self, grab_mode: CursorGrabMode) {
self.cursor_grab_mode = grab_mode;
self.command_queue
@ -834,12 +840,12 @@ impl Window {
.push(WindowCommand::SetAlwaysOnTop { always_on_top });
}
/// Close the operating system window corresponding to this [`Window`].
///
///
/// This will also lead to this [`Window`] being removed from the
/// [`Windows`] resource.
///
/// If the default [`WindowPlugin`] is used, when no windows are
/// open, the [app will exit](bevy_app::AppExit).
/// open, the [app will exit](bevy_app::AppExit).
/// To disable this behaviour, set `exit_on_all_closed` on the [`WindowPlugin`]
/// to `false`
///
@ -869,7 +875,7 @@ impl Window {
/// The "html canvas" element selector.
///
/// If set, this selector will be used to find a matching html canvas element,
/// rather than creating a new one.
/// rather than creating a new one.
/// Uses the [CSS selector format](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).
///
/// This value has no effect on non-web platforms.
@ -996,7 +1002,7 @@ pub struct WindowDescriptor {
/// The "html canvas" element selector.
///
/// If set, this selector will be used to find a matching html canvas element,
/// rather than creating a new one.
/// rather than creating a new one.
/// Uses the [CSS selector format](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).
///
/// This value has no effect on non-web platforms.

View File

@ -4,7 +4,7 @@ mod web_resize;
mod winit_config;
mod winit_windows;
use converters::convert_cursor_grab_mode;
use winit::window::CursorGrabMode;
pub use winit_config::*;
pub use winit_windows::*;
@ -136,9 +136,18 @@ fn change_window(
}
bevy_window::WindowCommand::SetCursorGrabMode { grab_mode } => {
let window = winit_windows.get_window(id).unwrap();
window
.set_cursor_grab(convert_cursor_grab_mode(grab_mode))
.unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
match grab_mode {
bevy_window::CursorGrabMode::None => {
window.set_cursor_grab(CursorGrabMode::None)
}
bevy_window::CursorGrabMode::Confined => window
.set_cursor_grab(CursorGrabMode::Confined)
.or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked)),
bevy_window::CursorGrabMode::Locked => window
.set_cursor_grab(CursorGrabMode::Locked)
.or_else(|_e| window.set_cursor_grab(CursorGrabMode::Confined)),
}
.unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
}
bevy_window::WindowCommand::SetCursorVisibility { visible } => {
let window = winit_windows.get_window(id).unwrap();