mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
Update wgpu
to 0.14.0, naga
to 0.10.0
, winit
to 0.27.4, raw-window-handle
to 0.5.0, ndk
to 0.7 (#6218)
# Objective - Update `wgpu` to 0.14.0, `naga` to `0.10.0`, `winit` to 0.27.4, `raw-window-handle` to 0.5.0, `ndk` to 0.7. ## Solution --- ## Changelog ### Changed - Changed `RawWindowHandleWrapper` to `RawHandleWrapper` which wraps both `RawWindowHandle` and `RawDisplayHandle`, which satisfies the `impl HasRawWindowHandle and HasRawDisplayHandle` that `wgpu` 0.14.0 requires. - Changed `bevy_window::WindowDescriptor`'s `cursor_locked` to `cursor_grab_mode`, change its type from `bool` to `bevy_window::CursorGrabMode`. ## Migration Guide - Adjust usage of `bevy_window::WindowDescriptor`'s `cursor_locked` to `cursor_grab_mode`, and adjust its type from `bool` to `bevy_window::CursorGrabMode`.
This commit is contained in:
parent
b2ca3fb8b5
commit
c313e21d65
17 changed files with 188 additions and 134 deletions
|
@ -40,7 +40,7 @@ wasm-bindgen-futures = "0.4"
|
||||||
js-sys = "0.3"
|
js-sys = "0.3"
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
ndk-glue = { version = "0.5" }
|
ndk-glue = { version = "0.7" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures-lite = "1.4.0"
|
futures-lite = "1.4.0"
|
||||||
|
|
|
@ -100,4 +100,4 @@ bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.9.0-dev" }
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
# This version *must* be the same as the version used by winit,
|
# This version *must* be the same as the version used by winit,
|
||||||
# or Android will break: https://github.com/rust-windowing/winit#android
|
# or Android will break: https://github.com/rust-windowing/winit#android
|
||||||
ndk-glue = {version = "0.5", features = ["logger"]}
|
ndk-glue = {version = "0.7", features = ["logger"]}
|
||||||
|
|
|
@ -49,9 +49,9 @@ bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" }
|
||||||
image = { version = "0.24", default-features = false }
|
image = { version = "0.24", default-features = false }
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
wgpu = { version = "0.13.1", features = ["spirv"] }
|
wgpu = { version = "0.14.0", features = ["spirv"] }
|
||||||
codespan-reporting = "0.11.0"
|
codespan-reporting = "0.11.0"
|
||||||
naga = { version = "0.9.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
naga = { version = "0.10.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||||
|
|
|
@ -149,7 +149,7 @@ impl Plugin for RenderPlugin {
|
||||||
|
|
||||||
let surface = windows
|
let surface = windows
|
||||||
.get_primary()
|
.get_primary()
|
||||||
.and_then(|window| window.raw_window_handle())
|
.and_then(|window| window.raw_handle())
|
||||||
.map(|wrapper| unsafe {
|
.map(|wrapper| unsafe {
|
||||||
let handle = wrapper.get_handle();
|
let handle = wrapper.get_handle();
|
||||||
instance.create_surface(&handle)
|
instance.create_surface(&handle)
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
use bevy_app::{App, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_utils::{tracing::debug, HashMap, HashSet};
|
use bevy_utils::{tracing::debug, HashMap, HashSet};
|
||||||
use bevy_window::{PresentMode, RawWindowHandleWrapper, WindowClosed, WindowId, Windows};
|
use bevy_window::{PresentMode, RawHandleWrapper, WindowClosed, WindowId, Windows};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// Token to ensure a system runs on the main thread.
|
/// Token to ensure a system runs on the main thread.
|
||||||
|
@ -38,7 +38,7 @@ impl Plugin for WindowRenderPlugin {
|
||||||
|
|
||||||
pub struct ExtractedWindow {
|
pub struct ExtractedWindow {
|
||||||
pub id: WindowId,
|
pub id: WindowId,
|
||||||
pub raw_window_handle: Option<RawWindowHandleWrapper>,
|
pub raw_handle: Option<RawHandleWrapper>,
|
||||||
pub physical_width: u32,
|
pub physical_width: u32,
|
||||||
pub physical_height: u32,
|
pub physical_height: u32,
|
||||||
pub present_mode: PresentMode,
|
pub present_mode: PresentMode,
|
||||||
|
@ -83,7 +83,7 @@ fn extract_windows(
|
||||||
.entry(window.id())
|
.entry(window.id())
|
||||||
.or_insert(ExtractedWindow {
|
.or_insert(ExtractedWindow {
|
||||||
id: window.id(),
|
id: window.id(),
|
||||||
raw_window_handle: window.raw_window_handle(),
|
raw_handle: window.raw_handle(),
|
||||||
physical_width: new_width,
|
physical_width: new_width,
|
||||||
physical_height: new_height,
|
physical_height: new_height,
|
||||||
present_mode: window.present_mode(),
|
present_mode: window.present_mode(),
|
||||||
|
@ -164,8 +164,8 @@ pub fn prepare_windows(
|
||||||
for window in windows
|
for window in windows
|
||||||
.windows
|
.windows
|
||||||
.values_mut()
|
.values_mut()
|
||||||
// value of raw_winndow_handle only None if synthetic test
|
// value of raw_handle is only None in synthetic tests
|
||||||
.filter(|x| x.raw_window_handle.is_some())
|
.filter(|x| x.raw_handle.is_some())
|
||||||
{
|
{
|
||||||
let window_surfaces = window_surfaces.deref_mut();
|
let window_surfaces = window_surfaces.deref_mut();
|
||||||
let surface = window_surfaces
|
let surface = window_surfaces
|
||||||
|
@ -173,8 +173,7 @@ pub fn prepare_windows(
|
||||||
.entry(window.id)
|
.entry(window.id)
|
||||||
.or_insert_with(|| unsafe {
|
.or_insert_with(|| unsafe {
|
||||||
// NOTE: On some OSes this MUST be called from the main thread.
|
// NOTE: On some OSes this MUST be called from the main thread.
|
||||||
render_instance
|
render_instance.create_surface(&window.raw_handle.as_ref().unwrap().get_handle())
|
||||||
.create_surface(&window.raw_window_handle.as_ref().unwrap().get_handle())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
|
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
|
||||||
|
@ -197,6 +196,7 @@ pub fn prepare_windows(
|
||||||
PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
|
PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
|
||||||
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
|
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
|
||||||
},
|
},
|
||||||
|
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do the initial surface configuration if it hasn't been configured yet. Or if size or
|
// Do the initial surface configuration if it hasn't been configured yet. Or if size or
|
||||||
|
|
|
@ -21,7 +21,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.9.0-dev" }
|
||||||
bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" }
|
bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" }
|
||||||
# Used for close_on_esc
|
# Used for close_on_esc
|
||||||
bevy_input = { path = "../bevy_input", version = "0.9.0-dev" }
|
bevy_input = { path = "../bevy_input", version = "0.9.0-dev" }
|
||||||
raw-window-handle = "0.4.2"
|
raw-window-handle = "0.5"
|
||||||
|
|
||||||
# other
|
# other
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#[warn(missing_docs)]
|
#[warn(missing_docs)]
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod event;
|
mod event;
|
||||||
mod raw_window_handle;
|
mod raw_handle;
|
||||||
mod system;
|
mod system;
|
||||||
mod window;
|
mod window;
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
pub use crate::raw_window_handle::*;
|
pub use crate::raw_handle::*;
|
||||||
pub use cursor::*;
|
pub use cursor::*;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use system::*;
|
pub use system::*;
|
||||||
|
|
75
crates/bevy_window/src/raw_handle.rs
Normal file
75
crates/bevy_window/src/raw_handle.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
use raw_window_handle::{
|
||||||
|
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A wrapper over [`RawWindowHandle`] and [`RawDisplayHandle`] that allows us to safely pass it across threads.
|
||||||
|
///
|
||||||
|
/// Depending on the platform, the underlying pointer-containing handle cannot be used on all threads,
|
||||||
|
/// and so we cannot simply make it (or any type that has a safe operation to get a [`RawWindowHandle`] or [`RawDisplayHandle`])
|
||||||
|
/// thread-safe.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RawHandleWrapper {
|
||||||
|
pub window_handle: RawWindowHandle,
|
||||||
|
pub display_handle: RawDisplayHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawHandleWrapper {
|
||||||
|
/// Returns a [`HasRawWindowHandle`] + [`HasRawDisplayHandle`] impl, which exposes [`RawWindowHandle`] and [`RawDisplayHandle`].
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Some platforms have constraints on where/how this handle can be used. For example, some platforms don't support doing window
|
||||||
|
/// operations off of the main thread. The caller must ensure the [`RawHandleWrapper`] is only used in valid contexts.
|
||||||
|
pub unsafe fn get_handle(&self) -> ThreadLockedRawWindowHandleWrapper {
|
||||||
|
ThreadLockedRawWindowHandleWrapper(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_display_handle(&self) -> RawDisplayHandle {
|
||||||
|
self.display_handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_window_handle(&self) -> RawWindowHandle {
|
||||||
|
self.window_handle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: [`RawHandleWrapper`] is just a normal "raw pointer", which doesn't impl Send/Sync. However the pointer is only
|
||||||
|
// exposed via an unsafe method that forces the user to make a call for a given platform. (ex: some platforms don't
|
||||||
|
// support doing window operations off of the main thread).
|
||||||
|
// A recommendation for this pattern (and more context) is available here:
|
||||||
|
// https://github.com/rust-windowing/raw-window-handle/issues/59
|
||||||
|
unsafe impl Send for RawHandleWrapper {}
|
||||||
|
unsafe impl Sync for RawHandleWrapper {}
|
||||||
|
|
||||||
|
/// A [`RawHandleWrapper`] that cannot be sent across threads.
|
||||||
|
///
|
||||||
|
/// This safely exposes [`RawWindowHandle`] and [`RawDisplayHandle`], but care must be taken to ensure that the construction itself is correct.
|
||||||
|
///
|
||||||
|
/// This can only be constructed via the [`RawHandleWrapper::get_handle()`] method;
|
||||||
|
/// be sure to read the safety docs there about platform-specific limitations.
|
||||||
|
/// In many cases, this should only be constructed on the main thread.
|
||||||
|
pub struct ThreadLockedRawWindowHandleWrapper(RawHandleWrapper);
|
||||||
|
|
||||||
|
// SAFETY: the caller has validated that this is a valid context to get [`RawHandleWrapper`]
|
||||||
|
// as otherwise an instance of this type could not have been constructed
|
||||||
|
// NOTE: we cannot simply impl HasRawWindowHandle for RawHandleWrapper,
|
||||||
|
// as the `raw_window_handle` method is safe. We cannot guarantee that all calls
|
||||||
|
// of this method are correct (as it may be off the main thread on an incompatible platform),
|
||||||
|
// and so exposing a safe method to get a [`RawWindowHandle`] directly would be UB.
|
||||||
|
unsafe impl HasRawWindowHandle for ThreadLockedRawWindowHandleWrapper {
|
||||||
|
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||||
|
self.0.get_window_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: the caller has validated that this is a valid context to get [`RawDisplayHandle`]
|
||||||
|
// as otherwise an instance of this type could not have been constructed
|
||||||
|
// NOTE: we cannot simply impl HasRawDisplayHandle for RawHandleWrapper,
|
||||||
|
// as the `raw_display_handle` method is safe. We cannot guarantee that all calls
|
||||||
|
// of this method are correct (as it may be off the main thread on an incompatible platform),
|
||||||
|
// and so exposing a safe method to get a [`RawDisplayHandle`] directly would be UB.
|
||||||
|
unsafe impl HasRawDisplayHandle for ThreadLockedRawWindowHandleWrapper {
|
||||||
|
fn raw_display_handle(&self) -> RawDisplayHandle {
|
||||||
|
self.0.get_display_handle()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
|
||||||
|
|
||||||
/// A wrapper over [`RawWindowHandle`] that allows us to safely pass it across threads.
|
|
||||||
///
|
|
||||||
/// Depending on the platform, the underlying pointer-containing handle cannot be used on all threads,
|
|
||||||
/// and so we cannot simply make it (or any type that has a safe operation to get a [`RawWindowHandle`])
|
|
||||||
/// thread-safe.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RawWindowHandleWrapper(RawWindowHandle);
|
|
||||||
|
|
||||||
impl RawWindowHandleWrapper {
|
|
||||||
pub(crate) fn new(handle: RawWindowHandle) -> Self {
|
|
||||||
Self(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a [`HasRawWindowHandle`] impl, which exposes [`RawWindowHandle`].
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// Some platforms have constraints on where/how this handle can be used. For example, some platforms don't support doing window
|
|
||||||
/// operations off of the main thread. The caller must ensure the [`RawWindowHandle`] is only used in valid contexts.
|
|
||||||
pub unsafe fn get_handle(&self) -> ThreadLockedRawWindowHandleWrapper {
|
|
||||||
ThreadLockedRawWindowHandleWrapper(self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SAFETY: RawWindowHandle is just a normal "raw pointer", which doesn't impl Send/Sync. However the pointer is only
|
|
||||||
// exposed via an unsafe method that forces the user to make a call for a given platform. (ex: some platforms don't
|
|
||||||
// support doing window operations off of the main thread).
|
|
||||||
// A recommendation for this pattern (and more context) is available here:
|
|
||||||
// https://github.com/rust-windowing/raw-window-handle/issues/59
|
|
||||||
unsafe impl Send for RawWindowHandleWrapper {}
|
|
||||||
unsafe impl Sync for RawWindowHandleWrapper {}
|
|
||||||
|
|
||||||
/// A [`RawWindowHandleWrapper`] that cannot be sent across threads.
|
|
||||||
///
|
|
||||||
/// This safely exposes a [`RawWindowHandle`], but care must be taken to ensure that the construction itself is correct.
|
|
||||||
///
|
|
||||||
/// This can only be constructed via the [`RawWindowHandleWrapper::get_handle()`] method;
|
|
||||||
/// be sure to read the safety docs there about platform-specific limitations.
|
|
||||||
/// In many cases, this should only be constructed on the main thread.
|
|
||||||
pub struct ThreadLockedRawWindowHandleWrapper(RawWindowHandle);
|
|
||||||
|
|
||||||
// SAFETY: the caller has validated that this is a valid context to get RawWindowHandle
|
|
||||||
// as otherwise an instance of this type could not have been constructed
|
|
||||||
// NOTE: we cannot simply impl HasRawWindowHandle for RawWindowHandleWrapper,
|
|
||||||
// as the `raw_window_handle` method is safe. We cannot guarantee that all calls
|
|
||||||
// of this method are correct (as it may be off the main thread on an incompatible platform),
|
|
||||||
// and so exposing a safe method to get a `RawWindowHandle` directly would be UB.
|
|
||||||
unsafe impl HasRawWindowHandle for ThreadLockedRawWindowHandleWrapper {
|
|
||||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ use bevy_ecs::system::Resource;
|
||||||
use bevy_math::{DVec2, IVec2, UVec2, Vec2};
|
use bevy_math::{DVec2, IVec2, UVec2, Vec2};
|
||||||
use bevy_reflect::{FromReflect, Reflect};
|
use bevy_reflect::{FromReflect, Reflect};
|
||||||
use bevy_utils::{tracing::warn, Uuid};
|
use bevy_utils::{tracing::warn, Uuid};
|
||||||
use raw_window_handle::RawWindowHandle;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Reflect, FromReflect)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Reflect, FromReflect)]
|
||||||
#[reflect_value(PartialEq, Hash)]
|
#[reflect_value(PartialEq, Hash)]
|
||||||
|
@ -76,7 +75,7 @@ impl WindowId {
|
||||||
use crate::CursorIcon;
|
use crate::CursorIcon;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::raw_window_handle::RawWindowHandleWrapper;
|
use crate::raw_handle::RawHandleWrapper;
|
||||||
|
|
||||||
impl fmt::Display for WindowId {
|
impl fmt::Display for WindowId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -257,9 +256,9 @@ pub struct Window {
|
||||||
decorations: bool,
|
decorations: bool,
|
||||||
cursor_icon: CursorIcon,
|
cursor_icon: CursorIcon,
|
||||||
cursor_visible: bool,
|
cursor_visible: bool,
|
||||||
cursor_locked: bool,
|
cursor_grab_mode: CursorGrabMode,
|
||||||
physical_cursor_position: Option<DVec2>,
|
physical_cursor_position: Option<DVec2>,
|
||||||
raw_window_handle: Option<RawWindowHandleWrapper>,
|
raw_handle: Option<RawHandleWrapper>,
|
||||||
focused: bool,
|
focused: bool,
|
||||||
mode: WindowMode,
|
mode: WindowMode,
|
||||||
canvas: Option<String>,
|
canvas: Option<String>,
|
||||||
|
@ -306,8 +305,8 @@ pub enum WindowCommand {
|
||||||
decorations: bool,
|
decorations: bool,
|
||||||
},
|
},
|
||||||
/// Set whether or not the cursor's position is locked.
|
/// Set whether or not the cursor's position is locked.
|
||||||
SetCursorLockMode {
|
SetCursorGrabMode {
|
||||||
locked: bool,
|
grab_mode: CursorGrabMode,
|
||||||
},
|
},
|
||||||
/// Set the cursor's [`CursorIcon`].
|
/// Set the cursor's [`CursorIcon`].
|
||||||
SetCursorIcon {
|
SetCursorIcon {
|
||||||
|
@ -343,6 +342,20 @@ pub enum WindowCommand {
|
||||||
Close,
|
Close,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines if and how the cursor is grabbed.
|
||||||
|
///
|
||||||
|
/// Use this enum with [`Window::set_cursor_grab_mode`] to grab the cursor.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
pub enum CursorGrabMode {
|
||||||
|
/// The cursor can freely leave the window.
|
||||||
|
None,
|
||||||
|
/// The cursor is confined to the window area.
|
||||||
|
Confined,
|
||||||
|
/// The cursor is locked inside the window area to a certain position.
|
||||||
|
Locked,
|
||||||
|
}
|
||||||
|
|
||||||
/// Defines the way a window is displayed.
|
/// Defines the way a window is displayed.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
@ -368,7 +381,7 @@ impl Window {
|
||||||
physical_height: u32,
|
physical_height: u32,
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
position: Option<IVec2>,
|
position: Option<IVec2>,
|
||||||
raw_window_handle: Option<RawWindowHandle>,
|
raw_handle: Option<RawHandleWrapper>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Window {
|
Window {
|
||||||
id,
|
id,
|
||||||
|
@ -385,10 +398,10 @@ impl Window {
|
||||||
resizable: window_descriptor.resizable,
|
resizable: window_descriptor.resizable,
|
||||||
decorations: window_descriptor.decorations,
|
decorations: window_descriptor.decorations,
|
||||||
cursor_visible: window_descriptor.cursor_visible,
|
cursor_visible: window_descriptor.cursor_visible,
|
||||||
cursor_locked: window_descriptor.cursor_locked,
|
cursor_grab_mode: window_descriptor.cursor_grab_mode,
|
||||||
cursor_icon: CursorIcon::Default,
|
cursor_icon: CursorIcon::Default,
|
||||||
physical_cursor_position: None,
|
physical_cursor_position: None,
|
||||||
raw_window_handle: raw_window_handle.map(RawWindowHandleWrapper::new),
|
raw_handle,
|
||||||
focused: true,
|
focused: true,
|
||||||
mode: window_descriptor.mode,
|
mode: window_descriptor.mode,
|
||||||
canvas: window_descriptor.canvas.clone(),
|
canvas: window_descriptor.canvas.clone(),
|
||||||
|
@ -645,34 +658,34 @@ impl Window {
|
||||||
self.command_queue
|
self.command_queue
|
||||||
.push(WindowCommand::SetDecorations { decorations });
|
.push(WindowCommand::SetDecorations { decorations });
|
||||||
}
|
}
|
||||||
/// Get whether or not the cursor is locked.
|
/// Get whether or how the cursor is grabbed.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **`macOS`** doesn't support cursor lock, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information.
|
/// - **`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.
|
||||||
/// - **`iOS/Android`** don't have cursors.
|
/// - **`iOS/Android`** don't have cursors.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cursor_locked(&self) -> bool {
|
pub fn cursor_grab_mode(&self) -> CursorGrabMode {
|
||||||
self.cursor_locked
|
self.cursor_grab_mode
|
||||||
}
|
}
|
||||||
/// Set whether or not the cursor is locked.
|
/// Set whether and how the cursor is grabbed.
|
||||||
///
|
///
|
||||||
/// This doesn't hide the cursor. For that, use [`set_cursor_visibility`](Window::set_cursor_visibility)
|
/// This doesn't hide the cursor. For that, use [`set_cursor_visibility`](Window::set_cursor_visibility)
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **`macOS`** doesn't support cursor lock, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information.
|
/// - **`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.
|
||||||
/// - **`iOS/Android`** don't have cursors.
|
/// - **`iOS/Android`** don't have cursors.
|
||||||
pub fn set_cursor_lock_mode(&mut self, lock_mode: bool) {
|
pub fn set_cursor_grab_mode(&mut self, grab_mode: CursorGrabMode) {
|
||||||
self.cursor_locked = lock_mode;
|
self.cursor_grab_mode = grab_mode;
|
||||||
self.command_queue
|
self.command_queue
|
||||||
.push(WindowCommand::SetCursorLockMode { locked: lock_mode });
|
.push(WindowCommand::SetCursorGrabMode { grab_mode });
|
||||||
}
|
}
|
||||||
/// Get whether or not the cursor is visible.
|
/// Get whether or not the cursor is visible.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **`Windows`**, **`X11`**, and **`Wayland`**: The cursor is hidden only when inside the window. To stop the cursor from leaving the window, use [`set_cursor_lock_mode`](Window::set_cursor_lock_mode).
|
/// - **`Windows`**, **`X11`**, and **`Wayland`**: The cursor is hidden only when inside the window. To stop the cursor from leaving the window, use [`set_cursor_grab_mode`](Window::set_cursor_grab_mode).
|
||||||
/// - **`macOS`**: The cursor is hidden only when the window is focused.
|
/// - **`macOS`**: The cursor is hidden only when the window is focused.
|
||||||
/// - **`iOS`** and **`Android`** do not have cursors
|
/// - **`iOS`** and **`Android`** do not have cursors
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -683,7 +696,7 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **`Windows`**, **`X11`**, and **`Wayland`**: The cursor is hidden only when inside the window. To stop the cursor from leaving the window, use [`set_cursor_lock_mode`](Window::set_cursor_lock_mode).
|
/// - **`Windows`**, **`X11`**, and **`Wayland`**: The cursor is hidden only when inside the window. To stop the cursor from leaving the window, use [`set_cursor_grab_mode`](Window::set_cursor_grab_mode).
|
||||||
/// - **`macOS`**: The cursor is hidden only when the window is focused.
|
/// - **`macOS`**: The cursor is hidden only when the window is focused.
|
||||||
/// - **`iOS`** and **`Android`** do not have cursors
|
/// - **`iOS`** and **`Android`** do not have cursors
|
||||||
pub fn set_cursor_visibility(&mut self, visible_mode: bool) {
|
pub fn set_cursor_visibility(&mut self, visible_mode: bool) {
|
||||||
|
@ -772,11 +785,11 @@ impl Window {
|
||||||
pub fn is_focused(&self) -> bool {
|
pub fn is_focused(&self) -> bool {
|
||||||
self.focused
|
self.focused
|
||||||
}
|
}
|
||||||
/// Get the [`RawWindowHandleWrapper`] corresponding to this window if set.
|
/// Get the [`RawHandleWrapper`] corresponding to this window if set.
|
||||||
///
|
///
|
||||||
/// During normal use, this can be safely unwrapped; the value should only be [`None`] when synthetically constructed for tests.
|
/// During normal use, this can be safely unwrapped; the value should only be [`None`] when synthetically constructed for tests.
|
||||||
pub fn raw_window_handle(&self) -> Option<RawWindowHandleWrapper> {
|
pub fn raw_handle(&self) -> Option<RawHandleWrapper> {
|
||||||
self.raw_window_handle.as_ref().cloned()
|
self.raw_handle.as_ref().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "html canvas" element selector.
|
/// The "html canvas" element selector.
|
||||||
|
@ -891,8 +904,8 @@ pub struct WindowDescriptor {
|
||||||
pub decorations: bool,
|
pub decorations: bool,
|
||||||
/// Sets whether the cursor is visible when the window has focus.
|
/// Sets whether the cursor is visible when the window has focus.
|
||||||
pub cursor_visible: bool,
|
pub cursor_visible: bool,
|
||||||
/// Sets whether the window locks the cursor inside its borders when the window has focus.
|
/// Sets whether and how the window grabs the cursor.
|
||||||
pub cursor_locked: bool,
|
pub cursor_grab_mode: CursorGrabMode,
|
||||||
/// Sets the [`WindowMode`](crate::WindowMode).
|
/// Sets the [`WindowMode`](crate::WindowMode).
|
||||||
///
|
///
|
||||||
/// The monitor to go fullscreen on can be selected with the `monitor` field.
|
/// The monitor to go fullscreen on can be selected with the `monitor` field.
|
||||||
|
@ -937,7 +950,7 @@ impl Default for WindowDescriptor {
|
||||||
present_mode: PresentMode::Fifo,
|
present_mode: PresentMode::Fifo,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
decorations: true,
|
decorations: true,
|
||||||
cursor_locked: false,
|
cursor_grab_mode: CursorGrabMode::None,
|
||||||
cursor_visible: true,
|
cursor_visible: true,
|
||||||
mode: WindowMode::Windowed,
|
mode: WindowMode::Windowed,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
|
|
|
@ -22,12 +22,11 @@ bevy_window = { path = "../bevy_window", version = "0.9.0-dev" }
|
||||||
bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" }
|
bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
winit = { version = "0.26.0", default-features = false }
|
winit = { version = "0.27", default-features = false }
|
||||||
approx = { version = "0.5.0", default-features = false }
|
approx = { version = "0.5", default-features = false }
|
||||||
raw-window-handle = "0.4.2"
|
raw-window-handle = "0.5"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
winit = { version = "0.26.0", default-features = false }
|
|
||||||
wasm-bindgen = { version = "0.2" }
|
wasm-bindgen = { version = "0.2" }
|
||||||
web-sys = "0.3"
|
web-sys = "0.3"
|
||||||
crossbeam-channel = "0.5"
|
crossbeam-channel = "0.5"
|
||||||
|
|
|
@ -5,7 +5,7 @@ use bevy_input::{
|
||||||
ButtonState,
|
ButtonState,
|
||||||
};
|
};
|
||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_window::CursorIcon;
|
use bevy_window::{CursorGrabMode, CursorIcon};
|
||||||
|
|
||||||
pub fn convert_keyboard_input(keyboard_input: &winit::event::KeyboardInput) -> KeyboardInput {
|
pub fn convert_keyboard_input(keyboard_input: &winit::event::KeyboardInput) -> KeyboardInput {
|
||||||
KeyboardInput {
|
KeyboardInput {
|
||||||
|
@ -266,3 +266,12 @@ pub fn convert_cursor_icon(cursor_icon: CursorIcon) -> winit::window::CursorIcon
|
||||||
CursorIcon::RowResize => winit::window::CursorIcon::RowResize,
|
CursorIcon::RowResize => winit::window::CursorIcon::RowResize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Map [`bevy_window::CursorGrabMode`] to [`winit::window::CursorGrabMode`].
|
||||||
|
pub fn convert_cursor_grab_mode(mode: CursorGrabMode) -> winit::window::CursorGrabMode {
|
||||||
|
match mode {
|
||||||
|
CursorGrabMode::None => winit::window::CursorGrabMode::None,
|
||||||
|
CursorGrabMode::Confined => winit::window::CursorGrabMode::Confined,
|
||||||
|
CursorGrabMode::Locked => winit::window::CursorGrabMode::Locked,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ mod web_resize;
|
||||||
mod winit_config;
|
mod winit_config;
|
||||||
mod winit_windows;
|
mod winit_windows;
|
||||||
|
|
||||||
|
use converters::convert_cursor_grab_mode;
|
||||||
pub use winit_config::*;
|
pub use winit_config::*;
|
||||||
pub use winit_windows::*;
|
pub use winit_windows::*;
|
||||||
|
|
||||||
|
@ -137,10 +138,10 @@ fn change_window(
|
||||||
let window = winit_windows.get_window(id).unwrap();
|
let window = winit_windows.get_window(id).unwrap();
|
||||||
window.set_cursor_icon(converters::convert_cursor_icon(icon));
|
window.set_cursor_icon(converters::convert_cursor_icon(icon));
|
||||||
}
|
}
|
||||||
bevy_window::WindowCommand::SetCursorLockMode { locked } => {
|
bevy_window::WindowCommand::SetCursorGrabMode { grab_mode } => {
|
||||||
let window = winit_windows.get_window(id).unwrap();
|
let window = winit_windows.get_window(id).unwrap();
|
||||||
window
|
window
|
||||||
.set_cursor_grab(locked)
|
.set_cursor_grab(convert_cursor_grab_mode(grab_mode))
|
||||||
.unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
|
.unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
|
||||||
}
|
}
|
||||||
bevy_window::WindowCommand::SetCursorVisibility { visible } => {
|
bevy_window::WindowCommand::SetCursorVisibility { visible } => {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
use crate::converters::convert_cursor_grab_mode;
|
||||||
use bevy_math::{DVec2, IVec2};
|
use bevy_math::{DVec2, IVec2};
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
use bevy_window::{MonitorSelection, Window, WindowDescriptor, WindowId, WindowMode};
|
use bevy_window::{
|
||||||
use raw_window_handle::HasRawWindowHandle;
|
MonitorSelection, RawHandleWrapper, Window, WindowDescriptor, WindowId, WindowMode,
|
||||||
|
};
|
||||||
|
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize},
|
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize},
|
||||||
window::Fullscreen,
|
window::Fullscreen,
|
||||||
|
@ -158,12 +161,12 @@ impl WinitWindows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if window_descriptor.cursor_locked {
|
match winit_window
|
||||||
match winit_window.set_cursor_grab(true) {
|
.set_cursor_grab(convert_cursor_grab_mode(window_descriptor.cursor_grab_mode))
|
||||||
|
{
|
||||||
Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {}
|
Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {}
|
||||||
Err(err) => Err(err).unwrap(),
|
Err(err) => Err(err).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
winit_window.set_cursor_visible(window_descriptor.cursor_visible);
|
winit_window.set_cursor_visible(window_descriptor.cursor_visible);
|
||||||
|
|
||||||
|
@ -192,7 +195,10 @@ impl WinitWindows {
|
||||||
.map(|position| IVec2::new(position.x, position.y));
|
.map(|position| IVec2::new(position.x, position.y));
|
||||||
let inner_size = winit_window.inner_size();
|
let inner_size = winit_window.inner_size();
|
||||||
let scale_factor = winit_window.scale_factor();
|
let scale_factor = winit_window.scale_factor();
|
||||||
let raw_window_handle = winit_window.raw_window_handle();
|
let raw_handle = RawHandleWrapper {
|
||||||
|
window_handle: winit_window.raw_window_handle(),
|
||||||
|
display_handle: winit_window.raw_display_handle(),
|
||||||
|
};
|
||||||
self.windows.insert(winit_window.id(), winit_window);
|
self.windows.insert(winit_window.id(), winit_window);
|
||||||
Window::new(
|
Window::new(
|
||||||
window_id,
|
window_id,
|
||||||
|
@ -201,7 +207,7 @@ impl WinitWindows {
|
||||||
inner_size.height,
|
inner_size.height,
|
||||||
scale_factor,
|
scale_factor,
|
||||||
position,
|
position,
|
||||||
Some(raw_window_handle),
|
Some(raw_handle),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +247,9 @@ pub fn get_fitting_videomode(
|
||||||
match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) {
|
match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) {
|
||||||
Equal => {
|
Equal => {
|
||||||
match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) {
|
match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) {
|
||||||
Equal => b.refresh_rate().cmp(&a.refresh_rate()),
|
Equal => b
|
||||||
|
.refresh_rate_millihertz()
|
||||||
|
.cmp(&a.refresh_rate_millihertz()),
|
||||||
default => default,
|
default => default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +266,9 @@ pub fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::mon
|
||||||
use std::cmp::Ordering::*;
|
use std::cmp::Ordering::*;
|
||||||
match b.size().width.cmp(&a.size().width) {
|
match b.size().width.cmp(&a.size().width) {
|
||||||
Equal => match b.size().height.cmp(&a.size().height) {
|
Equal => match b.size().height.cmp(&a.size().height) {
|
||||||
Equal => b.refresh_rate().cmp(&a.refresh_rate()),
|
Equal => b
|
||||||
|
.refresh_rate_millihertz()
|
||||||
|
.cmp(&a.refresh_rate_millihertz()),
|
||||||
default => default,
|
default => default,
|
||||||
},
|
},
|
||||||
default => default,
|
default => default,
|
||||||
|
|
19
deny.toml
19
deny.toml
|
@ -35,24 +35,21 @@ wildcards = "deny"
|
||||||
highlight = "all"
|
highlight = "all"
|
||||||
# Certain crates/versions that will be skipped when doing duplicate detection.
|
# Certain crates/versions that will be skipped when doing duplicate detection.
|
||||||
skip = [
|
skip = [
|
||||||
{ name = "cfg-if", version = "0.1" }, # from winit v0.26.0
|
|
||||||
{ name = "core-foundation", version = "0.7" }, # from winit v0.26.0
|
|
||||||
{ name = "core-foundation-sys", version = "0.7" }, # from winit v0.26.0
|
|
||||||
{ name = "core-graphics", version = "0.19" }, # from winit v0.26.0
|
|
||||||
{ name = "ndk", version = "0.5" }, # from winit v0.26.1
|
|
||||||
{ name = "ndk", version = "0.6" }, # from rodio v0.16.0
|
|
||||||
{ name = "ndk-glue", version = "0.5" }, # from winit v0.26.1
|
|
||||||
{ name = "ndk-sys", version = "0.2" }, # from winit v0.26.1
|
|
||||||
{ name = "ndk-sys", version = "0.3" }, # from rodio v0.16.0
|
{ name = "ndk-sys", version = "0.3" }, # from rodio v0.16.0
|
||||||
{ name = "parking_lot", version = "0.11" }, # from winit v0.26.1
|
{ name = "ndk", version = "0.6" }, # from rodio v0.16.0
|
||||||
{ name = "parking_lot_core", version = "0.8" }, # from winit v0.26.1
|
{ name = "raw-window-handle", version = "0.4" }, # from winit v0.27.4
|
||||||
{ name = "raw-window-handle", version = "0.4" }, # from wgpu v0.13.0
|
|
||||||
{ name = "nix", version = "0.23.1" }, # from alsa v0.6.0
|
{ name = "nix", version = "0.23.1" }, # from alsa v0.6.0
|
||||||
{ name = "windows_aarch64_msvc", version = "0.36" }, # from notify v5.0.0
|
{ name = "windows_aarch64_msvc", version = "0.36" }, # from notify v5.0.0
|
||||||
{ name = "windows_i686_gnu", version = "0.36" }, # from notify v5.0.0
|
{ name = "windows_i686_gnu", version = "0.36" }, # from notify v5.0.0
|
||||||
{ name = "windows_i686_msvc", version = "0.36" }, # from notify v5.0.0
|
{ name = "windows_i686_msvc", version = "0.36" }, # from notify v5.0.0
|
||||||
{ name = "windows_x86_64_gnu", version = "0.36" }, # from notify v5.0.0
|
{ name = "windows_x86_64_gnu", version = "0.36" }, # from notify v5.0.0
|
||||||
{ name = "windows_x86_64_msvc", version = "0.36" }, # from notify v5.0.0
|
{ name = "windows_x86_64_msvc", version = "0.36" }, # from notify v5.0.0
|
||||||
|
{ name = "windows-sys", version = "0.36" }, # from notify v5.0.0
|
||||||
|
{ name = "windows_aarch64_msvc", version = "0.37" }, # from rodio v0.16.0
|
||||||
|
{ name = "windows_i686_gnu", version = "0.37" }, # from rodio v0.16.0
|
||||||
|
{ name = "windows_i686_msvc", version = "0.37" }, # from rodio v0.16.0
|
||||||
|
{ name = "windows_x86_64_gnu", version = "0.37" }, # from rodio v0.16.0
|
||||||
|
{ name = "windows_x86_64_msvc", version = "0.37" }, # from rodio v0.16.0
|
||||||
]
|
]
|
||||||
|
|
||||||
[sources]
|
[sources]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Demonstrates how to grab and hide the mouse cursor.
|
//! Demonstrates how to grab and hide the mouse cursor.
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy::window::CursorGrabMode;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -19,10 +20,10 @@ fn grab_mouse(
|
||||||
let window = windows.primary_mut();
|
let window = windows.primary_mut();
|
||||||
if mouse.just_pressed(MouseButton::Left) {
|
if mouse.just_pressed(MouseButton::Left) {
|
||||||
window.set_cursor_visibility(false);
|
window.set_cursor_visibility(false);
|
||||||
window.set_cursor_lock_mode(true);
|
window.set_cursor_grab_mode(CursorGrabMode::Locked);
|
||||||
}
|
}
|
||||||
if key.just_pressed(KeyCode::Escape) {
|
if key.just_pressed(KeyCode::Escape) {
|
||||||
window.set_cursor_visibility(true);
|
window.set_cursor_visibility(true);
|
||||||
window.set_cursor_lock_mode(false);
|
window.set_cursor_grab_mode(CursorGrabMode::None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
window::PresentMode,
|
window::{CursorGrabMode, PresentMode},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -54,7 +54,10 @@ fn change_title(time: Res<Time>, mut windows: ResMut<Windows>) {
|
||||||
fn toggle_cursor(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
|
fn toggle_cursor(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
|
||||||
let window = windows.primary_mut();
|
let window = windows.primary_mut();
|
||||||
if input.just_pressed(KeyCode::Space) {
|
if input.just_pressed(KeyCode::Space) {
|
||||||
window.set_cursor_lock_mode(!window.cursor_locked());
|
window.set_cursor_grab_mode(match window.cursor_grab_mode() {
|
||||||
|
CursorGrabMode::None => CursorGrabMode::Locked,
|
||||||
|
CursorGrabMode::Locked | CursorGrabMode::Confined => CursorGrabMode::None,
|
||||||
|
});
|
||||||
window.set_cursor_visibility(!window.cursor_visible());
|
window.set_cursor_visibility(!window.cursor_visible());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue