mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 12:13:25 +00:00
Handle failed cursor grab mode changes so that the cursor grab mode change can be attempted again (#16293)
# Objective - Currently when you attempt to change the cursor_grab_mode it caches the new value whether the cursor grab succeeded or failed. This change handles the Result being returned by set_cursor_grab and changes the cursor_grab_mode back to the cached version in case of an Error. - Creates a way to handle #16237 and #16238 ## Solution - I changed the signature of winit_windows attempt_grab to return the Result<(), ExternalError> that winit set_cursor_grab returns. The system that calls attempt_grab now checks if there's an error returned, and if there is it sets the grab_mode back to the cached version (similar to what hit_test does a few lines down). ## Testing - I tested using this system that previously would not correctly lock the mouse on Ubuntu/x11 ``` pub fn lock_mouse(mut primary_window: Query<&mut Window, With<PrimaryWindow>>) { let window = &mut primary_window.single_mut(); if window.focused { window.cursor_options.grab_mode = CursorGrabMode::Confined; } else { window.cursor_options.grab_mode = CursorGrabMode::None; } } ``` - I only tested on Ubuntu with x11
This commit is contained in:
parent
ef9427727f
commit
1e3ecbefdb
2 changed files with 14 additions and 4 deletions
|
@ -385,8 +385,11 @@ pub(crate) fn changed_windows(
|
|||
}
|
||||
}
|
||||
|
||||
if window.cursor_options.grab_mode != cache.window.cursor_options.grab_mode {
|
||||
crate::winit_windows::attempt_grab(winit_window, window.cursor_options.grab_mode);
|
||||
if window.cursor_options.grab_mode != cache.window.cursor_options.grab_mode
|
||||
&& crate::winit_windows::attempt_grab(winit_window, window.cursor_options.grab_mode)
|
||||
.is_err()
|
||||
{
|
||||
window.cursor_options.grab_mode = cache.window.cursor_options.grab_mode;
|
||||
}
|
||||
|
||||
if window.cursor_options.visible != cache.window.cursor_options.visible {
|
||||
|
|
|
@ -10,6 +10,7 @@ use bevy_window::{
|
|||
|
||||
use winit::{
|
||||
dpi::{LogicalSize, PhysicalPosition},
|
||||
error::ExternalError,
|
||||
event_loop::ActiveEventLoop,
|
||||
monitor::{MonitorHandle, VideoModeHandle},
|
||||
window::{CursorGrabMode as WinitCursorGrabMode, Fullscreen, Window as WinitWindow, WindowId},
|
||||
|
@ -279,7 +280,7 @@ impl WinitWindows {
|
|||
|
||||
// Do not set the grab mode on window creation if it's none. It can fail on mobile.
|
||||
if window.cursor_options.grab_mode != CursorGrabMode::None {
|
||||
attempt_grab(&winit_window, window.cursor_options.grab_mode);
|
||||
let _ = attempt_grab(&winit_window, window.cursor_options.grab_mode);
|
||||
}
|
||||
|
||||
winit_window.set_cursor_visible(window.cursor_options.visible);
|
||||
|
@ -380,7 +381,10 @@ pub fn get_best_videomode(monitor: &MonitorHandle) -> VideoModeHandle {
|
|||
modes.first().unwrap().clone()
|
||||
}
|
||||
|
||||
pub(crate) fn attempt_grab(winit_window: &WinitWindow, grab_mode: CursorGrabMode) {
|
||||
pub(crate) fn attempt_grab(
|
||||
winit_window: &WinitWindow,
|
||||
grab_mode: CursorGrabMode,
|
||||
) -> Result<(), ExternalError> {
|
||||
let grab_result = match grab_mode {
|
||||
CursorGrabMode::None => winit_window.set_cursor_grab(WinitCursorGrabMode::None),
|
||||
CursorGrabMode::Confined => winit_window
|
||||
|
@ -398,6 +402,9 @@ pub(crate) fn attempt_grab(winit_window: &WinitWindow, grab_mode: CursorGrabMode
|
|||
};
|
||||
|
||||
bevy_utils::tracing::error!("Unable to {} cursor: {}", err_desc, err);
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue