Change the requested cursor grab depending on platform support, fix setting window size

This commit is contained in:
SeanOMik 2023-09-19 00:16:01 -04:00
parent fef032351e
commit db84f03b57
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
1 changed files with 43 additions and 41 deletions

View File

@ -1,7 +1,7 @@
use std::sync::Arc;
use glam::Vec2;
use tracing::{warn, error};
use glam::{Vec2, IVec2};
use tracing::{warn, error, debug};
use winit::{window::{Window, Fullscreen}, dpi::{LogicalPosition, LogicalSize}, error::ExternalError};
pub use winit::window::{CursorGrabMode, CursorIcon, Icon, Theme, WindowButtons, WindowLevel};
@ -99,19 +99,19 @@ pub struct WindowOptions {
/// Platform-specific:
/// * iOS / Android: Unsupported.
/// * Web: Sets the size of the canvas element.
pub inner_size: Vec2,
pub inner_size: IVec2,
/// Sets a maximum dimension size for the window.
///
/// Platform-specific:
/// * iOS / Android / Web / Orbital: Unsupported.
pub max_inner_size: Option<Vec2>,
pub max_inner_size: Option<IVec2>,
/// Sets a minimum dimension size for the window.
///
/// Platform-specific:
/// * iOS / Android / Web / Orbital: Unsupported.
pub min_inner_size: Option<Vec2>,
pub min_inner_size: Option<IVec2>,
/// Sets the window to maximized or back.
///
@ -188,7 +188,7 @@ impl Default for WindowOptions {
mode: WindowMode::Windowed,
ime_allowed: false,
ime_position: Default::default(),
inner_size: Default::default(),
inner_size: glam::i32::IVec2::new(800, 600),
max_inner_size: None,
min_inner_size: None,
maximized: false,
@ -209,20 +209,48 @@ pub struct WindowPlugin {
create_options: WindowOptions,
}
/// Convert an Vec2 to a LogicalPosition<f32>
fn vec2_to_logical_pos(pos: Vec2) -> LogicalPosition<f32> {
LogicalPosition { x: pos.x, y: pos.y }
}
fn vec2_to_logical_size(size: Vec2) -> LogicalSize<f32> {
/// Convert an IVec2 to a LogicalSize<i32>
fn ivec2_to_logical_size(size: IVec2) -> LogicalSize<i32> {
LogicalSize { width: size.x, height: size.y }
}
fn vec2_to_logical_pos_op(pos: Option<Vec2>) -> Option<LogicalPosition<f32>> {
pos.map(|pos| vec2_to_logical_pos(pos))
/// Convert an Option<IVec2> to an Option<LogicalSize<i32>>
fn ivec2_to_logical_size_op(size: Option<IVec2>) -> Option<LogicalSize<i32>> {
size.map(|size| ivec2_to_logical_size(size))
}
/// Convert an Option<Vec2> to an Option<LogicalSize<f32>>
fn vec2_to_logical_size_op(size: Option<Vec2>) -> Option<LogicalSize<f32>> {
size.map(|size| vec2_to_logical_size(size))
size.map(|size| LogicalSize { width: size.x, height: size.y } )
}
/// Set the cursor grab of a window depending on the platform.
/// This will also modify the parameter `grab` to ensure it matches what the platform can support
fn set_cursor_grab(window: &Window, grab: &mut CursorGrabMode) -> anyhow::Result<()> {
if *grab != CursorGrabMode::None {
if cfg!(unix) {
*grab = CursorGrabMode::Confined;
// TODO: Find a way to see if winit is using x11 or wayland. wayland supports Locked
} else if cfg!(wasm) {
*grab = CursorGrabMode::Locked;
} else if cfg!(windows) {
*grab = CursorGrabMode::Confined; // NOTE: May support Locked later
} else if cfg!(target_os = "macos") {
*grab = CursorGrabMode::Locked; // NOTE: May support Confined later
} else if cfg!(any(target_os = "android", target_os = "ios", target_os = "orbital")) {
warn!("CursorGrabMode is not supported on Android, IOS, or Oribital, skipping");
return Ok(())
}
}
window.set_cursor_grab(*grab)?;
Ok(())
}
fn window_updater_system(world: &mut edict::World) -> anyhow::Result<()> {
@ -230,36 +258,10 @@ fn window_updater_system(world: &mut edict::World) -> anyhow::Result<()> {
// if the options changed, update the window
if opts.changed() {
window.set_content_protected(opts.content_protected);
match opts.cursor_grab {
CursorGrabMode::Confined => {
match window.set_cursor_grab(opts.cursor_grab)
.or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked)) {
Ok(()) => {},
Err(ExternalError::NotSupported(_)) => {
warn!("Setting CursorGrab is not supported on this platform");
},
Err(e) => {
error!("OS error when setting CursorGrab: {:?}", e);
}
}
},
_ => {
match window.set_cursor_grab(opts.cursor_grab) {
Ok(()) => {},
Err(ExternalError::NotSupported(_)) => {
warn!("Setting CursorGrab is not supported on this platform");
},
Err(e) => {
error!("OS error when setting CursorGrab: {:?}", e);
}
}
}
}
set_cursor_grab(&window, &mut opts.cursor_grab)?;
match window.set_cursor_hittest(opts.cursor_hittest) {
Ok(()) => {},
Err(ExternalError::NotSupported(_)) => {
warn!("Setting cursor hittest is not supported on this platform");
},
Err(ExternalError::NotSupported(_)) => { /* ignore */ },
Err(e) => {
error!("OS error when setting cursor hittest: {:?}", e);
}
@ -284,12 +286,12 @@ fn window_updater_system(world: &mut edict::World) -> anyhow::Result<()> {
window.set_ime_allowed(opts.ime_allowed);
window.set_ime_position(vec2_to_logical_pos(opts.ime_position));
//window.set_inner_size(vec2_to_logical_size(opts.inner_size)); // TODO
window.set_inner_size(ivec2_to_logical_size(opts.inner_size));
if opts.max_inner_size.is_some() {
window.set_max_inner_size(vec2_to_logical_size_op(opts.max_inner_size));
window.set_max_inner_size(ivec2_to_logical_size_op(opts.max_inner_size));
}
if opts.min_inner_size.is_some() {
window.set_min_inner_size(vec2_to_logical_size_op(opts.min_inner_size));
window.set_min_inner_size(ivec2_to_logical_size_op(opts.min_inner_size));
}
//window.set_maximized(opts.maximized); // TODO
//window.set_minimized(opts.minimized); // TODO