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
					
				| @ -385,8 +385,11 @@ pub(crate) fn changed_windows( | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if window.cursor_options.grab_mode != cache.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); |             && 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 { |         if window.cursor_options.visible != cache.window.cursor_options.visible { | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ use bevy_window::{ | |||||||
| 
 | 
 | ||||||
| use winit::{ | use winit::{ | ||||||
|     dpi::{LogicalSize, PhysicalPosition}, |     dpi::{LogicalSize, PhysicalPosition}, | ||||||
|  |     error::ExternalError, | ||||||
|     event_loop::ActiveEventLoop, |     event_loop::ActiveEventLoop, | ||||||
|     monitor::{MonitorHandle, VideoModeHandle}, |     monitor::{MonitorHandle, VideoModeHandle}, | ||||||
|     window::{CursorGrabMode as WinitCursorGrabMode, Fullscreen, Window as WinitWindow, WindowId}, |     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.
 |         // 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 { |         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); |         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() |     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 { |     let grab_result = match grab_mode { | ||||||
|         CursorGrabMode::None => winit_window.set_cursor_grab(WinitCursorGrabMode::None), |         CursorGrabMode::None => winit_window.set_cursor_grab(WinitCursorGrabMode::None), | ||||||
|         CursorGrabMode::Confined => winit_window |         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); |         bevy_utils::tracing::error!("Unable to {} cursor: {}", err_desc, err); | ||||||
|  |         Err(err) | ||||||
|  |     } else { | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Knar
						Knar