From 29b09823ee499469b186871aa2e48376836900a2 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sat, 26 Nov 2022 13:10:11 +0000 Subject: [PATCH] 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. --- crates/bevy_window/src/window.rs | 18 ++++++++++++------ crates/bevy_winit/src/lib.rs | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 1c7416b2c96a2..05f934fc16e8d 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -699,8 +699,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 @@ -711,8 +714,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 @@ -797,12 +803,12 @@ impl Window { }); } /// 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` /// @@ -832,7 +838,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. @@ -957,7 +963,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. diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 13307d7718e58..7834c0c117a2e 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -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();