Repository: bevyengine/bevy
File: crates/bevy_winit/src/winit_windows.rs (Rust)

Code before:
///
/// TODO: When Winit 0.31 releases this function can be removed and replaced with
/// `MonitorHandle::current_video_mode()`
fn get_current_videomode(monitor: &MonitorHandle) -> Option<VideoModeHandle> {
    monitor
        .video_modes()
        .filter(|mode| {
            mode.size() == monitor.size()
                && Some(mode.refresh_rate_millihertz()) == monitor.refresh_rate_millihertz()
        })
        .max_by_key(VideoModeHandle::bit_depth)
}

pub(crate) fn attempt_grab(
    winit_window: &WinitWindow,
    grab_mode: CursorGrabMode,
) -> Result<(), ExternalError> {
    // Do not attempt to grab on web if unsupported (e.g. mobile)
    #[cfg(target_arch = "wasm32")]
    if !js_sys::Reflect::has(
        web_sys::window().unwrap().document().unwrap().as_ref(),
        &"exitPointerLock".into(),
    )
    .unwrap_or(false)
    {
        return Ok(());
    }

    let grab_result = match grab_mode {
        CursorGrabMode::None => winit_window.set_cursor_grab(WinitCursorGrabMode::None),
        CursorGrabMode::Confined => winit_window
            .set_cursor_grab(WinitCursorGrabMode::Confined)
            .or_else(|_e| winit_window.set_cursor_grab(WinitCursorGrabMode::Locked)),
        CursorGrabMode::Locked => winit_window
            .set_cursor_grab(WinitCursorGrabMode::Locked)
            .or_else(|_e| winit_window.set_cursor_grab(WinitCursorGrabMode::Confined)),
    };

    if let Err(err) = grab_result {
        let err_desc = match grab_mode {
            CursorGrabMode::Confined | CursorGrabMode::Locked => "grab",
            CursorGrabMode::None => "ungrab",
        };

        tracing::error!("Unable to {} cursor: {}", err_desc, err);
        Err(err)
    } else {
        Ok(())
    }
}


Review comment (suggestion):
We should be returning some form of "not supported" error, and then avoiding panics later in the callstack.

Code after:
///
/// TODO: When Winit 0.31 releases this function can be removed and replaced with
/// `MonitorHandle::current_video_mode()`
fn get_current_videomode(monitor: &MonitorHandle) -> Option<VideoModeHandle> {
    monitor
        .video_modes()
        .filter(|mode| {
            mode.size() == monitor.size()
                && Some(mode.refresh_rate_millihertz()) == monitor.refresh_rate_millihertz()
        })
        .max_by_key(VideoModeHandle::bit_depth)
}

#[cfg(target_arch = "wasm32")]
fn pointer_supported() -> Result<bool, ExternalError> {
    Ok(js_sys::Reflect::has(
        web_sys::window()
            .ok_or(ExternalError::Ignored)?
            .document()
            .ok_or(ExternalError::Ignored)?
            .as_ref(),
        &"exitPointerLock".into(),
    )
    .unwrap_or(false))
}

pub(crate) fn attempt_grab(
    winit_window: &WinitWindow,
    grab_mode: CursorGrabMode,
) -> Result<(), ExternalError> {
    // Do not attempt to grab on web if unsupported (e.g. mobile)
    #[cfg(target_arch = "wasm32")]
    if !pointer_supported()? {
        return Err(ExternalError::Ignored);
    }

    let grab_result = match grab_mode {
        CursorGrabMode::None => winit_window.set_cursor_grab(WinitCursorGrabMode::None),
        CursorGrabMode::Confined => winit_window
            .set_cursor_grab(WinitCursorGrabMode::Confined)
            .or_else(|_e| winit_window.set_cursor_grab(WinitCursorGrabMode::Locked)),
        CursorGrabMode::Locked => winit_window
            .set_cursor_grab(WinitCursorGrabMode::Locked)
            .or_else(|_e| winit_window.set_cursor_grab(WinitCursorGrabMode::Confined)),
    };

    if let Err(err) = grab_result {
        let err_desc = match grab_mode {
            CursorGrabMode::Confined | CursorGrabMode::Locked => "grab",
            CursorGrabMode::None => "ungrab",
        };