diff --git a/Cargo.toml b/Cargo.toml index 2ebec265bd3de..9be0b0bd6e7b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -293,3 +293,4 @@ required-features = ["bevy_winit"] name = "assets_wasm" path = "examples/wasm/assets_wasm.rs" required-features = ["bevy_winit"] + diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 3112e8df8c6d2..7d2212667cc30 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -40,6 +40,8 @@ pub struct Window { vsync: bool, resizable: bool, decorations: bool, + cursor_visible: bool, + cursor_locked: bool, mode: WindowMode, #[cfg(target_arch = "wasm32")] pub canvas: Option, @@ -68,6 +70,12 @@ pub enum WindowCommand { SetDecorations { decorations: bool, }, + SetCursorLockMode { + locked: bool, + }, + SetCursorVisibility { + visible: bool, + }, } /// Defines the way a window is displayed @@ -92,6 +100,8 @@ impl Window { vsync: window_descriptor.vsync, resizable: window_descriptor.resizable, decorations: window_descriptor.decorations, + cursor_visible: window_descriptor.cursor_visible, + cursor_locked: window_descriptor.cursor_locked, mode: window_descriptor.mode, #[cfg(target_arch = "wasm32")] canvas: window_descriptor.canvas.clone(), @@ -165,6 +175,27 @@ impl Window { .push(WindowCommand::SetDecorations { decorations }); } + pub fn cursor_locked(&self) -> bool { + self.cursor_locked + } + + pub fn set_cursor_lock_mode(&mut self, lock_mode: bool) { + self.cursor_locked = lock_mode; + self.command_queue + .push(WindowCommand::SetCursorLockMode { locked: lock_mode }); + } + + pub fn cursor_visible(&self) -> bool { + self.cursor_visible + } + + pub fn set_cursor_visibility(&mut self, visibile_mode: bool) { + self.cursor_visible = visibile_mode; + self.command_queue.push(WindowCommand::SetCursorVisibility { + visible: visibile_mode, + }); + } + pub fn mode(&self) -> WindowMode { self.mode } @@ -191,6 +222,8 @@ pub struct WindowDescriptor { pub vsync: bool, pub resizable: bool, pub decorations: bool, + pub cursor_visible: bool, + pub cursor_locked: bool, pub mode: WindowMode, #[cfg(target_arch = "wasm32")] pub canvas: Option, @@ -210,6 +243,8 @@ impl Default for WindowDescriptor { vsync: true, resizable: true, decorations: true, + cursor_locked: false, + cursor_visible: true, mode: WindowMode::Windowed, #[cfg(target_arch = "wasm32")] canvas: None, diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index fd1a3626c9a79..5b47d1c9d9b87 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -84,6 +84,14 @@ fn change_window(_: &mut World, resources: &mut Resources) { let window = winit_windows.get_window(id).unwrap(); window.set_decorations(decorations); } + bevy_window::WindowCommand::SetCursorLockMode { locked } => { + let window = winit_windows.get_window(id).unwrap(); + window.set_cursor_grab(locked).unwrap(); + } + bevy_window::WindowCommand::SetCursorVisibility { visible } => { + let window = winit_windows.get_window(id).unwrap(); + window.set_cursor_visible(visible); + } } } } diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 2ee217a99dfea..774f624f46831 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -71,6 +71,11 @@ impl WinitWindows { let winit_window = winit_window_builder.build(&event_loop).unwrap(); + winit_window + .set_cursor_grab(window.cursor_locked()) + .unwrap(); + winit_window.set_cursor_visible(window.cursor_visible()); + self.window_id_to_winit .insert(window.id(), winit_window.id()); self.winit_to_window_id diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index 2930c0081d530..246775e953af5 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -13,6 +13,7 @@ fn main() { }) .add_default_plugins() .add_system(change_title.system()) + .add_system(toggle_cursor.system()) .run(); } @@ -24,3 +25,12 @@ fn change_title(time: Res