diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index ee2b431996fee..e70dad72655dd 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -281,7 +281,7 @@ impl App { /// /// # `run()` might not return /// - /// Calls to [`App::run()`] might never return. + /// Calls to [`App::run()`] will never return on iOS and Web. /// /// In simple and *headless* applications, one can expect that execution will /// proceed, normally, after calling [`run()`](App::run()) but this is not the case for @@ -292,10 +292,7 @@ impl App { /// window is closed and that event loop terminates – behavior of processes that /// do not is often platform dependent or undocumented. /// - /// By default, *Bevy* uses the `winit` crate for window creation. See - /// [`WinitSettings::return_from_run`](https://docs.rs/bevy/latest/bevy/winit/struct.WinitSettings.html#structfield.return_from_run) - /// for further discussion of this topic and for a mechanism to require that [`App::run()`] - /// *does* return – albeit one that carries its own caveats and disclaimers. + /// By default, *Bevy* uses the `winit` crate for window creation. /// /// # Panics /// diff --git a/crates/bevy_input/Cargo.toml b/crates/bevy_input/Cargo.toml index 4292633430b63..555aecd409a75 100644 --- a/crates/bevy_input/Cargo.toml +++ b/crates/bevy_input/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["bevy"] [features] default = [] -serialize = ["serde"] +serialize = ["serde", "smol_str/serde"] [dependencies] # bevy @@ -25,6 +25,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.12.0", features = [ # other serde = { version = "1", features = ["derive"], optional = true } thiserror = "1.0" +smol_str = "0.2" [dev-dependencies] bevy = { path = "../../", version = "0.12.0" } diff --git a/crates/bevy_input/src/input.rs b/crates/bevy_input/src/input.rs index bfcf8e9558735..b1ecd8c3ba79c 100644 --- a/crates/bevy_input/src/input.rs +++ b/crates/bevy_input/src/input.rs @@ -45,7 +45,7 @@ use bevy_ecs::schedule::State; ///[`DetectChangesMut::bypass_change_detection`]: bevy_ecs::change_detection::DetectChangesMut::bypass_change_detection #[derive(Debug, Clone, Resource, Reflect)] #[reflect(Default)] -pub struct Input { +pub struct Input { /// A collection of every button that is currently being pressed. pressed: HashSet, /// A collection of every button that has just been pressed. @@ -54,7 +54,7 @@ pub struct Input { just_released: HashSet, } -impl Default for Input { +impl Default for Input { fn default() -> Self { Self { pressed: Default::default(), @@ -66,12 +66,12 @@ impl Default for Input { impl Input where - T: Copy + Eq + Hash + Send + Sync + 'static, + T: Clone + Eq + Hash + Send + Sync + 'static, { /// Registers a press for the given `input`. pub fn press(&mut self, input: T) { // Returns `true` if the `input` wasn't pressed. - if self.pressed.insert(input) { + if self.pressed.insert(input.clone()) { self.just_pressed.insert(input); } } diff --git a/crates/bevy_input/src/keyboard.rs b/crates/bevy_input/src/keyboard.rs index 924649e226f57..73330617e0965 100644 --- a/crates/bevy_input/src/keyboard.rs +++ b/crates/bevy_input/src/keyboard.rs @@ -8,9 +8,12 @@ use bevy_ecs::{ system::ResMut, }; use bevy_reflect::Reflect; +use smol_str::SmolStr; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; +#[cfg(feature = "serialize")] +use serde::{Deserialize, Serialize}; /// A keyboard input event. /// @@ -21,7 +24,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// The event is consumed inside of the [`keyboard_input_system`] /// to update the [`Input`](crate::Input) resource. -#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] #[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", @@ -29,10 +32,11 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; reflect(Serialize, Deserialize) )] pub struct KeyboardInput { - /// The scan code of the key. - pub scan_code: u32, /// The key code of the key. - pub key_code: Option, + pub key_code: KeyCode, + /// The logical key code of the key. + pub logical_key: Key, + /// The press state of the key. pub state: ButtonState, /// Window that received the input. @@ -43,39 +47,70 @@ pub struct KeyboardInput { /// /// ## Differences /// -/// The main difference between the [`KeyboardInput`] event and the [`Input`] or [`Input`] resources is that +/// The main difference between the [`KeyboardInput`] event and the [`Input`] or [`Input`] resources is that /// the latter have convenient functions such as [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`]. pub fn keyboard_input_system( - mut scan_input: ResMut>, + mut logical_key_input: ResMut>, mut key_input: ResMut>, mut keyboard_input_events: EventReader, ) { // Avoid clearing if it's not empty to ensure change detection is not triggered. - scan_input.bypass_change_detection().clear(); + logical_key_input.bypass_change_detection().clear(); key_input.bypass_change_detection().clear(); for event in keyboard_input_events.read() { let KeyboardInput { - scan_code, state, .. + key_code, + logical_key, + state, + .. } = event; - if let Some(key_code) = event.key_code { - match state { - ButtonState::Pressed => key_input.press(key_code), - ButtonState::Released => key_input.release(key_code), - } + match state { + ButtonState::Pressed => key_input.press(*key_code), + ButtonState::Released => key_input.release(*key_code), } match state { - ButtonState::Pressed => scan_input.press(ScanCode(*scan_code)), - ButtonState::Released => scan_input.release(ScanCode(*scan_code)), + ButtonState::Pressed => logical_key_input.press(logical_key.clone()), + ButtonState::Released => logical_key_input.release(logical_key.clone()), } } } +/// Contains the platform-native physical key identifier +/// +/// The exact values vary from platform to platform (which is part of why this is a per-platform +/// enum), but the values are primarily tied to the key's physical location on the keyboard. +/// +/// This enum is primarily used to store raw keycodes when Winit doesn't map a given native +/// physical key identifier to a meaningful [`KeyCode`] variant. In the presence of identifiers we +/// haven't mapped for you yet, this lets you use use [`KeyCode`] to: +/// +/// - Correctly match key press and release events. +/// - On non-web platforms, support assigning keybinds to virtually any key through a UI. +#[derive(Debug, Clone, Ord, PartialOrd, Copy, PartialEq, Eq, Hash, Reflect)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub enum NativeKeyCode { + /// Unidentified + Unidentified, + /// An Android "scancode". + Android(u32), + /// A macOS "scancode". + MacOS(u16), + /// A Windows "scancode". + Windows(u16), + /// An XKB "keycode". + Xkb(u32), +} + /// The key code of a [`KeyboardInput`]. /// /// ## Usage /// /// It is used as the generic `T` value of an [`Input`] to create a `Res>`. -/// The resource values are mapped to the current layout of the keyboard and correlate to an [`ScanCode`]. +/// The resource values are mapped to the current layout of the keyboard and correlate to a [`NativeKeyCode`]. /// /// ## Updating /// @@ -89,375 +124,1264 @@ pub fn keyboard_input_system( )] #[repr(u32)] pub enum KeyCode { - /// The `1` key over the letters. - Key1, - /// The `2` key over the letters. - Key2, - /// The `3` key over the letters. - Key3, - /// The `4` key over the letters. - Key4, - /// The `5` key over the letters. - Key5, - /// The `6` key over the letters. - Key6, - /// The `7` key over the letters. - Key7, - /// The `8` key over the letters. - Key8, - /// The `9` key over the letters. - Key9, - /// The `0` key over the letters. - Key0, - - /// The `A` key. - A, - /// The `B` key. - B, - /// The `C` key. - C, - /// The `D` key. - D, - /// The `E` key. - E, - /// The `F` key. - F, - /// The `G` key. - G, - /// The `H` key. - H, - /// The `I` key. - I, - /// The `J` key. - J, - /// The `K` key. - K, - /// The `L` key. - L, - /// The `M` key. - M, - /// The `N` key. - N, - /// The `O` key. - O, - /// The `P` key. - P, - /// The `Q` key. - Q, - /// The `R` key. - R, - /// The `S` key. - S, - /// The `T` key. - T, - /// The `U` key. - U, - /// The `V` key. - V, - /// The `W` key. - W, - /// The `X` key. - X, - /// The `Y` key. - Y, - /// The `Z` key. - Z, - - /// The `Escape` / `ESC` key, next to the `F1` key. + /// This variant is used when the key cannot be translated to any other variant. + /// + /// The native keycode is provided (if available) so you're able to more reliably match + /// key-press and key-release events by hashing the [`KeyCode`]. It is also possible to use + /// this for keybinds for non-standard keys, but such keybinds are tied to a given platform. + Unidentified(NativeKeyCode), + /// ` on a US keyboard. This is also called a backtick or grave. + /// This is the 半角/全角/漢字 + /// (hankaku/zenkaku/kanji) key on Japanese keyboards + Backquote, + /// Used for both the US \\ (on the 101-key layout) and also for the key + /// located between the " and Enter keys on row C of the 102-, + /// 104- and 106-key layouts. + /// Labeled # on a UK (102) keyboard. + Backslash, + /// [ on a US keyboard. + BracketLeft, + /// ] on a US keyboard. + BracketRight, + /// , on a US keyboard. + Comma, + /// 0 on a US keyboard. + Digit0, + /// 1 on a US keyboard. + Digit1, + /// 2 on a US keyboard. + Digit2, + /// 3 on a US keyboard. + Digit3, + /// 4 on a US keyboard. + Digit4, + /// 5 on a US keyboard. + Digit5, + /// 6 on a US keyboard. + Digit6, + /// 7 on a US keyboard. + Digit7, + /// 8 on a US keyboard. + Digit8, + /// 9 on a US keyboard. + Digit9, + /// = on a US keyboard. + Equal, + /// Located between the left Shift and Z keys. + /// Labeled \\ on a UK keyboard. + IntlBackslash, + /// Located between the / and right Shift keys. + /// Labeled \\ (ro) on a Japanese keyboard. + IntlRo, + /// Located between the = and Backspace keys. + /// Labeled ¥ (yen) on a Japanese keyboard. \\ on a + /// Russian keyboard. + IntlYen, + /// a on a US keyboard. + /// Labeled q on an AZERTY (e.g., French) keyboard. + KeyA, + /// b on a US keyboard. + KeyB, + /// c on a US keyboard. + KeyC, + /// d on a US keyboard. + KeyD, + /// e on a US keyboard. + KeyE, + /// f on a US keyboard. + KeyF, + /// g on a US keyboard. + KeyG, + /// h on a US keyboard. + KeyH, + /// i on a US keyboard. + KeyI, + /// j on a US keyboard. + KeyJ, + /// k on a US keyboard. + KeyK, + /// l on a US keyboard. + KeyL, + /// m on a US keyboard. + KeyM, + /// n on a US keyboard. + KeyN, + /// o on a US keyboard. + KeyO, + /// p on a US keyboard. + KeyP, + /// q on a US keyboard. + /// Labeled a on an AZERTY (e.g., French) keyboard. + KeyQ, + /// r on a US keyboard. + KeyR, + /// s on a US keyboard. + KeyS, + /// t on a US keyboard. + KeyT, + /// u on a US keyboard. + KeyU, + /// v on a US keyboard. + KeyV, + /// w on a US keyboard. + /// Labeled z on an AZERTY (e.g., French) keyboard. + KeyW, + /// x on a US keyboard. + KeyX, + /// y on a US keyboard. + /// Labeled z on a QWERTZ (e.g., German) keyboard. + KeyY, + /// z on a US keyboard. + /// Labeled w on an AZERTY (e.g., French) keyboard, and y on a + /// QWERTZ (e.g., German) keyboard. + KeyZ, + /// - on a US keyboard. + Minus, + /// . on a US keyboard. + Period, + /// ' on a US keyboard. + Quote, + /// ; on a US keyboard. + Semicolon, + /// / on a US keyboard. + Slash, + /// Alt, Option, or . + AltLeft, + /// Alt, Option, or . + /// This is labeled AltGr on many keyboard layouts. + AltRight, + /// Backspace or . + /// Labeled Delete on Apple keyboards. + Backspace, + /// CapsLock or + CapsLock, + /// The application context menu key, which is typically found between the right + /// Super key and the right Control key. + ContextMenu, + /// Control or + ControlLeft, + /// Control or + ControlRight, + /// Enter or . Labeled Return on Apple keyboards. + Enter, + /// The Windows, , Command, or other OS symbol key. + SuperLeft, + /// The Windows, , Command, or other OS symbol key. + SuperRight, + /// Shift or + ShiftLeft, + /// Shift or + ShiftRight, + ///   (space) + Space, + /// Tab or + Tab, + /// Japanese: (henkan) + Convert, + /// Japanese: カタカナ/ひらがな/ローマ字 (katakana/hiragana/romaji) + KanaMode, + /// Korean: HangulMode 한/영 (han/yeong) + /// + /// Japanese (Mac keyboard): (kana) + Lang1, + /// Korean: Hanja (hanja) + /// + /// Japanese (Mac keyboard): (eisu) + Lang2, + /// Japanese (word-processing keyboard): Katakana + Lang3, + /// Japanese (word-processing keyboard): Hiragana + Lang4, + /// Japanese (word-processing keyboard): Zenkaku/Hankaku + Lang5, + /// Japanese: 無変換 (muhenkan) + NonConvert, + /// . The forward delete key. + /// Note that on Apple keyboards, the key labelled Delete on the main part of + /// the keyboard is encoded as [`Backspace`]. + /// + /// [`Backspace`]: Self::Backspace + Delete, + /// Page Down, End, or + End, + /// Help. Not present on standard PC keyboards. + Help, + /// Home or + Home, + /// Insert or Ins. Not present on Apple keyboards. + Insert, + /// Page Down, PgDn, or + PageDown, + /// Page Up, PgUp, or + PageUp, + /// + ArrowDown, + /// + ArrowLeft, + /// + ArrowRight, + /// + ArrowUp, + /// On the Mac, this is used for the numpad Clear key. + NumLock, + /// 0 Ins on a keyboard. 0 on a phone or remote control + Numpad0, + /// 1 End on a keyboard. 1 or 1 QZ on a phone or remote control + Numpad1, + /// 2 ↓ on a keyboard. 2 ABC on a phone or remote control + Numpad2, + /// 3 PgDn on a keyboard. 3 DEF on a phone or remote control + Numpad3, + /// 4 ← on a keyboard. 4 GHI on a phone or remote control + Numpad4, + /// 5 on a keyboard. 5 JKL on a phone or remote control + Numpad5, + /// 6 → on a keyboard. 6 MNO on a phone or remote control + Numpad6, + /// 7 Home on a keyboard. 7 PQRS or 7 PRS on a phone + /// or remote control + Numpad7, + /// 8 ↑ on a keyboard. 8 TUV on a phone or remote control + Numpad8, + /// 9 PgUp on a keyboard. 9 WXYZ or 9 WXY on a phone + /// or remote control + Numpad9, + /// + + NumpadAdd, + /// Found on the Microsoft Natural Keyboard. + NumpadBackspace, + /// C or A (All Clear). Also for use with numpads that have a + /// Clear key that is separate from the NumLock key. On the Mac, the + /// numpad Clear key is encoded as [`NumLock`]. + /// + /// [`NumLock`]: Self::NumLock + NumpadClear, + /// C (Clear Entry) + NumpadClearEntry, + /// , (thousands separator). For locales where the thousands separator + /// is a "." (e.g., Brazil), this key may generate a .. + NumpadComma, + /// . Del. For locales where the decimal separator is "," (e.g., + /// Brazil), this key may generate a ,. + NumpadDecimal, + /// / + NumpadDivide, + /// The Enter key on the numpad. + NumpadEnter, + /// = + NumpadEqual, + /// # on a phone or remote control device. This key is typically found + /// below the 9 key and to the right of the 0 key. + NumpadHash, + /// M Add current entry to the value stored in memory. + NumpadMemoryAdd, + /// M Clear the value stored in memory. + NumpadMemoryClear, + /// M Replace the current entry with the value stored in memory. + NumpadMemoryRecall, + /// M Replace the value stored in memory with the current entry. + NumpadMemoryStore, + /// M Subtract current entry from the value stored in memory. + NumpadMemorySubtract, + /// * on a keyboard. For use with numpads that provide mathematical + /// operations (+, - * and /). + /// + /// Use `NumpadStar` for the * key on phones and remote controls. + NumpadMultiply, + /// ( Found on the Microsoft Natural Keyboard. + NumpadParenLeft, + /// ) Found on the Microsoft Natural Keyboard. + NumpadParenRight, + /// * on a phone or remote control device. + /// + /// This key is typically found below the 7 key and to the left of + /// the 0 key. + /// + /// Use "NumpadMultiply" for the * key on + /// numeric keypads. + NumpadStar, + /// - + NumpadSubtract, + /// Esc or Escape, - - /// The `F1` key. + /// Fn This is typically a hardware key that does not generate a separate code. + Fn, + /// FLock or FnLock. Function Lock key. Found on the Microsoft + /// Natural Keyboard. + FnLock, + /// PrtScr SysRq or Print Screen + PrintScreen, + /// Scroll Lock + ScrollLock, + /// Pause Break + Pause, + /// Some laptops place this key to the left of the key. + /// + /// This also the "back" button (triangle) on Android. + BrowserBack, + /// BrowserFavorites + BrowserFavorites, + /// Some laptops place this key to the right of the key. + BrowserForward, + /// The "home" button on Android. + BrowserHome, + /// BrowserRefresh + BrowserRefresh, + /// BrowserSearch + BrowserSearch, + /// BrowserStop + BrowserStop, + /// Eject or . This key is placed in the function section on some Apple + /// keyboards. + Eject, + /// Sometimes labelled My Computer on the keyboard + LaunchApp1, + /// Sometimes labelled Calculator on the keyboard + LaunchApp2, + /// LaunchMail + LaunchMail, + /// MediaPlayPause + MediaPlayPause, + /// MediaSelect + MediaSelect, + /// MediaStop + MediaStop, + /// MediaTrackNext + MediaTrackNext, + /// MediaTrackPrevious + MediaTrackPrevious, + /// This key is placed in the function section on some Apple keyboards, replacing the + /// Eject key. + Power, + /// Sleep + Sleep, + /// AudioVolumeDown + AudioVolumeDown, + /// AudioVolumeMute + AudioVolumeMute, + /// AudioVolumeUp + AudioVolumeUp, + /// WakeUp + WakeUp, + /// Legacy modifier key. Also called "Super" in certain places. + Meta, + /// Legacy modifier key. + Hyper, + /// Turbo + Turbo, + /// Abort + Abort, + /// Resume + Resume, + /// Suspend + Suspend, + /// Found on Sun’s USB keyboard. + Again, + /// Found on Sun’s USB keyboard. + Copy, + /// Found on Sun’s USB keyboard. + Cut, + /// Found on Sun’s USB keyboard. + Find, + /// Found on Sun’s USB keyboard. + Open, + /// Found on Sun’s USB keyboard. + Paste, + /// Found on Sun’s USB keyboard. + Props, + /// Found on Sun’s USB keyboard. + Select, + /// Found on Sun’s USB keyboard. + Undo, + /// Use for dedicated ひらがな key found on some Japanese word processing keyboards. + Hiragana, + /// Use for dedicated カタカナ key found on some Japanese word processing keyboards. + Katakana, + /// General-purpose function key. + /// Usually found at the top of the keyboard. F1, - /// The `F2` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F2, - /// The `F3` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F3, - /// The `F4` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F4, - /// The `F5` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F5, - /// The `F6` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F6, - /// The `F7` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F7, - /// The `F8` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F8, - /// The `F9` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F9, - /// The `F10` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F10, - /// The `F11` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F11, - /// The `F12` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F12, - /// The `F13` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F13, - /// The `F14` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F14, - /// The `F15` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F15, - /// The `F16` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F16, - /// The `F17` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F17, - /// The `F18` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F18, - /// The `F19` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F19, - /// The `F20` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F20, - /// The `F21` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F21, - /// The `F22` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F22, - /// The `F23` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F23, - /// The `F24` key. + /// General-purpose function key. + /// Usually found at the top of the keyboard. F24, + /// General-purpose function key. + F25, + /// General-purpose function key. + F26, + /// General-purpose function key. + F27, + /// General-purpose function key. + F28, + /// General-purpose function key. + F29, + /// General-purpose function key. + F30, + /// General-purpose function key. + F31, + /// General-purpose function key. + F32, + /// General-purpose function key. + F33, + /// General-purpose function key. + F34, + /// General-purpose function key. + F35, +} - /// The `Snapshot` / `Print Screen` key. - Snapshot, - /// The `Scroll` / `Scroll Lock` key. - Scroll, - /// The `Pause` / `Break` key, next to the `Scroll` key. - Pause, - - /// The `Insert` key, next to the `Backspace` key. - Insert, - /// The `Home` key. - Home, - /// The `Delete` key. - Delete, - /// The `End` key. - End, - /// The `PageDown` key. - PageDown, - /// The `PageUp` key. - PageUp, - - /// The `Left` / `Left Arrow` key. - Left, - /// The `Up` / `Up Arrow` key. - Up, - /// The `Right` / `Right Arrow` key. - Right, - /// The `Down` / `Down Arrow` key. - Down, - - /// The `Back` / `Backspace` key. - Back, - /// The `Return` / `Enter` key. - Return, - /// The `Space` / `Spacebar` / ` ` key. - Space, - - /// The `Compose` key on Linux. - Compose, - /// The `Caret` / `^` key. - Caret, - - /// The `Numlock` key. - Numlock, - /// The `Numpad0` / `0` key. - Numpad0, - /// The `Numpad1` / `1` key. - Numpad1, - /// The `Numpad2` / `2` key. - Numpad2, - /// The `Numpad3` / `3` key. - Numpad3, - /// The `Numpad4` / `4` key. - Numpad4, - /// The `Numpad5` / `5` key. - Numpad5, - /// The `Numpad6` / `6` key. - Numpad6, - /// The `Numpad7` / `7` key. - Numpad7, - /// The `Numpad8` / `8` key. - Numpad8, - /// The `Numpad9` / `9` key. - Numpad9, - - /// The `AbntC1` key. - AbntC1, - /// The `AbntC2` key. - AbntC2, - - /// The `NumpadAdd` / `+` key. - NumpadAdd, - /// The `Apostrophe` / `'` key. - Apostrophe, - /// The `Apps` key. - Apps, - /// The `Asterisk` / `*` key. - Asterisk, - /// The `Plus` / `+` key. - Plus, - /// The `At` / `@` key. - At, - /// The `Ax` key. - Ax, - /// The `Backslash` / `\` key. - Backslash, - /// The `Calculator` key. - Calculator, - /// The `Capital` key. - Capital, - /// The `Colon` / `:` key. - Colon, - /// The `Comma` / `,` key. - Comma, - /// The `Convert` key. - Convert, - /// The `NumpadDecimal` / `.` key. - NumpadDecimal, - /// The `NumpadDivide` / `/` key. - NumpadDivide, - /// The `Equals` / `=` key. - Equals, - /// The `Grave` / `Backtick` / `` ` `` key. - Grave, - /// The `Kana` key. - Kana, - /// The `Kanji` key. - Kanji, - - /// The `Left Alt` key. Maps to `Left Option` on Mac. - AltLeft, - /// The `Left Bracket` / `[` key. - BracketLeft, - /// The `Left Control` key. - ControlLeft, - /// The `Left Shift` key. - ShiftLeft, - /// The `Left Super` key. - /// Generic keyboards usually display this key with the *Microsoft Windows* logo. - /// Apple keyboards call this key the *Command Key* and display it using the ⌘ character. - #[doc(alias("LWin", "LMeta", "LLogo"))] - SuperLeft, - - /// The `Mail` key. - Mail, - /// The `MediaSelect` key. - MediaSelect, - /// The `MediaStop` key. - MediaStop, - /// The `Minus` / `-` key. - Minus, - /// The `NumpadMultiply` / `*` key. - NumpadMultiply, - /// The `Mute` key. - Mute, - /// The `MyComputer` key. - MyComputer, - /// The `NavigateForward` / `Prior` key. - NavigateForward, - /// The `NavigateBackward` / `Next` key. - NavigateBackward, - /// The `NextTrack` key. - NextTrack, - /// The `NoConvert` key. - NoConvert, - /// The `NumpadComma` / `,` key. - NumpadComma, - /// The `NumpadEnter` key. - NumpadEnter, - /// The `NumpadEquals` / `=` key. - NumpadEquals, - /// The `Oem102` key. - Oem102, - /// The `Period` / `.` key. - Period, - /// The `PlayPause` key. - PlayPause, - /// The `Power` key. - Power, - /// The `PrevTrack` key. - PrevTrack, - - /// The `Right Alt` key. Maps to `Right Option` on Mac. - AltRight, - /// The `Right Bracket` / `]` key. - BracketRight, - /// The `Right Control` key. - ControlRight, - /// The `Right Shift` key. - ShiftRight, - /// The `Right Super` key. - /// Generic keyboards usually display this key with the *Microsoft Windows* logo. - /// Apple keyboards call this key the *Command Key* and display it using the ⌘ character. - #[doc(alias("RWin", "RMeta", "RLogo"))] - SuperRight, - - /// The `Semicolon` / `;` key. - Semicolon, - /// The `Slash` / `/` key. - Slash, - /// The `Sleep` key. - Sleep, - /// The `Stop` key. - Stop, - /// The `NumpadSubtract` / `-` key. - NumpadSubtract, - /// The `Sysrq` key. - Sysrq, - /// The `Tab` / ` ` key. - Tab, - /// The `Underline` / `_` key. - Underline, - /// The `Unlabeled` key. - Unlabeled, - - /// The `VolumeDown` key. - VolumeDown, - /// The `VolumeUp` key. - VolumeUp, - - /// The `Wake` key. - Wake, - - /// The `WebBack` key. - WebBack, - /// The `WebFavorites` key. - WebFavorites, - /// The `WebForward` key. - WebForward, - /// The `WebHome` key. - WebHome, - /// The `WebRefresh` key. - WebRefresh, - /// The `WebSearch` key. - WebSearch, - /// The `WebStop` key. - WebStop, - - /// The `Yen` key. - Yen, - - /// The `Copy` key. - Copy, - /// The `Paste` key. - Paste, - /// The `Cut` key. - Cut, +/// Contains the platform-native logical key identifier +/// +/// Exactly what that means differs from platform to platform, but the values are to some degree +/// tied to the currently active keyboard layout. The same key on the same keyboard may also report +/// different values on different platforms, which is one of the reasons this is a per-platform +/// enum. +/// +/// This enum is primarily used to store raw keysym when Winit doesn't map a given native logical +/// key identifier to a meaningful [`Key`] variant. This lets you use [`Key`], and let the user +/// define keybinds which work in the presence of identifiers we haven't mapped for you yet. +#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq, Hash, Reflect)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +pub enum NativeKey { + /// Unidentified + Unidentified, + /// An Android "keycode", which is similar to a "virtual-key code" on Windows. + Android(u32), + /// A macOS "scancode". There does not appear to be any direct analogue to either keysyms or + /// "virtual-key" codes in macOS, so we report the scancode instead. + MacOS(u16), + /// A Windows "virtual-key code". + Windows(u16), + /// An XKB "keysym". + Xkb(u32), + /// A "key value string". + // TOCLEAN: Thierry: this is originally SmolStr, but difficult to translate to FromReflect. + Web(SmolStr), } -/// The scan code of a [`KeyboardInput`]. +/// The logical key code of a [`KeyboardInput`]. /// /// ## Usage /// -/// It is used as the generic `` value of an [`Input`] to create a `Res>`. -/// The resource values are mapped to the physical location of a key on the keyboard and correlate to an [`KeyCode`] +/// It is used as the generic `T` value of an [`Input`] to create a `Res>`. +/// The resource values are mapped to the current layout of the keyboard and correlate to a [`KeyCode`]. /// /// ## Updating /// /// The resource is updated inside of the [`keyboard_input_system`]. -#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Reflect)] +/// +/// ## Technical +/// +/// Its values map 1 to 1 to winit's Key. +#[non_exhaustive] +#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Reflect)] #[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -pub struct ScanCode(pub u32); +pub enum Key { + /// A key string that corresponds to the character typed by the user, taking into account the + /// user’s current locale setting, and any system-level keyboard mapping overrides that are in + /// effect. + Character(SmolStr), + + /// This variant is used when the key cannot be translated to any other variant. + /// + /// The native key is provided (if available) in order to allow the user to specify keybindings + /// for keys which are not defined by this API, mainly through some sort of UI. + Unidentified(NativeKey), + + /// Contains the text representation of the dead-key when available. + /// + /// ## Platform-specific + /// - **Web:** Always contains `None` + Dead(Option), + + /// The `Alt` (Alternative) key. + /// + /// This key enables the alternate modifier function for interpreting concurrent or subsequent + /// keyboard input. This key value is also used for the Apple Option key. + Alt, + /// The Alternate Graphics (AltGr or AltGraph) key. + /// + /// This key is used enable the ISO Level 3 shift modifier (the standard `Shift` key is the + /// level 2 modifier). + AltGraph, + /// The `Caps Lock` (Capital) key. + /// + /// Toggle capital character lock function for interpreting subsequent keyboard input event. + CapsLock, + /// The `Control` or `Ctrl` key. + /// + /// Used to enable control modifier function for interpreting concurrent or subsequent keyboard + /// input. + Control, + /// The Function switch `Fn` key. Activating this key simultaneously with another key changes + /// that key’s value to an alternate character or function. This key is often handled directly + /// in the keyboard hardware and does not usually generate key events. + Fn, + /// The Function-Lock (`FnLock` or `F-Lock`) key. Activating this key switches the mode of the + /// keyboard to changes some keys' values to an alternate character or function. This key is + /// often handled directly in the keyboard hardware and does not usually generate key events. + FnLock, + /// The `NumLock` or Number Lock key. Used to toggle numpad mode function for interpreting + /// subsequent keyboard input. + NumLock, + /// Toggle between scrolling and cursor movement modes. + ScrollLock, + /// Used to enable shift modifier function for interpreting concurrent or subsequent keyboard + /// input. + Shift, + /// The Symbol modifier key (used on some virtual keyboards). + Symbol, + /// The SymbolLock key, only on web. + SymbolLock, + /// Legacy modifier key. Also called "Super" in certain places. + Meta, + /// Legacy modifier key. + Hyper, + /// Used to enable "super" modifier function for interpreting concurrent or subsequent keyboard + /// input. This key value is used for the "Windows Logo" key and the Apple `Command` or `⌘` key. + /// + /// Note: In some contexts (e.g. the Web) this is referred to as the "Meta" key. + Super, + /// The `Enter` or `↵` key. Used to activate current selection or accept current input. This key + /// value is also used for the `Return` (Macintosh numpad) key. This key value is also used for + /// the Android `KEYCODE_DPAD_CENTER`. + Enter, + /// The Horizontal Tabulation `Tab` key. + Tab, + /// Used in text to insert a space between words. Usually located below the character keys. + Space, + /// Navigate or traverse downward. (`KEYCODE_DPAD_DOWN`) + ArrowDown, + /// Navigate or traverse leftward. (`KEYCODE_DPAD_LEFT`) + ArrowLeft, + /// Navigate or traverse rightward. (`KEYCODE_DPAD_RIGHT`) + ArrowRight, + /// Navigate or traverse upward. (`KEYCODE_DPAD_UP`) + ArrowUp, + /// The End key, used with keyboard entry to go to the end of content (`KEYCODE_MOVE_END`). + End, + /// The Home key, used with keyboard entry, to go to start of content (`KEYCODE_MOVE_HOME`). + /// For the mobile phone `Home` key (which goes to the phone’s main screen), use [`GoHome`]. + /// + /// [`GoHome`]: Self::GoHome + Home, + /// Scroll down or display next page of content. + PageDown, + /// Scroll up or display previous page of content. + PageUp, + /// Used to remove the character to the left of the cursor. This key value is also used for + /// the key labeled `Delete` on MacOS keyboards. + Backspace, + /// Remove the currently selected input. + Clear, + /// Copy the current selection. (`APPCOMMAND_COPY`) + Copy, + /// The Cursor Select key. + CrSel, + /// Cut the current selection. (`APPCOMMAND_CUT`) + Cut, + /// Used to delete the character to the right of the cursor. This key value is also used for the + /// key labeled `Delete` on MacOS keyboards when `Fn` is active. + Delete, + /// The Erase to End of Field key. This key deletes all characters from the current cursor + /// position to the end of the current field. + EraseEof, + /// The Extend Selection (Exsel) key. + ExSel, + /// Toggle between text modes for insertion or overtyping. + /// (`KEYCODE_INSERT`) + Insert, + /// The Paste key. (`APPCOMMAND_PASTE`) + Paste, + /// Redo the last action. (`APPCOMMAND_REDO`) + Redo, + /// Undo the last action. (`APPCOMMAND_UNDO`) + Undo, + /// The Accept (Commit, OK) key. Accept current option or input method sequence conversion. + Accept, + /// Redo or repeat an action. + Again, + /// The Attention (Attn) key. + Attn, + /// The Cancel key. (on linux and web) + Cancel, + /// Show the application’s context menu. + /// This key is commonly found between the right `Super` key and the right `Control` key. + ContextMenu, + /// The `Esc` key. This key was originally used to initiate an escape sequence, but is + /// now more generally used to exit or "escape" the current context, such as closing a dialog + /// or exiting full screen mode. + Escape, + /// The Execute key. + Execute, + /// Open the Find dialog. (`APPCOMMAND_FIND`) + Find, + /// Open a help dialog or toggle display of help information. (`APPCOMMAND_HELP`, + /// `KEYCODE_HELP`) + Help, + /// Pause the current state or application (as appropriate). + /// + /// Note: Do not use this value for the `Pause` button on media controllers. Use `"MediaPause"` + /// instead. + Pause, + /// Play or resume the current state or application (as appropriate). + /// + /// Note: Do not use this value for the `Play` button on media controllers. Use `"MediaPlay"` + /// instead. + Play, + /// The properties (Props) key. + Props, + /// The Select key. + Select, + /// The ZoomIn key. (`KEYCODE_ZOOM_IN`) + ZoomIn, + /// The ZoomOut key. (`KEYCODE_ZOOM_OUT`) + ZoomOut, + /// The Brightness Down key. Typically controls the display brightness. + /// (`KEYCODE_BRIGHTNESS_DOWN`) + BrightnessDown, + /// The Brightness Up key. Typically controls the display brightness. (`KEYCODE_BRIGHTNESS_UP`) + BrightnessUp, + /// Toggle removable media to eject (open) and insert (close) state. (`KEYCODE_MEDIA_EJECT`) + Eject, + /// LogOff + LogOff, + /// Toggle power state. (`KEYCODE_POWER`) + /// Note: Note: Some devices might not expose this key to the operating environment. + Power, + /// The `PowerOff` key. Sometime called `PowerDown`. + PowerOff, + /// Initiate print-screen function. + PrintScreen, + /// The Hibernate key. This key saves the current state of the computer to disk so that it can + /// be restored. The computer will then shutdown. + Hibernate, + /// The Standby key. This key turns off the display and places the computer into a low-power + /// mode without completely shutting down. It is sometimes labelled `Suspend` or `Sleep` key. + /// (`KEYCODE_SLEEP`) + Standby, + /// The WakeUp key. (`KEYCODE_WAKEUP`) + WakeUp, + /// Initate the multi-candidate mode. + AllCandidates, + /// The Alphanumeric key (on linux/web) + Alphanumeric, + /// Initiate the Code Input mode to allow characters to be entered by + /// their code points. + CodeInput, + /// The Compose key, also known as "Multi_key" on the X Window System. This key acts in a + /// manner similar to a dead key, triggering a mode where subsequent key presses are combined to + /// produce a different character. + Compose, + /// Convert the current input method sequence. + Convert, + /// The Final Mode `Final` key used on some Asian keyboards, to enable the final mode for IMEs. + FinalMode, + /// Switch to the first character group. (ISO/IEC 9995) + GroupFirst, + /// Switch to the last character group. (ISO/IEC 9995) + GroupLast, + /// Switch to the next character group. (ISO/IEC 9995) + GroupNext, + /// Switch to the previous character group. (ISO/IEC 9995) + GroupPrevious, + /// Toggle between or cycle through input modes of IMEs. + ModeChange, + /// NextCandidate, web only. + NextCandidate, + /// Accept current input method sequence without + /// conversion in IMEs. + NonConvert, + /// PreviousCandidate, web only. + PreviousCandidate, + /// IME PROCESS key + Process, + /// SingleCandidate + SingleCandidate, + /// Toggle between Hangul and English modes. + HangulMode, + /// HanjaMode + HanjaMode, + /// JunjaMode + JunjaMode, + /// The Eisu key. This key may close the IME, but its purpose is defined by the current IME. + /// (`KEYCODE_EISU`) + Eisu, + /// The (Half-Width) Characters key. + Hankaku, + /// The Hiragana (Japanese Kana characters) key. + Hiragana, + /// The Hiragana/Katakana toggle key. (`KEYCODE_KATAKANA_HIRAGANA`) + HiraganaKatakana, + /// The Kana Mode (Kana Lock) key. This key is used to enter hiragana mode (typically from + /// romaji mode). + KanaMode, + /// The Kanji (Japanese name for ideographic characters of Chinese origin) Mode key. This key is + /// typically used to switch to a hiragana keyboard for the purpose of converting input into + /// kanji. (`KEYCODE_KANA`) + KanjiMode, + /// The Katakana (Japanese Kana characters) key. + Katakana, + /// The Roman characters function key. + Romaji, + /// The Zenkaku (Full-Width) Characters key. + Zenkaku, + /// The Zenkaku/Hankaku (full-width/half-width) toggle key. (`KEYCODE_ZENKAKU_HANKAKU`) + ZenkakuHankaku, + /// General purpose virtual function key, as index 1. + Soft1, + /// General purpose virtual function key, as index 2. + Soft2, + /// General purpose virtual function key, as index 3. + Soft3, + /// General purpose virtual function key, as index 4. + Soft4, + /// Select next (numerically or logically) lower channel. (`APPCOMMAND_MEDIA_CHANNEL_DOWN`, + /// `KEYCODE_CHANNEL_DOWN`) + ChannelDown, + /// Select next (numerically or logically) higher channel. (`APPCOMMAND_MEDIA_CHANNEL_UP`, + /// `KEYCODE_CHANNEL_UP`) + ChannelUp, + /// Close the current document or message (Note: This doesn’t close the application). + /// (`APPCOMMAND_CLOSE`) + Close, + /// Open an editor to forward the current message. (`APPCOMMAND_FORWARD_MAIL`) + MailForward, + /// Open an editor to reply to the current message. (`APPCOMMAND_REPLY_TO_MAIL`) + MailReply, + /// Send the current message. (`APPCOMMAND_SEND_MAIL`) + MailSend, + /// Close the current media, for example to close a CD or DVD tray. (`KEYCODE_MEDIA_CLOSE`) + MediaClose, + /// Initiate or continue forward playback at faster than normal speed, or increase speed if + /// already fast forwarding. (`APPCOMMAND_MEDIA_FAST_FORWARD`, `KEYCODE_MEDIA_FAST_FORWARD`) + MediaFastForward, + /// Pause the currently playing media. (`APPCOMMAND_MEDIA_PAUSE`, `KEYCODE_MEDIA_PAUSE`) + /// + /// Note: Media controller devices should use this value rather than `"Pause"` for their pause + /// keys. + MediaPause, + /// Initiate or continue media playback at normal speed, if not currently playing at normal + /// speed. (`APPCOMMAND_MEDIA_PLAY`, `KEYCODE_MEDIA_PLAY`) + MediaPlay, + /// Toggle media between play and pause states. (`APPCOMMAND_MEDIA_PLAY_PAUSE`, + /// `KEYCODE_MEDIA_PLAY_PAUSE`) + MediaPlayPause, + /// Initiate or resume recording of currently selected media. (`APPCOMMAND_MEDIA_RECORD`, + /// `KEYCODE_MEDIA_RECORD`) + MediaRecord, + /// Initiate or continue reverse playback at faster than normal speed, or increase speed if + /// already rewinding. (`APPCOMMAND_MEDIA_REWIND`, `KEYCODE_MEDIA_REWIND`) + MediaRewind, + /// Stop media playing, pausing, forwarding, rewinding, or recording, if not already stopped. + /// (`APPCOMMAND_MEDIA_STOP`, `KEYCODE_MEDIA_STOP`) + MediaStop, + /// Seek to next media or program track. (`APPCOMMAND_MEDIA_NEXTTRACK`, `KEYCODE_MEDIA_NEXT`) + MediaTrackNext, + /// Seek to previous media or program track. (`APPCOMMAND_MEDIA_PREVIOUSTRACK`, + /// `KEYCODE_MEDIA_PREVIOUS`) + MediaTrackPrevious, + /// Open a new document or message. (`APPCOMMAND_NEW`) + New, + /// Open an existing document or message. (`APPCOMMAND_OPEN`) + Open, + /// Print the current document or message. (`APPCOMMAND_PRINT`) + Print, + /// Save the current document or message. (`APPCOMMAND_SAVE`) + Save, + /// Spellcheck the current document or selection. (`APPCOMMAND_SPELL_CHECK`) + SpellCheck, + /// The `11` key found on media numpads that + /// have buttons from `1` ... `12`. + Key11, + /// The `12` key found on media numpads that + /// have buttons from `1` ... `12`. + Key12, + /// Adjust audio balance leftward. (`VK_AUDIO_BALANCE_LEFT`) + AudioBalanceLeft, + /// Adjust audio balance rightward. (`VK_AUDIO_BALANCE_RIGHT`) + AudioBalanceRight, + /// Decrease audio bass boost or cycle down through bass boost states. (`APPCOMMAND_BASS_DOWN`, + /// `VK_BASS_BOOST_DOWN`) + AudioBassBoostDown, + /// Toggle bass boost on/off. (`APPCOMMAND_BASS_BOOST`) + AudioBassBoostToggle, + /// Increase audio bass boost or cycle up through bass boost states. (`APPCOMMAND_BASS_UP`, + /// `VK_BASS_BOOST_UP`) + AudioBassBoostUp, + /// Adjust audio fader towards front. (`VK_FADER_FRONT`) + AudioFaderFront, + /// Adjust audio fader towards rear. (`VK_FADER_REAR`) + AudioFaderRear, + /// Advance surround audio mode to next available mode. (`VK_SURROUND_MODE_NEXT`) + AudioSurroundModeNext, + /// Decrease treble. (`APPCOMMAND_TREBLE_DOWN`) + AudioTrebleDown, + /// Increase treble. (`APPCOMMAND_TREBLE_UP`) + AudioTrebleUp, + /// Decrease audio volume. (`APPCOMMAND_VOLUME_DOWN`, `KEYCODE_VOLUME_DOWN`) + AudioVolumeDown, + /// Increase audio volume. (`APPCOMMAND_VOLUME_UP`, `KEYCODE_VOLUME_UP`) + AudioVolumeUp, + /// Toggle between muted state and prior volume level. (`APPCOMMAND_VOLUME_MUTE`, + /// `KEYCODE_VOLUME_MUTE`) + AudioVolumeMute, + /// Toggle the microphone on/off. (`APPCOMMAND_MIC_ON_OFF_TOGGLE`) + MicrophoneToggle, + /// Decrease microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_DOWN`) + MicrophoneVolumeDown, + /// Increase microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_UP`) + MicrophoneVolumeUp, + /// Mute the microphone. (`APPCOMMAND_MICROPHONE_VOLUME_MUTE`, `KEYCODE_MUTE`) + MicrophoneVolumeMute, + /// Show correction list when a word is incorrectly identified. (`APPCOMMAND_CORRECTION_LIST`) + SpeechCorrectionList, + /// Toggle between dictation mode and command/control mode. + /// (`APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE`) + SpeechInputToggle, + /// The first generic "LaunchApplication" key. This is commonly associated with launching "My + /// Computer", and may have a computer symbol on the key. (`APPCOMMAND_LAUNCH_APP1`) + LaunchApplication1, + /// The second generic "LaunchApplication" key. This is commonly associated with launching + /// "Calculator", and may have a calculator symbol on the key. (`APPCOMMAND_LAUNCH_APP2`, + /// `KEYCODE_CALCULATOR`) + LaunchApplication2, + /// The "Calendar" key. (`KEYCODE_CALENDAR`) + LaunchCalendar, + /// The "Contacts" key. (`KEYCODE_CONTACTS`) + LaunchContacts, + /// The "Mail" key. (`APPCOMMAND_LAUNCH_MAIL`) + LaunchMail, + /// The "Media Player" key. (`APPCOMMAND_LAUNCH_MEDIA_SELECT`) + LaunchMediaPlayer, + /// LaunchMusicPlayer + LaunchMusicPlayer, + /// LaunchPhone + LaunchPhone, + /// LaunchScreenSaver + LaunchScreenSaver, + /// LaunchSpreadsheet + LaunchSpreadsheet, + /// LaunchWebBrowser + LaunchWebBrowser, + /// LaunchWebCam + LaunchWebCam, + /// LaunchWordProcessor + LaunchWordProcessor, + /// Navigate to previous content or page in current history. (`APPCOMMAND_BROWSER_BACKWARD`) + BrowserBack, + /// Open the list of browser favorites. (`APPCOMMAND_BROWSER_FAVORITES`) + BrowserFavorites, + /// Navigate to next content or page in current history. (`APPCOMMAND_BROWSER_FORWARD`) + BrowserForward, + /// Go to the user’s preferred home page. (`APPCOMMAND_BROWSER_HOME`) + BrowserHome, + /// Refresh the current page or content. (`APPCOMMAND_BROWSER_REFRESH`) + BrowserRefresh, + /// Call up the user’s preferred search page. (`APPCOMMAND_BROWSER_SEARCH`) + BrowserSearch, + /// Stop loading the current page or content. (`APPCOMMAND_BROWSER_STOP`) + BrowserStop, + /// The Application switch key, which provides a list of recent apps to switch between. + /// (`KEYCODE_APP_SWITCH`) + AppSwitch, + /// The Call key. (`KEYCODE_CALL`) + Call, + /// The Camera key. (`KEYCODE_CAMERA`) + Camera, + /// The Camera focus key. (`KEYCODE_FOCUS`) + CameraFocus, + /// The End Call key. (`KEYCODE_ENDCALL`) + EndCall, + /// The Back key. (`KEYCODE_BACK`) + GoBack, + /// The Home key, which goes to the phone’s main screen. (`KEYCODE_HOME`) + GoHome, + /// The Headset Hook key. (`KEYCODE_HEADSETHOOK`) + HeadsetHook, + /// LastNumberRedial + LastNumberRedial, + /// The Notification key. (`KEYCODE_NOTIFICATION`) + Notification, + /// Toggle between manner mode state: silent, vibrate, ring, ... (`KEYCODE_MANNER_MODE`) + MannerMode, + /// VoiceDial + VoiceDial, + /// Switch to viewing TV. (`KEYCODE_TV`) + TV, + /// TV 3D Mode. (`KEYCODE_3D_MODE`) + TV3DMode, + /// Toggle between antenna and cable input. (`KEYCODE_TV_ANTENNA_CABLE`) + TVAntennaCable, + /// Audio description. (`KEYCODE_TV_AUDIO_DESCRIPTION`) + TVAudioDescription, + /// Audio description mixing volume down. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN`) + TVAudioDescriptionMixDown, + /// Audio description mixing volume up. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP`) + TVAudioDescriptionMixUp, + /// Contents menu. (`KEYCODE_TV_CONTENTS_MENU`) + TVContentsMenu, + /// Contents menu. (`KEYCODE_TV_DATA_SERVICE`) + TVDataService, + /// Switch the input mode on an external TV. (`KEYCODE_TV_INPUT`) + TVInput, + /// Switch to component input #1. (`KEYCODE_TV_INPUT_COMPONENT_1`) + TVInputComponent1, + /// Switch to component input #2. (`KEYCODE_TV_INPUT_COMPONENT_2`) + TVInputComponent2, + /// Switch to composite input #1. (`KEYCODE_TV_INPUT_COMPOSITE_1`) + TVInputComposite1, + /// Switch to composite input #2. (`KEYCODE_TV_INPUT_COMPOSITE_2`) + TVInputComposite2, + /// Switch to HDMI input #1. (`KEYCODE_TV_INPUT_HDMI_1`) + TVInputHDMI1, + /// Switch to HDMI input #2. (`KEYCODE_TV_INPUT_HDMI_2`) + TVInputHDMI2, + /// Switch to HDMI input #3. (`KEYCODE_TV_INPUT_HDMI_3`) + TVInputHDMI3, + /// Switch to HDMI input #4. (`KEYCODE_TV_INPUT_HDMI_4`) + TVInputHDMI4, + /// Switch to VGA input #1. (`KEYCODE_TV_INPUT_VGA_1`) + TVInputVGA1, + /// Media context menu. (`KEYCODE_TV_MEDIA_CONTEXT_MENU`) + TVMediaContext, + /// Toggle network. (`KEYCODE_TV_NETWORK`) + TVNetwork, + /// Number entry. (`KEYCODE_TV_NUMBER_ENTRY`) + TVNumberEntry, + /// Toggle the power on an external TV. (`KEYCODE_TV_POWER`) + TVPower, + /// Radio. (`KEYCODE_TV_RADIO_SERVICE`) + TVRadioService, + /// Satellite. (`KEYCODE_TV_SATELLITE`) + TVSatellite, + /// Broadcast Satellite. (`KEYCODE_TV_SATELLITE_BS`) + TVSatelliteBS, + /// Communication Satellite. (`KEYCODE_TV_SATELLITE_CS`) + TVSatelliteCS, + /// Toggle between available satellites. (`KEYCODE_TV_SATELLITE_SERVICE`) + TVSatelliteToggle, + /// Analog Terrestrial. (`KEYCODE_TV_TERRESTRIAL_ANALOG`) + TVTerrestrialAnalog, + /// Digital Terrestrial. (`KEYCODE_TV_TERRESTRIAL_DIGITAL`) + TVTerrestrialDigital, + /// Timer programming. (`KEYCODE_TV_TIMER_PROGRAMMING`) + TVTimer, + /// Switch the input mode on an external AVR (audio/video receiver). (`KEYCODE_AVR_INPUT`) + AVRInput, + /// Toggle the power on an external AVR (audio/video receiver). (`KEYCODE_AVR_POWER`) + AVRPower, + /// General purpose color-coded media function key, as index 0 (red). (`VK_COLORED_KEY_0`, + /// `KEYCODE_PROG_RED`) + ColorF0Red, + /// General purpose color-coded media function key, as index 1 (green). (`VK_COLORED_KEY_1`, + /// `KEYCODE_PROG_GREEN`) + ColorF1Green, + /// General purpose color-coded media function key, as index 2 (yellow). (`VK_COLORED_KEY_2`, + /// `KEYCODE_PROG_YELLOW`) + ColorF2Yellow, + /// General purpose color-coded media function key, as index 3 (blue). (`VK_COLORED_KEY_3`, + /// `KEYCODE_PROG_BLUE`) + ColorF3Blue, + /// General purpose color-coded media function key, as index 4 (grey). (`VK_COLORED_KEY_4`) + ColorF4Grey, + /// General purpose color-coded media function key, as index 5 (brown). (`VK_COLORED_KEY_5`) + ColorF5Brown, + /// Toggle the display of Closed Captions. (`VK_CC`, `KEYCODE_CAPTIONS`) + ClosedCaptionToggle, + /// Adjust brightness of device, by toggling between or cycling through states. (`VK_DIMMER`) + Dimmer, + /// Swap video sources. (`VK_DISPLAY_SWAP`) + DisplaySwap, + /// Select Digital Video Rrecorder. (`KEYCODE_DVR`) + DVR, + /// Exit the current application. (`VK_EXIT`) + Exit, + /// Clear program or content stored as favorite 0. (`VK_CLEAR_FAVORITE_0`) + FavoriteClear0, + /// Clear program or content stored as favorite 1. (`VK_CLEAR_FAVORITE_1`) + FavoriteClear1, + /// Clear program or content stored as favorite 2. (`VK_CLEAR_FAVORITE_2`) + FavoriteClear2, + /// Clear program or content stored as favorite 3. (`VK_CLEAR_FAVORITE_3`) + FavoriteClear3, + /// Select (recall) program or content stored as favorite 0. (`VK_RECALL_FAVORITE_0`) + FavoriteRecall0, + /// Select (recall) program or content stored as favorite 1. (`VK_RECALL_FAVORITE_1`) + FavoriteRecall1, + /// Select (recall) program or content stored as favorite 2. (`VK_RECALL_FAVORITE_2`) + FavoriteRecall2, + /// Select (recall) program or content stored as favorite 3. (`VK_RECALL_FAVORITE_3`) + FavoriteRecall3, + /// Store current program or content as favorite 0. (`VK_STORE_FAVORITE_0`) + FavoriteStore0, + /// Store current program or content as favorite 1. (`VK_STORE_FAVORITE_1`) + FavoriteStore1, + /// Store current program or content as favorite 2. (`VK_STORE_FAVORITE_2`) + FavoriteStore2, + /// Store current program or content as favorite 3. (`VK_STORE_FAVORITE_3`) + FavoriteStore3, + /// Toggle display of program or content guide. (`VK_GUIDE`, `KEYCODE_GUIDE`) + Guide, + /// If guide is active and displayed, then display next day’s content. (`VK_NEXT_DAY`) + GuideNextDay, + /// If guide is active and displayed, then display previous day’s content. (`VK_PREV_DAY`) + GuidePreviousDay, + /// Toggle display of information about currently selected context or media. (`VK_INFO`, + /// `KEYCODE_INFO`) + Info, + /// Toggle instant replay. (`VK_INSTANT_REPLAY`) + InstantReplay, + /// Launch linked content, if available and appropriate. (`VK_LINK`) + Link, + /// List the current program. (`VK_LIST`) + ListProgram, + /// Toggle display listing of currently available live content or programs. (`VK_LIVE`) + LiveContent, + /// Lock or unlock current content or program. (`VK_LOCK`) + Lock, + /// Show a list of media applications: audio/video players and image viewers. (`VK_APPS`) + /// + /// Note: Do not confuse this key value with the Windows' `VK_APPS` / `VK_CONTEXT_MENU` key, + /// which is encoded as `"ContextMenu"`. + MediaApps, + /// Audio track key. (`KEYCODE_MEDIA_AUDIO_TRACK`) + MediaAudioTrack, + /// Select previously selected channel or media. (`VK_LAST`, `KEYCODE_LAST_CHANNEL`) + MediaLast, + /// Skip backward to next content or program. (`KEYCODE_MEDIA_SKIP_BACKWARD`) + MediaSkipBackward, + /// Skip forward to next content or program. (`VK_SKIP`, `KEYCODE_MEDIA_SKIP_FORWARD`) + MediaSkipForward, + /// Step backward to next content or program. (`KEYCODE_MEDIA_STEP_BACKWARD`) + MediaStepBackward, + /// Step forward to next content or program. (`KEYCODE_MEDIA_STEP_FORWARD`) + MediaStepForward, + /// Media top menu. (`KEYCODE_MEDIA_TOP_MENU`) + MediaTopMenu, + /// Navigate in. (`KEYCODE_NAVIGATE_IN`) + NavigateIn, + /// Navigate to next key. (`KEYCODE_NAVIGATE_NEXT`) + NavigateNext, + /// Navigate out. (`KEYCODE_NAVIGATE_OUT`) + NavigateOut, + /// Navigate to previous key. (`KEYCODE_NAVIGATE_PREVIOUS`) + NavigatePrevious, + /// Cycle to next favorite channel (in favorites list). (`VK_NEXT_FAVORITE_CHANNEL`) + NextFavoriteChannel, + /// Cycle to next user profile (if there are multiple user profiles). (`VK_USER`) + NextUserProfile, + /// Access on-demand content or programs. (`VK_ON_DEMAND`) + OnDemand, + /// Pairing key to pair devices. (`KEYCODE_PAIRING`) + Pairing, + /// Move picture-in-picture window down. (`VK_PINP_DOWN`) + PinPDown, + /// Move picture-in-picture window. (`VK_PINP_MOVE`) + PinPMove, + /// Toggle display of picture-in-picture window. (`VK_PINP_TOGGLE`) + PinPToggle, + /// Move picture-in-picture window up. (`VK_PINP_UP`) + PinPUp, + /// Decrease media playback speed. (`VK_PLAY_SPEED_DOWN`) + PlaySpeedDown, + /// Reset playback to normal speed. (`VK_PLAY_SPEED_RESET`) + PlaySpeedReset, + /// Increase media playback speed. (`VK_PLAY_SPEED_UP`) + PlaySpeedUp, + /// Toggle random media or content shuffle mode. (`VK_RANDOM_TOGGLE`) + RandomToggle, + /// Not a physical key, but this key code is sent when the remote control battery is low. + /// (`VK_RC_LOW_BATTERY`) + RcLowBattery, + /// Toggle or cycle between media recording speeds. (`VK_RECORD_SPEED_NEXT`) + RecordSpeedNext, + /// Toggle RF (radio frequency) input bypass mode (pass RF input directly to the RF output). + /// (`VK_RF_BYPASS`) + RfBypass, + /// Toggle scan channels mode. (`VK_SCAN_CHANNELS_TOGGLE`) + ScanChannelsToggle, + /// Advance display screen mode to next available mode. (`VK_SCREEN_MODE_NEXT`) + ScreenModeNext, + /// Toggle display of device settings screen. (`VK_SETTINGS`, `KEYCODE_SETTINGS`) + Settings, + /// Toggle split screen mode. (`VK_SPLIT_SCREEN_TOGGLE`) + SplitScreenToggle, + /// Switch the input mode on an external STB (set top box). (`KEYCODE_STB_INPUT`) + STBInput, + /// Toggle the power on an external STB (set top box). (`KEYCODE_STB_POWER`) + STBPower, + /// Toggle display of subtitles, if available. (`VK_SUBTITLE`) + Subtitle, + /// Toggle display of teletext, if available (`VK_TELETEXT`, `KEYCODE_TV_TELETEXT`). + Teletext, + /// Advance video mode to next available mode. (`VK_VIDEO_MODE_NEXT`) + VideoModeNext, + /// Cause device to identify itself in some manner, e.g., audibly or visibly. (`VK_WINK`) + Wink, + /// Toggle between full-screen and scaled content, or alter magnification level. (`VK_ZOOM`, + /// `KEYCODE_TV_ZOOM_MODE`) + ZoomToggle, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F1, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F2, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F3, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F4, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F5, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F6, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F7, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F8, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F9, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F10, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F11, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F12, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F13, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F14, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F15, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F16, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F17, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F18, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F19, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F20, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F21, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F22, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F23, + /// General-purpose function key. + /// Usually found at the top of the keyboard. + F24, + /// General-purpose function key. + F25, + /// General-purpose function key. + F26, + /// General-purpose function key. + F27, + /// General-purpose function key. + F28, + /// General-purpose function key. + F29, + /// General-purpose function key. + F30, + /// General-purpose function key. + F31, + /// General-purpose function key. + F32, + /// General-purpose function key. + F33, + /// General-purpose function key. + F34, + /// General-purpose function key. + F35, +} diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 259b1623f153c..09077be6b1e18 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -26,7 +26,7 @@ pub mod prelude { gamepad::{ Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, Gamepads, }, - keyboard::{KeyCode, ScanCode}, + keyboard::{Key, KeyCode}, mouse::MouseButton, touch::{TouchInput, Touches}, Axis, Input, @@ -36,7 +36,7 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_reflect::Reflect; -use keyboard::{keyboard_input_system, KeyCode, KeyboardInput, ScanCode}; +use keyboard::{keyboard_input_system, Key, KeyCode, KeyboardInput, NativeKey}; use mouse::{ mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel, @@ -69,7 +69,7 @@ impl Plugin for InputPlugin { // keyboard .add_event::() .init_resource::>() - .init_resource::>() + .init_resource::>() .add_systems(PreUpdate, keyboard_input_system.in_set(InputSystem)) // mouse .add_event::() @@ -116,7 +116,8 @@ impl Plugin for InputPlugin { // Register keyboard types app.register_type::() .register_type::() - .register_type::(); + .register_type::() + .register_type::(); // Register mouse types app.register_type::() diff --git a/crates/bevy_input/src/mouse.rs b/crates/bevy_input/src/mouse.rs index 8eea5141e96df..bee4e5adab7cc 100644 --- a/crates/bevy_input/src/mouse.rs +++ b/crates/bevy_input/src/mouse.rs @@ -61,6 +61,10 @@ pub enum MouseButton { Right, /// The middle mouse button. Middle, + /// The back mouse button. + Back, + /// The forward mouse button. + Forward, /// Another mouse button with the associated number. Other(u16), } diff --git a/crates/bevy_tasks/Cargo.toml b/crates/bevy_tasks/Cargo.toml index d208f92450e45..b1274ff47b601 100644 --- a/crates/bevy_tasks/Cargo.toml +++ b/crates/bevy_tasks/Cargo.toml @@ -12,8 +12,8 @@ keywords = ["bevy"] multi-threaded = [] [dependencies] -futures-lite = "1.4.0" -async-executor = "1.3.0" +futures-lite = "1.13" +async-executor = "1.5" async-channel = "1.4.2" async-io = { version = "2.0.0", optional = true } async-task = "4.2.0" @@ -23,7 +23,7 @@ concurrent-queue = "2.0.0" wasm-bindgen-futures = "0.4" [dev-dependencies] -instant = { version = "0.1", features = ["wasm-bindgen"] } +web-time = { version = "0.2" } [lints] workspace = true diff --git a/crates/bevy_tasks/examples/busy_behavior.rs b/crates/bevy_tasks/examples/busy_behavior.rs index 8a74034e0ca90..23a43de017a59 100644 --- a/crates/bevy_tasks/examples/busy_behavior.rs +++ b/crates/bevy_tasks/examples/busy_behavior.rs @@ -1,4 +1,5 @@ use bevy_tasks::TaskPoolBuilder; +use web_time::{Duration, Instant}; // This sample demonstrates creating a thread pool with 4 tasks and spawning 40 tasks that spin // for 100ms. It's expected to take about a second to run (assuming the machine has >= 4 logical @@ -10,12 +11,12 @@ fn main() { .num_threads(4) .build(); - let t0 = instant::Instant::now(); + let t0 = Instant::now(); pool.scope(|s| { for i in 0..40 { s.spawn(async move { - let now = instant::Instant::now(); - while instant::Instant::now() - now < instant::Duration::from_millis(100) { + let now = Instant::now(); + while Instant::now() - now < Duration::from_millis(100) { // spin, simulating work being done } @@ -28,6 +29,6 @@ fn main() { } }); - let t1 = instant::Instant::now(); + let t1 = Instant::now(); println!("all tasks finished in {} secs", (t1 - t0).as_secs_f32()); } diff --git a/crates/bevy_tasks/examples/idle_behavior.rs b/crates/bevy_tasks/examples/idle_behavior.rs index daa2eaf2e2a89..3ce121f989fc3 100644 --- a/crates/bevy_tasks/examples/idle_behavior.rs +++ b/crates/bevy_tasks/examples/idle_behavior.rs @@ -1,4 +1,5 @@ use bevy_tasks::TaskPoolBuilder; +use web_time::{Duration, Instant}; // This sample demonstrates a thread pool with one thread per logical core and only one task // spinning. Other than the one thread, the system should remain idle, demonstrating good behavior @@ -13,8 +14,8 @@ fn main() { for i in 0..1 { s.spawn(async move { println!("Blocking for 10 seconds"); - let now = instant::Instant::now(); - while instant::Instant::now() - now < instant::Duration::from_millis(10000) { + let now = Instant::now(); + while Instant::now() - now < Duration::from_millis(10000) { // spin, simulating work being done } diff --git a/crates/bevy_time/src/real.rs b/crates/bevy_time/src/real.rs index b1922b635bca9..90b7b8042df23 100644 --- a/crates/bevy_time/src/real.rs +++ b/crates/bevy_time/src/real.rs @@ -25,7 +25,7 @@ use crate::time::Time; /// zero must be handled without errors in application logic, as it may /// theoretically also happen at other times. /// -/// [`Instant`](std::time::Instant)s for [`startup()`](Time::startup), +/// [`Instant`]s for [`startup()`](Time::startup), /// [`first_update()`](Time::first_update) and /// [`last_update()`](Time::last_update) are recorded and accessible. #[derive(Debug, Copy, Clone, Reflect)] @@ -47,7 +47,7 @@ impl Default for Real { impl Time { /// Constructs a new `Time` instance with a specific startup - /// [`Instant`](std::time::Instant). + /// [`Instant`]. pub fn new(startup: Instant) -> Self { Self::new_with(Real { startup, @@ -77,7 +77,7 @@ impl Time { self.update_with_instant(last_update + duration); } - /// Updates time with a specified [`Instant`](std::time::Instant). + /// Updates time with a specified [`Instant`]. /// /// This method is provided for use in tests. /// @@ -95,7 +95,7 @@ impl Time { self.context_mut().last_update = Some(instant); } - /// Returns the [`Instant`](std::time::Instant) the clock was created. + /// Returns the [`Instant`] the clock was created. /// /// This usually represents when the app was started. #[inline] @@ -103,7 +103,7 @@ impl Time { self.context().startup } - /// Returns the [`Instant`](std::time::Instant) when [`Self::update`] was first called, if it + /// Returns the [`Instant`] when [`Self::update`] was first called, if it /// exists. /// /// This usually represents when the first app update started. @@ -112,7 +112,7 @@ impl Time { self.context().first_update } - /// Returns the [`Instant`](std::time::Instant) when [`Self::update`] was last called, if it + /// Returns the [`Instant`] when [`Self::update`] was last called, if it /// exists. /// /// This usually represents when the current app update started. diff --git a/crates/bevy_utils/Cargo.toml b/crates/bevy_utils/Cargo.toml index bf1eea4b5f069..be3d039da1b10 100644 --- a/crates/bevy_utils/Cargo.toml +++ b/crates/bevy_utils/Cargo.toml @@ -14,7 +14,7 @@ detailed_trace = [] [dependencies] ahash = "0.8.3" tracing = { version = "0.1", default-features = false, features = ["std"] } -instant = { version = "0.1", features = ["wasm-bindgen"] } +web-time = { version = "0.2" } uuid = { version = "1.1", features = ["v4", "serde"] } hashbrown = { version = "0.14", features = ["serde"] } bevy_utils_proc_macros = { version = "0.12.0", path = "macros" } diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 320bb407c9096..acfa59323f73d 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -28,11 +28,11 @@ pub use cow_arc::*; pub use default::default; pub use float_ord::*; pub use hashbrown; -pub use instant::{Duration, Instant}; pub use petgraph; pub use thiserror; pub use tracing; pub use uuid::Uuid; +pub use web_time::{Duration, Instant}; #[allow(missing_docs)] pub mod nonmax { diff --git a/crates/bevy_window/src/cursor.rs b/crates/bevy_window/src/cursor.rs index bf6b5948092aa..6a80fd8e835c0 100644 --- a/crates/bevy_window/src/cursor.rs +++ b/crates/bevy_window/src/cursor.rs @@ -20,78 +20,130 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; )] #[reflect(Debug, PartialEq, Default)] pub enum CursorIcon { - /// The platform-dependent default cursor. + /// The platform-dependent default cursor. Often rendered as arrow. #[default] Default, - /// A simple crosshair. - Crosshair, - /// A hand (often used to indicate links in web browsers). - Hand, - /// An arrow. This is the default cursor on most systems. - Arrow, - /// Indicates something is to be moved. - Move, - /// Indicates text that may be selected or edited. - Text, - /// Program busy indicator. - Wait, - /// Help indicator (often rendered as a "?") + + /// A context menu is available for the object under the cursor. Often + /// rendered as an arrow with a small menu-like graphic next to it. + ContextMenu, + + /// Help is available for the object under the cursor. Often rendered as a + /// question mark or a balloon. Help, - /// Progress indicator. Shows that processing is being done. - /// - /// But in contrast with "Wait" the user may still interact with the program. - /// Often rendered as a spinning beach ball, or an arrow with a watch or hourglass. + + /// The cursor is a pointer that indicates a link. Often rendered as the + /// backside of a hand with the index finger extended. + Pointer, + + /// A progress indicator. The program is performing some processing, but is + /// different from [`CursorIcon::Wait`] in that the user may still interact + /// with the program. Progress, - /// Cursor showing that something cannot be done. - NotAllowed, - /// Indicates that a context menu is available. - ContextMenu, - /// Indicates that a cell (or set of cells) may be selected. + + /// Indicates that the program is busy and the user should wait. Often + /// rendered as a watch or hourglass. + Wait, + + /// Indicates that a cell or set of cells may be selected. Often rendered as + /// a thick plus-sign with a dot in the middle. Cell, - /// Indicates vertical text that may be selected or edited. + + /// A simple crosshair (e.g., short line segments resembling a "+" sign). + /// Often used to indicate a two dimensional bitmap selection mode. + Crosshair, + + /// Indicates text that may be selected. Often rendered as an I-beam. + Text, + + /// Indicates vertical-text that may be selected. Often rendered as a + /// horizontal I-beam. VerticalText, - /// Indicates that an alias of something is to be created. + + /// Indicates an alias of/shortcut to something is to be created. Often + /// rendered as an arrow with a small curved arrow next to it. Alias, - /// Indicates something is to be copied. + + /// Indicates something is to be copied. Often rendered as an arrow with a + /// small plus sign next to it. Copy, - /// Indicates that the dragged item cannot be dropped here. + + /// Indicates something is to be moved. + Move, + + /// Indicates that the dragged item cannot be dropped at the current cursor + /// location. Often rendered as a hand or pointer with a small circle with a + /// line through it. NoDrop, - /// Indicates that something can be grabbed. + + /// Indicates that the requested action will not be carried out. Often + /// rendered as a circle with a line through it. + NotAllowed, + + /// Indicates that something can be grabbed (dragged to be moved). Often + /// rendered as the backside of an open hand. Grab, - /// Indicates that something is grabbed. + + /// Indicates that something is being grabbed (dragged to be moved). Often + /// rendered as the backside of a hand with fingers closed mostly out of + /// view. Grabbing, - /// Indicates that the user can scroll by dragging the mouse. - AllScroll, - /// Indicates that the user can zoom in. - ZoomIn, - /// Indicates that the user can zoom out. - ZoomOut, - /// Indicates that an edge of a box is to be moved right (east). + + /// The east border to be moved. EResize, - /// Indicates that an edge of a box is to be moved up (north). + + /// The north border to be moved. NResize, - /// Indicates that an edge of a box is to be moved up and right (north/east). + + /// The north-east corner to be moved. NeResize, - /// indicates that an edge of a box is to be moved up and left (north/west). + + /// The north-west corner to be moved. NwResize, - /// Indicates that an edge of a box is to be moved down (south). + + /// The south border to be moved. SResize, - /// The cursor indicates that an edge of a box is to be moved down and right (south/east). + + /// The south-east corner to be moved. SeResize, - /// The cursor indicates that an edge of a box is to be moved down and left (south/west). + + /// The south-west corner to be moved. SwResize, - /// Indicates that an edge of a box is to be moved left (west). + + /// The west border to be moved. WResize, - /// Indicates a bidirectional resize cursor. + + /// The east and west borders to be moved. EwResize, - /// Indicates a bidirectional resize cursor. + + /// The south and north borders to be moved. NsResize, - /// Indicates a bidirectional resize cursor. + + /// The north-east and south-west corners to be moved. NeswResize, - /// Indicates a bidirectional resize cursor. + + /// The north-west and south-east corners to be moved. NwseResize, - /// Indicates that a column can be resized horizontally. + + /// Indicates that the item/column can be resized horizontally. Often + /// rendered as arrows pointing left and right with a vertical bar + /// separating them. ColResize, - /// Indicates that the row can be resized vertically. + + /// Indicates that the item/row can be resized vertically. Often rendered as + /// arrows pointing up and down with a horizontal bar separating them. RowResize, + + /// Indicates that the something can be scrolled in any direction. Often + /// rendered as arrows pointing up, down, left, and right with a dot in the + /// middle. + AllScroll, + + /// Indicates that something can be zoomed in. Often rendered as a + /// magnifying glass with a "+" in the center of the glass. + ZoomIn, + + /// Indicates that something can be zoomed in. Often rendered as a + /// magnifying glass with a "-" in the center of the glass. + ZoomOut, } diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index c16abf9d951e4..5b81b64585628 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -28,19 +28,21 @@ bevy_utils = { path = "../bevy_utils", version = "0.12.0" } bevy_tasks = { path = "../bevy_tasks", version = "0.12.0" } # other -winit = { version = "0.28.7", default-features = false } -accesskit_winit = { version = "0.15", default-features = false } +winit = { version = "0.29", default-features = false, features = ["rwh_05"] } +accesskit_winit = { version = "0.16", default-features = false } approx = { version = "0.5", default-features = false } raw-window-handle = "0.5" [target.'cfg(target_os = "android")'.dependencies] -winit = { version = "0.28.7", default-features = false, features = [ +winit = { version = "0.29", default-features = false, features = [ "android-native-activity", + "rwh_05", ] } [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = { version = "0.2" } web-sys = "0.3" + crossbeam-channel = "0.5" [package.metadata.docs.rs] diff --git a/crates/bevy_winit/src/converters.rs b/crates/bevy_winit/src/converters.rs index 85302ecb0d68c..00274fd92339b 100644 --- a/crates/bevy_winit/src/converters.rs +++ b/crates/bevy_winit/src/converters.rs @@ -1,21 +1,22 @@ use bevy_ecs::entity::Entity; use bevy_input::{ - keyboard::{KeyCode, KeyboardInput}, + keyboard::{KeyCode, KeyboardInput, NativeKeyCode}, mouse::MouseButton, touch::{ForceTouch, TouchInput, TouchPhase}, ButtonState, }; use bevy_math::Vec2; use bevy_window::{CursorIcon, EnabledButtons, WindowLevel, WindowTheme}; +use winit::keyboard::{Key, NamedKey, NativeKey}; pub fn convert_keyboard_input( - keyboard_input: &winit::event::KeyboardInput, + keyboard_input: &winit::event::KeyEvent, window: Entity, ) -> KeyboardInput { KeyboardInput { - scan_code: keyboard_input.scancode, state: convert_element_state(keyboard_input.state), - key_code: keyboard_input.virtual_keycode.map(convert_virtual_key_code), + key_code: convert_physical_key_code(keyboard_input.physical_key), + logical_key: convert_logical_key_code(&keyboard_input.logical_key), window, } } @@ -32,6 +33,8 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut winit::event::MouseButton::Left => MouseButton::Left, winit::event::MouseButton::Right => MouseButton::Right, winit::event::MouseButton::Middle => MouseButton::Middle, + winit::event::MouseButton::Back => MouseButton::Back, + winit::event::MouseButton::Forward => MouseButton::Forward, winit::event::MouseButton::Other(val) => MouseButton::Other(val), } } @@ -64,180 +67,570 @@ pub fn convert_touch_input( } } -pub fn convert_virtual_key_code(virtual_key_code: winit::event::VirtualKeyCode) -> KeyCode { +pub fn convert_physical_native_key_code( + native_key_code: winit::keyboard::NativeKeyCode, +) -> NativeKeyCode { + match native_key_code { + winit::keyboard::NativeKeyCode::Unidentified => NativeKeyCode::Unidentified, + winit::keyboard::NativeKeyCode::Android(scan_code) => NativeKeyCode::Android(scan_code), + winit::keyboard::NativeKeyCode::MacOS(scan_code) => NativeKeyCode::MacOS(scan_code), + winit::keyboard::NativeKeyCode::Windows(scan_code) => NativeKeyCode::Windows(scan_code), + winit::keyboard::NativeKeyCode::Xkb(key_code) => NativeKeyCode::Xkb(key_code), + } +} +pub fn convert_physical_key_code(virtual_key_code: winit::keyboard::PhysicalKey) -> KeyCode { match virtual_key_code { - winit::event::VirtualKeyCode::Key1 => KeyCode::Key1, - winit::event::VirtualKeyCode::Key2 => KeyCode::Key2, - winit::event::VirtualKeyCode::Key3 => KeyCode::Key3, - winit::event::VirtualKeyCode::Key4 => KeyCode::Key4, - winit::event::VirtualKeyCode::Key5 => KeyCode::Key5, - winit::event::VirtualKeyCode::Key6 => KeyCode::Key6, - winit::event::VirtualKeyCode::Key7 => KeyCode::Key7, - winit::event::VirtualKeyCode::Key8 => KeyCode::Key8, - winit::event::VirtualKeyCode::Key9 => KeyCode::Key9, - winit::event::VirtualKeyCode::Key0 => KeyCode::Key0, - winit::event::VirtualKeyCode::A => KeyCode::A, - winit::event::VirtualKeyCode::B => KeyCode::B, - winit::event::VirtualKeyCode::C => KeyCode::C, - winit::event::VirtualKeyCode::D => KeyCode::D, - winit::event::VirtualKeyCode::E => KeyCode::E, - winit::event::VirtualKeyCode::F => KeyCode::F, - winit::event::VirtualKeyCode::G => KeyCode::G, - winit::event::VirtualKeyCode::H => KeyCode::H, - winit::event::VirtualKeyCode::I => KeyCode::I, - winit::event::VirtualKeyCode::J => KeyCode::J, - winit::event::VirtualKeyCode::K => KeyCode::K, - winit::event::VirtualKeyCode::L => KeyCode::L, - winit::event::VirtualKeyCode::M => KeyCode::M, - winit::event::VirtualKeyCode::N => KeyCode::N, - winit::event::VirtualKeyCode::O => KeyCode::O, - winit::event::VirtualKeyCode::P => KeyCode::P, - winit::event::VirtualKeyCode::Q => KeyCode::Q, - winit::event::VirtualKeyCode::R => KeyCode::R, - winit::event::VirtualKeyCode::S => KeyCode::S, - winit::event::VirtualKeyCode::T => KeyCode::T, - winit::event::VirtualKeyCode::U => KeyCode::U, - winit::event::VirtualKeyCode::V => KeyCode::V, - winit::event::VirtualKeyCode::W => KeyCode::W, - winit::event::VirtualKeyCode::X => KeyCode::X, - winit::event::VirtualKeyCode::Y => KeyCode::Y, - winit::event::VirtualKeyCode::Z => KeyCode::Z, - winit::event::VirtualKeyCode::Escape => KeyCode::Escape, - winit::event::VirtualKeyCode::F1 => KeyCode::F1, - winit::event::VirtualKeyCode::F2 => KeyCode::F2, - winit::event::VirtualKeyCode::F3 => KeyCode::F3, - winit::event::VirtualKeyCode::F4 => KeyCode::F4, - winit::event::VirtualKeyCode::F5 => KeyCode::F5, - winit::event::VirtualKeyCode::F6 => KeyCode::F6, - winit::event::VirtualKeyCode::F7 => KeyCode::F7, - winit::event::VirtualKeyCode::F8 => KeyCode::F8, - winit::event::VirtualKeyCode::F9 => KeyCode::F9, - winit::event::VirtualKeyCode::F10 => KeyCode::F10, - winit::event::VirtualKeyCode::F11 => KeyCode::F11, - winit::event::VirtualKeyCode::F12 => KeyCode::F12, - winit::event::VirtualKeyCode::F13 => KeyCode::F13, - winit::event::VirtualKeyCode::F14 => KeyCode::F14, - winit::event::VirtualKeyCode::F15 => KeyCode::F15, - winit::event::VirtualKeyCode::F16 => KeyCode::F16, - winit::event::VirtualKeyCode::F17 => KeyCode::F17, - winit::event::VirtualKeyCode::F18 => KeyCode::F18, - winit::event::VirtualKeyCode::F19 => KeyCode::F19, - winit::event::VirtualKeyCode::F20 => KeyCode::F20, - winit::event::VirtualKeyCode::F21 => KeyCode::F21, - winit::event::VirtualKeyCode::F22 => KeyCode::F22, - winit::event::VirtualKeyCode::F23 => KeyCode::F23, - winit::event::VirtualKeyCode::F24 => KeyCode::F24, - winit::event::VirtualKeyCode::Snapshot => KeyCode::Snapshot, - winit::event::VirtualKeyCode::Scroll => KeyCode::Scroll, - winit::event::VirtualKeyCode::Pause => KeyCode::Pause, - winit::event::VirtualKeyCode::Insert => KeyCode::Insert, - winit::event::VirtualKeyCode::Home => KeyCode::Home, - winit::event::VirtualKeyCode::Delete => KeyCode::Delete, - winit::event::VirtualKeyCode::End => KeyCode::End, - winit::event::VirtualKeyCode::PageDown => KeyCode::PageDown, - winit::event::VirtualKeyCode::PageUp => KeyCode::PageUp, - winit::event::VirtualKeyCode::Left => KeyCode::Left, - winit::event::VirtualKeyCode::Up => KeyCode::Up, - winit::event::VirtualKeyCode::Right => KeyCode::Right, - winit::event::VirtualKeyCode::Down => KeyCode::Down, - winit::event::VirtualKeyCode::Back => KeyCode::Back, - winit::event::VirtualKeyCode::Return => KeyCode::Return, - winit::event::VirtualKeyCode::Space => KeyCode::Space, - winit::event::VirtualKeyCode::Compose => KeyCode::Compose, - winit::event::VirtualKeyCode::Caret => KeyCode::Caret, - winit::event::VirtualKeyCode::Numlock => KeyCode::Numlock, - winit::event::VirtualKeyCode::Numpad0 => KeyCode::Numpad0, - winit::event::VirtualKeyCode::Numpad1 => KeyCode::Numpad1, - winit::event::VirtualKeyCode::Numpad2 => KeyCode::Numpad2, - winit::event::VirtualKeyCode::Numpad3 => KeyCode::Numpad3, - winit::event::VirtualKeyCode::Numpad4 => KeyCode::Numpad4, - winit::event::VirtualKeyCode::Numpad5 => KeyCode::Numpad5, - winit::event::VirtualKeyCode::Numpad6 => KeyCode::Numpad6, - winit::event::VirtualKeyCode::Numpad7 => KeyCode::Numpad7, - winit::event::VirtualKeyCode::Numpad8 => KeyCode::Numpad8, - winit::event::VirtualKeyCode::Numpad9 => KeyCode::Numpad9, - winit::event::VirtualKeyCode::AbntC1 => KeyCode::AbntC1, - winit::event::VirtualKeyCode::AbntC2 => KeyCode::AbntC2, - winit::event::VirtualKeyCode::NumpadAdd => KeyCode::NumpadAdd, - winit::event::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe, - winit::event::VirtualKeyCode::Apps => KeyCode::Apps, - winit::event::VirtualKeyCode::Asterisk => KeyCode::Asterisk, - winit::event::VirtualKeyCode::Plus => KeyCode::Plus, - winit::event::VirtualKeyCode::At => KeyCode::At, - winit::event::VirtualKeyCode::Ax => KeyCode::Ax, - winit::event::VirtualKeyCode::Backslash => KeyCode::Backslash, - winit::event::VirtualKeyCode::Calculator => KeyCode::Calculator, - winit::event::VirtualKeyCode::Capital => KeyCode::Capital, - winit::event::VirtualKeyCode::Colon => KeyCode::Colon, - winit::event::VirtualKeyCode::Comma => KeyCode::Comma, - winit::event::VirtualKeyCode::Convert => KeyCode::Convert, - winit::event::VirtualKeyCode::NumpadDecimal => KeyCode::NumpadDecimal, - winit::event::VirtualKeyCode::NumpadDivide => KeyCode::NumpadDivide, - winit::event::VirtualKeyCode::Equals => KeyCode::Equals, - winit::event::VirtualKeyCode::Grave => KeyCode::Grave, - winit::event::VirtualKeyCode::Kana => KeyCode::Kana, - winit::event::VirtualKeyCode::Kanji => KeyCode::Kanji, - winit::event::VirtualKeyCode::LAlt => KeyCode::AltLeft, - winit::event::VirtualKeyCode::LBracket => KeyCode::BracketLeft, - winit::event::VirtualKeyCode::LControl => KeyCode::ControlLeft, - winit::event::VirtualKeyCode::LShift => KeyCode::ShiftLeft, - winit::event::VirtualKeyCode::LWin => KeyCode::SuperLeft, - winit::event::VirtualKeyCode::Mail => KeyCode::Mail, - winit::event::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect, - winit::event::VirtualKeyCode::MediaStop => KeyCode::MediaStop, - winit::event::VirtualKeyCode::Minus => KeyCode::Minus, - winit::event::VirtualKeyCode::NumpadMultiply => KeyCode::NumpadMultiply, - winit::event::VirtualKeyCode::Mute => KeyCode::Mute, - winit::event::VirtualKeyCode::MyComputer => KeyCode::MyComputer, - winit::event::VirtualKeyCode::NavigateForward => KeyCode::NavigateForward, - winit::event::VirtualKeyCode::NavigateBackward => KeyCode::NavigateBackward, - winit::event::VirtualKeyCode::NextTrack => KeyCode::NextTrack, - winit::event::VirtualKeyCode::NoConvert => KeyCode::NoConvert, - winit::event::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma, - winit::event::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter, - winit::event::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals, - winit::event::VirtualKeyCode::OEM102 => KeyCode::Oem102, - winit::event::VirtualKeyCode::Period => KeyCode::Period, - winit::event::VirtualKeyCode::PlayPause => KeyCode::PlayPause, - winit::event::VirtualKeyCode::Power => KeyCode::Power, - winit::event::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack, - winit::event::VirtualKeyCode::RAlt => KeyCode::AltRight, - winit::event::VirtualKeyCode::RBracket => KeyCode::BracketRight, - winit::event::VirtualKeyCode::RControl => KeyCode::ControlRight, - winit::event::VirtualKeyCode::RShift => KeyCode::ShiftRight, - winit::event::VirtualKeyCode::RWin => KeyCode::SuperRight, - winit::event::VirtualKeyCode::Semicolon => KeyCode::Semicolon, - winit::event::VirtualKeyCode::Slash => KeyCode::Slash, - winit::event::VirtualKeyCode::Sleep => KeyCode::Sleep, - winit::event::VirtualKeyCode::Stop => KeyCode::Stop, - winit::event::VirtualKeyCode::NumpadSubtract => KeyCode::NumpadSubtract, - winit::event::VirtualKeyCode::Sysrq => KeyCode::Sysrq, - winit::event::VirtualKeyCode::Tab => KeyCode::Tab, - winit::event::VirtualKeyCode::Underline => KeyCode::Underline, - winit::event::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled, - winit::event::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown, - winit::event::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp, - winit::event::VirtualKeyCode::Wake => KeyCode::Wake, - winit::event::VirtualKeyCode::WebBack => KeyCode::WebBack, - winit::event::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites, - winit::event::VirtualKeyCode::WebForward => KeyCode::WebForward, - winit::event::VirtualKeyCode::WebHome => KeyCode::WebHome, - winit::event::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh, - winit::event::VirtualKeyCode::WebSearch => KeyCode::WebSearch, - winit::event::VirtualKeyCode::WebStop => KeyCode::WebStop, - winit::event::VirtualKeyCode::Yen => KeyCode::Yen, - winit::event::VirtualKeyCode::Copy => KeyCode::Copy, - winit::event::VirtualKeyCode::Paste => KeyCode::Paste, - winit::event::VirtualKeyCode::Cut => KeyCode::Cut, + winit::keyboard::PhysicalKey::Unidentified(native_key_code) => { + KeyCode::Unidentified(convert_physical_native_key_code(native_key_code)) + } + winit::keyboard::PhysicalKey::Code(code) => match code { + winit::keyboard::KeyCode::Backquote => KeyCode::Backquote, + winit::keyboard::KeyCode::Backslash => KeyCode::Backslash, + winit::keyboard::KeyCode::BracketLeft => KeyCode::BracketLeft, + winit::keyboard::KeyCode::BracketRight => KeyCode::BracketRight, + winit::keyboard::KeyCode::Comma => KeyCode::Comma, + winit::keyboard::KeyCode::Digit0 => KeyCode::Digit0, + winit::keyboard::KeyCode::Digit1 => KeyCode::Digit1, + winit::keyboard::KeyCode::Digit2 => KeyCode::Digit2, + winit::keyboard::KeyCode::Digit3 => KeyCode::Digit3, + winit::keyboard::KeyCode::Digit4 => KeyCode::Digit4, + winit::keyboard::KeyCode::Digit5 => KeyCode::Digit5, + winit::keyboard::KeyCode::Digit6 => KeyCode::Digit6, + winit::keyboard::KeyCode::Digit7 => KeyCode::Digit7, + winit::keyboard::KeyCode::Digit8 => KeyCode::Digit8, + winit::keyboard::KeyCode::Digit9 => KeyCode::Digit9, + winit::keyboard::KeyCode::Equal => KeyCode::Equal, + winit::keyboard::KeyCode::IntlBackslash => KeyCode::IntlBackslash, + winit::keyboard::KeyCode::IntlRo => KeyCode::IntlRo, + winit::keyboard::KeyCode::IntlYen => KeyCode::IntlYen, + winit::keyboard::KeyCode::KeyA => KeyCode::KeyA, + winit::keyboard::KeyCode::KeyB => KeyCode::KeyB, + winit::keyboard::KeyCode::KeyC => KeyCode::KeyC, + winit::keyboard::KeyCode::KeyD => KeyCode::KeyD, + winit::keyboard::KeyCode::KeyE => KeyCode::KeyE, + winit::keyboard::KeyCode::KeyF => KeyCode::KeyF, + winit::keyboard::KeyCode::KeyG => KeyCode::KeyG, + winit::keyboard::KeyCode::KeyH => KeyCode::KeyH, + winit::keyboard::KeyCode::KeyI => KeyCode::KeyI, + winit::keyboard::KeyCode::KeyJ => KeyCode::KeyJ, + winit::keyboard::KeyCode::KeyK => KeyCode::KeyK, + winit::keyboard::KeyCode::KeyL => KeyCode::KeyL, + winit::keyboard::KeyCode::KeyM => KeyCode::KeyM, + winit::keyboard::KeyCode::KeyN => KeyCode::KeyN, + winit::keyboard::KeyCode::KeyO => KeyCode::KeyO, + winit::keyboard::KeyCode::KeyP => KeyCode::KeyP, + winit::keyboard::KeyCode::KeyQ => KeyCode::KeyQ, + winit::keyboard::KeyCode::KeyR => KeyCode::KeyR, + winit::keyboard::KeyCode::KeyS => KeyCode::KeyS, + winit::keyboard::KeyCode::KeyT => KeyCode::KeyT, + winit::keyboard::KeyCode::KeyU => KeyCode::KeyU, + winit::keyboard::KeyCode::KeyV => KeyCode::KeyV, + winit::keyboard::KeyCode::KeyW => KeyCode::KeyW, + winit::keyboard::KeyCode::KeyX => KeyCode::KeyX, + winit::keyboard::KeyCode::KeyY => KeyCode::KeyY, + winit::keyboard::KeyCode::KeyZ => KeyCode::KeyZ, + winit::keyboard::KeyCode::Minus => KeyCode::Minus, + winit::keyboard::KeyCode::Period => KeyCode::Period, + winit::keyboard::KeyCode::Quote => KeyCode::Quote, + winit::keyboard::KeyCode::Semicolon => KeyCode::Semicolon, + winit::keyboard::KeyCode::Slash => KeyCode::Slash, + winit::keyboard::KeyCode::AltLeft => KeyCode::AltLeft, + winit::keyboard::KeyCode::AltRight => KeyCode::AltRight, + winit::keyboard::KeyCode::Backspace => KeyCode::Backspace, + winit::keyboard::KeyCode::CapsLock => KeyCode::CapsLock, + winit::keyboard::KeyCode::ContextMenu => KeyCode::ContextMenu, + winit::keyboard::KeyCode::ControlLeft => KeyCode::ControlLeft, + winit::keyboard::KeyCode::ControlRight => KeyCode::ControlRight, + winit::keyboard::KeyCode::Enter => KeyCode::Enter, + winit::keyboard::KeyCode::SuperLeft => KeyCode::SuperLeft, + winit::keyboard::KeyCode::SuperRight => KeyCode::SuperRight, + winit::keyboard::KeyCode::ShiftLeft => KeyCode::ShiftLeft, + winit::keyboard::KeyCode::ShiftRight => KeyCode::ShiftRight, + winit::keyboard::KeyCode::Space => KeyCode::Space, + winit::keyboard::KeyCode::Tab => KeyCode::Tab, + winit::keyboard::KeyCode::Convert => KeyCode::Convert, + winit::keyboard::KeyCode::KanaMode => KeyCode::KanaMode, + winit::keyboard::KeyCode::Lang1 => KeyCode::Lang1, + winit::keyboard::KeyCode::Lang2 => KeyCode::Lang2, + winit::keyboard::KeyCode::Lang3 => KeyCode::Lang3, + winit::keyboard::KeyCode::Lang4 => KeyCode::Lang4, + winit::keyboard::KeyCode::Lang5 => KeyCode::Lang5, + winit::keyboard::KeyCode::NonConvert => KeyCode::NonConvert, + winit::keyboard::KeyCode::Delete => KeyCode::Delete, + winit::keyboard::KeyCode::End => KeyCode::End, + winit::keyboard::KeyCode::Help => KeyCode::Help, + winit::keyboard::KeyCode::Home => KeyCode::Home, + winit::keyboard::KeyCode::Insert => KeyCode::Insert, + winit::keyboard::KeyCode::PageDown => KeyCode::PageDown, + winit::keyboard::KeyCode::PageUp => KeyCode::PageUp, + winit::keyboard::KeyCode::ArrowDown => KeyCode::ArrowDown, + winit::keyboard::KeyCode::ArrowLeft => KeyCode::ArrowLeft, + winit::keyboard::KeyCode::ArrowRight => KeyCode::ArrowRight, + winit::keyboard::KeyCode::ArrowUp => KeyCode::ArrowUp, + winit::keyboard::KeyCode::NumLock => KeyCode::NumLock, + winit::keyboard::KeyCode::Numpad0 => KeyCode::Numpad0, + winit::keyboard::KeyCode::Numpad1 => KeyCode::Numpad1, + winit::keyboard::KeyCode::Numpad2 => KeyCode::Numpad2, + winit::keyboard::KeyCode::Numpad3 => KeyCode::Numpad3, + winit::keyboard::KeyCode::Numpad4 => KeyCode::Numpad4, + winit::keyboard::KeyCode::Numpad5 => KeyCode::Numpad5, + winit::keyboard::KeyCode::Numpad6 => KeyCode::Numpad6, + winit::keyboard::KeyCode::Numpad7 => KeyCode::Numpad7, + winit::keyboard::KeyCode::Numpad8 => KeyCode::Numpad8, + winit::keyboard::KeyCode::Numpad9 => KeyCode::Numpad9, + winit::keyboard::KeyCode::NumpadAdd => KeyCode::NumpadAdd, + winit::keyboard::KeyCode::NumpadBackspace => KeyCode::NumpadBackspace, + winit::keyboard::KeyCode::NumpadClear => KeyCode::NumpadClear, + winit::keyboard::KeyCode::NumpadClearEntry => KeyCode::NumpadClearEntry, + winit::keyboard::KeyCode::NumpadComma => KeyCode::NumpadComma, + winit::keyboard::KeyCode::NumpadDecimal => KeyCode::NumpadDecimal, + winit::keyboard::KeyCode::NumpadDivide => KeyCode::NumpadDivide, + winit::keyboard::KeyCode::NumpadEnter => KeyCode::NumpadEnter, + winit::keyboard::KeyCode::NumpadEqual => KeyCode::NumpadEqual, + winit::keyboard::KeyCode::NumpadHash => KeyCode::NumpadHash, + winit::keyboard::KeyCode::NumpadMemoryAdd => KeyCode::NumpadMemoryAdd, + winit::keyboard::KeyCode::NumpadMemoryClear => KeyCode::NumpadMemoryClear, + winit::keyboard::KeyCode::NumpadMemoryRecall => KeyCode::NumpadMemoryRecall, + winit::keyboard::KeyCode::NumpadMemoryStore => KeyCode::NumpadMemoryStore, + winit::keyboard::KeyCode::NumpadMemorySubtract => KeyCode::NumpadMemorySubtract, + winit::keyboard::KeyCode::NumpadMultiply => KeyCode::NumpadMultiply, + winit::keyboard::KeyCode::NumpadParenLeft => KeyCode::NumpadParenLeft, + winit::keyboard::KeyCode::NumpadParenRight => KeyCode::NumpadParenRight, + winit::keyboard::KeyCode::NumpadStar => KeyCode::NumpadStar, + winit::keyboard::KeyCode::NumpadSubtract => KeyCode::NumpadSubtract, + winit::keyboard::KeyCode::Escape => KeyCode::Escape, + winit::keyboard::KeyCode::Fn => KeyCode::Fn, + winit::keyboard::KeyCode::FnLock => KeyCode::FnLock, + winit::keyboard::KeyCode::PrintScreen => KeyCode::PrintScreen, + winit::keyboard::KeyCode::ScrollLock => KeyCode::ScrollLock, + winit::keyboard::KeyCode::Pause => KeyCode::Pause, + winit::keyboard::KeyCode::BrowserBack => KeyCode::BrowserBack, + winit::keyboard::KeyCode::BrowserFavorites => KeyCode::BrowserFavorites, + winit::keyboard::KeyCode::BrowserForward => KeyCode::BrowserForward, + winit::keyboard::KeyCode::BrowserHome => KeyCode::BrowserHome, + winit::keyboard::KeyCode::BrowserRefresh => KeyCode::BrowserRefresh, + winit::keyboard::KeyCode::BrowserSearch => KeyCode::BrowserSearch, + winit::keyboard::KeyCode::BrowserStop => KeyCode::BrowserStop, + winit::keyboard::KeyCode::Eject => KeyCode::Eject, + winit::keyboard::KeyCode::LaunchApp1 => KeyCode::LaunchApp1, + winit::keyboard::KeyCode::LaunchApp2 => KeyCode::LaunchApp2, + winit::keyboard::KeyCode::LaunchMail => KeyCode::LaunchMail, + winit::keyboard::KeyCode::MediaPlayPause => KeyCode::MediaPlayPause, + winit::keyboard::KeyCode::MediaSelect => KeyCode::MediaSelect, + winit::keyboard::KeyCode::MediaStop => KeyCode::MediaStop, + winit::keyboard::KeyCode::MediaTrackNext => KeyCode::MediaTrackNext, + winit::keyboard::KeyCode::MediaTrackPrevious => KeyCode::MediaTrackPrevious, + winit::keyboard::KeyCode::Power => KeyCode::Power, + winit::keyboard::KeyCode::Sleep => KeyCode::Sleep, + winit::keyboard::KeyCode::AudioVolumeDown => KeyCode::AudioVolumeDown, + winit::keyboard::KeyCode::AudioVolumeMute => KeyCode::AudioVolumeMute, + winit::keyboard::KeyCode::AudioVolumeUp => KeyCode::AudioVolumeUp, + winit::keyboard::KeyCode::WakeUp => KeyCode::WakeUp, + winit::keyboard::KeyCode::Meta => KeyCode::Meta, + winit::keyboard::KeyCode::Hyper => KeyCode::Hyper, + winit::keyboard::KeyCode::Turbo => KeyCode::Turbo, + winit::keyboard::KeyCode::Abort => KeyCode::Abort, + winit::keyboard::KeyCode::Resume => KeyCode::Resume, + winit::keyboard::KeyCode::Suspend => KeyCode::Suspend, + winit::keyboard::KeyCode::Again => KeyCode::Again, + winit::keyboard::KeyCode::Copy => KeyCode::Copy, + winit::keyboard::KeyCode::Cut => KeyCode::Cut, + winit::keyboard::KeyCode::Find => KeyCode::Find, + winit::keyboard::KeyCode::Open => KeyCode::Open, + winit::keyboard::KeyCode::Paste => KeyCode::Paste, + winit::keyboard::KeyCode::Props => KeyCode::Props, + winit::keyboard::KeyCode::Select => KeyCode::Select, + winit::keyboard::KeyCode::Undo => KeyCode::Undo, + winit::keyboard::KeyCode::Hiragana => KeyCode::Hiragana, + winit::keyboard::KeyCode::Katakana => KeyCode::Katakana, + winit::keyboard::KeyCode::F1 => KeyCode::F1, + winit::keyboard::KeyCode::F2 => KeyCode::F2, + winit::keyboard::KeyCode::F3 => KeyCode::F3, + winit::keyboard::KeyCode::F4 => KeyCode::F4, + winit::keyboard::KeyCode::F5 => KeyCode::F5, + winit::keyboard::KeyCode::F6 => KeyCode::F6, + winit::keyboard::KeyCode::F7 => KeyCode::F7, + winit::keyboard::KeyCode::F8 => KeyCode::F8, + winit::keyboard::KeyCode::F9 => KeyCode::F9, + winit::keyboard::KeyCode::F10 => KeyCode::F10, + winit::keyboard::KeyCode::F11 => KeyCode::F11, + winit::keyboard::KeyCode::F12 => KeyCode::F12, + winit::keyboard::KeyCode::F13 => KeyCode::F13, + winit::keyboard::KeyCode::F14 => KeyCode::F14, + winit::keyboard::KeyCode::F15 => KeyCode::F15, + winit::keyboard::KeyCode::F16 => KeyCode::F16, + winit::keyboard::KeyCode::F17 => KeyCode::F17, + winit::keyboard::KeyCode::F18 => KeyCode::F18, + winit::keyboard::KeyCode::F19 => KeyCode::F19, + winit::keyboard::KeyCode::F20 => KeyCode::F20, + winit::keyboard::KeyCode::F21 => KeyCode::F21, + winit::keyboard::KeyCode::F22 => KeyCode::F22, + winit::keyboard::KeyCode::F23 => KeyCode::F23, + winit::keyboard::KeyCode::F24 => KeyCode::F24, + winit::keyboard::KeyCode::F25 => KeyCode::F25, + winit::keyboard::KeyCode::F26 => KeyCode::F26, + winit::keyboard::KeyCode::F27 => KeyCode::F27, + winit::keyboard::KeyCode::F28 => KeyCode::F28, + winit::keyboard::KeyCode::F29 => KeyCode::F29, + winit::keyboard::KeyCode::F30 => KeyCode::F30, + winit::keyboard::KeyCode::F31 => KeyCode::F31, + winit::keyboard::KeyCode::F32 => KeyCode::F32, + winit::keyboard::KeyCode::F33 => KeyCode::F33, + winit::keyboard::KeyCode::F34 => KeyCode::F34, + winit::keyboard::KeyCode::F35 => KeyCode::F35, + _ => KeyCode::Unidentified(NativeKeyCode::Unidentified), + }, + } +} + +pub fn convert_logical_key_code( + logical_key_code: &winit::keyboard::Key, +) -> bevy_input::keyboard::Key { + match logical_key_code { + Key::Character(s) => bevy_input::keyboard::Key::Character(s.clone()), + Key::Unidentified(nk) => bevy_input::keyboard::Key::Unidentified(convert_native_key(nk)), + Key::Dead(c) => bevy_input::keyboard::Key::Dead(c.to_owned()), + Key::Named(NamedKey::Alt) => bevy_input::keyboard::Key::Alt, + Key::Named(NamedKey::AltGraph) => bevy_input::keyboard::Key::AltGraph, + Key::Named(NamedKey::CapsLock) => bevy_input::keyboard::Key::CapsLock, + Key::Named(NamedKey::Control) => bevy_input::keyboard::Key::Control, + Key::Named(NamedKey::Fn) => bevy_input::keyboard::Key::Fn, + Key::Named(NamedKey::FnLock) => bevy_input::keyboard::Key::FnLock, + Key::Named(NamedKey::NumLock) => bevy_input::keyboard::Key::NumLock, + Key::Named(NamedKey::ScrollLock) => bevy_input::keyboard::Key::ScrollLock, + Key::Named(NamedKey::Shift) => bevy_input::keyboard::Key::Shift, + Key::Named(NamedKey::Symbol) => bevy_input::keyboard::Key::Symbol, + Key::Named(NamedKey::SymbolLock) => bevy_input::keyboard::Key::SymbolLock, + Key::Named(NamedKey::Meta) => bevy_input::keyboard::Key::Meta, + Key::Named(NamedKey::Hyper) => bevy_input::keyboard::Key::Hyper, + Key::Named(NamedKey::Super) => bevy_input::keyboard::Key::Super, + Key::Named(NamedKey::Enter) => bevy_input::keyboard::Key::Enter, + Key::Named(NamedKey::Tab) => bevy_input::keyboard::Key::Tab, + Key::Named(NamedKey::Space) => bevy_input::keyboard::Key::Space, + Key::Named(NamedKey::ArrowDown) => bevy_input::keyboard::Key::ArrowDown, + Key::Named(NamedKey::ArrowLeft) => bevy_input::keyboard::Key::ArrowLeft, + Key::Named(NamedKey::ArrowRight) => bevy_input::keyboard::Key::ArrowRight, + Key::Named(NamedKey::ArrowUp) => bevy_input::keyboard::Key::ArrowUp, + Key::Named(NamedKey::End) => bevy_input::keyboard::Key::End, + Key::Named(NamedKey::Home) => bevy_input::keyboard::Key::Home, + Key::Named(NamedKey::PageDown) => bevy_input::keyboard::Key::PageDown, + Key::Named(NamedKey::PageUp) => bevy_input::keyboard::Key::PageUp, + Key::Named(NamedKey::Backspace) => bevy_input::keyboard::Key::Backspace, + Key::Named(NamedKey::Clear) => bevy_input::keyboard::Key::Clear, + Key::Named(NamedKey::Copy) => bevy_input::keyboard::Key::Copy, + Key::Named(NamedKey::CrSel) => bevy_input::keyboard::Key::CrSel, + Key::Named(NamedKey::Cut) => bevy_input::keyboard::Key::Cut, + Key::Named(NamedKey::Delete) => bevy_input::keyboard::Key::Delete, + Key::Named(NamedKey::EraseEof) => bevy_input::keyboard::Key::EraseEof, + Key::Named(NamedKey::ExSel) => bevy_input::keyboard::Key::ExSel, + Key::Named(NamedKey::Insert) => bevy_input::keyboard::Key::Insert, + Key::Named(NamedKey::Paste) => bevy_input::keyboard::Key::Paste, + Key::Named(NamedKey::Redo) => bevy_input::keyboard::Key::Redo, + Key::Named(NamedKey::Undo) => bevy_input::keyboard::Key::Undo, + Key::Named(NamedKey::Accept) => bevy_input::keyboard::Key::Accept, + Key::Named(NamedKey::Again) => bevy_input::keyboard::Key::Again, + Key::Named(NamedKey::Attn) => bevy_input::keyboard::Key::Attn, + Key::Named(NamedKey::Cancel) => bevy_input::keyboard::Key::Cancel, + Key::Named(NamedKey::ContextMenu) => bevy_input::keyboard::Key::ContextMenu, + Key::Named(NamedKey::Escape) => bevy_input::keyboard::Key::Escape, + Key::Named(NamedKey::Execute) => bevy_input::keyboard::Key::Execute, + Key::Named(NamedKey::Find) => bevy_input::keyboard::Key::Find, + Key::Named(NamedKey::Help) => bevy_input::keyboard::Key::Help, + Key::Named(NamedKey::Pause) => bevy_input::keyboard::Key::Pause, + Key::Named(NamedKey::Play) => bevy_input::keyboard::Key::Play, + Key::Named(NamedKey::Props) => bevy_input::keyboard::Key::Props, + Key::Named(NamedKey::Select) => bevy_input::keyboard::Key::Select, + Key::Named(NamedKey::ZoomIn) => bevy_input::keyboard::Key::ZoomIn, + Key::Named(NamedKey::ZoomOut) => bevy_input::keyboard::Key::ZoomOut, + Key::Named(NamedKey::BrightnessDown) => bevy_input::keyboard::Key::BrightnessDown, + Key::Named(NamedKey::BrightnessUp) => bevy_input::keyboard::Key::BrightnessUp, + Key::Named(NamedKey::Eject) => bevy_input::keyboard::Key::Eject, + Key::Named(NamedKey::LogOff) => bevy_input::keyboard::Key::LogOff, + Key::Named(NamedKey::Power) => bevy_input::keyboard::Key::Power, + Key::Named(NamedKey::PowerOff) => bevy_input::keyboard::Key::PowerOff, + Key::Named(NamedKey::PrintScreen) => bevy_input::keyboard::Key::PrintScreen, + Key::Named(NamedKey::Hibernate) => bevy_input::keyboard::Key::Hibernate, + Key::Named(NamedKey::Standby) => bevy_input::keyboard::Key::Standby, + Key::Named(NamedKey::WakeUp) => bevy_input::keyboard::Key::WakeUp, + Key::Named(NamedKey::AllCandidates) => bevy_input::keyboard::Key::AllCandidates, + Key::Named(NamedKey::Alphanumeric) => bevy_input::keyboard::Key::Alphanumeric, + Key::Named(NamedKey::CodeInput) => bevy_input::keyboard::Key::CodeInput, + Key::Named(NamedKey::Compose) => bevy_input::keyboard::Key::Compose, + Key::Named(NamedKey::Convert) => bevy_input::keyboard::Key::Convert, + Key::Named(NamedKey::FinalMode) => bevy_input::keyboard::Key::FinalMode, + Key::Named(NamedKey::GroupFirst) => bevy_input::keyboard::Key::GroupFirst, + Key::Named(NamedKey::GroupLast) => bevy_input::keyboard::Key::GroupLast, + Key::Named(NamedKey::GroupNext) => bevy_input::keyboard::Key::GroupNext, + Key::Named(NamedKey::GroupPrevious) => bevy_input::keyboard::Key::GroupPrevious, + Key::Named(NamedKey::ModeChange) => bevy_input::keyboard::Key::ModeChange, + Key::Named(NamedKey::NextCandidate) => bevy_input::keyboard::Key::NextCandidate, + Key::Named(NamedKey::NonConvert) => bevy_input::keyboard::Key::NonConvert, + Key::Named(NamedKey::PreviousCandidate) => bevy_input::keyboard::Key::PreviousCandidate, + Key::Named(NamedKey::Process) => bevy_input::keyboard::Key::Process, + Key::Named(NamedKey::SingleCandidate) => bevy_input::keyboard::Key::SingleCandidate, + Key::Named(NamedKey::HangulMode) => bevy_input::keyboard::Key::HangulMode, + Key::Named(NamedKey::HanjaMode) => bevy_input::keyboard::Key::HanjaMode, + Key::Named(NamedKey::JunjaMode) => bevy_input::keyboard::Key::JunjaMode, + Key::Named(NamedKey::Eisu) => bevy_input::keyboard::Key::Eisu, + Key::Named(NamedKey::Hankaku) => bevy_input::keyboard::Key::Hankaku, + Key::Named(NamedKey::Hiragana) => bevy_input::keyboard::Key::Hiragana, + Key::Named(NamedKey::HiraganaKatakana) => bevy_input::keyboard::Key::HiraganaKatakana, + Key::Named(NamedKey::KanaMode) => bevy_input::keyboard::Key::KanaMode, + Key::Named(NamedKey::KanjiMode) => bevy_input::keyboard::Key::KanjiMode, + Key::Named(NamedKey::Katakana) => bevy_input::keyboard::Key::Katakana, + Key::Named(NamedKey::Romaji) => bevy_input::keyboard::Key::Romaji, + Key::Named(NamedKey::Zenkaku) => bevy_input::keyboard::Key::Zenkaku, + Key::Named(NamedKey::ZenkakuHankaku) => bevy_input::keyboard::Key::ZenkakuHankaku, + Key::Named(NamedKey::Soft1) => bevy_input::keyboard::Key::Soft1, + Key::Named(NamedKey::Soft2) => bevy_input::keyboard::Key::Soft2, + Key::Named(NamedKey::Soft3) => bevy_input::keyboard::Key::Soft3, + Key::Named(NamedKey::Soft4) => bevy_input::keyboard::Key::Soft4, + Key::Named(NamedKey::ChannelDown) => bevy_input::keyboard::Key::ChannelDown, + Key::Named(NamedKey::ChannelUp) => bevy_input::keyboard::Key::ChannelUp, + Key::Named(NamedKey::Close) => bevy_input::keyboard::Key::Close, + Key::Named(NamedKey::MailForward) => bevy_input::keyboard::Key::MailForward, + Key::Named(NamedKey::MailReply) => bevy_input::keyboard::Key::MailReply, + Key::Named(NamedKey::MailSend) => bevy_input::keyboard::Key::MailSend, + Key::Named(NamedKey::MediaClose) => bevy_input::keyboard::Key::MediaClose, + Key::Named(NamedKey::MediaFastForward) => bevy_input::keyboard::Key::MediaFastForward, + Key::Named(NamedKey::MediaPause) => bevy_input::keyboard::Key::MediaPause, + Key::Named(NamedKey::MediaPlay) => bevy_input::keyboard::Key::MediaPlay, + Key::Named(NamedKey::MediaPlayPause) => bevy_input::keyboard::Key::MediaPlayPause, + Key::Named(NamedKey::MediaRecord) => bevy_input::keyboard::Key::MediaRecord, + Key::Named(NamedKey::MediaRewind) => bevy_input::keyboard::Key::MediaRewind, + Key::Named(NamedKey::MediaStop) => bevy_input::keyboard::Key::MediaStop, + Key::Named(NamedKey::MediaTrackNext) => bevy_input::keyboard::Key::MediaTrackNext, + Key::Named(NamedKey::MediaTrackPrevious) => bevy_input::keyboard::Key::MediaTrackPrevious, + Key::Named(NamedKey::New) => bevy_input::keyboard::Key::New, + Key::Named(NamedKey::Open) => bevy_input::keyboard::Key::Open, + Key::Named(NamedKey::Print) => bevy_input::keyboard::Key::Print, + Key::Named(NamedKey::Save) => bevy_input::keyboard::Key::Save, + Key::Named(NamedKey::SpellCheck) => bevy_input::keyboard::Key::SpellCheck, + Key::Named(NamedKey::Key11) => bevy_input::keyboard::Key::Key11, + Key::Named(NamedKey::Key12) => bevy_input::keyboard::Key::Key12, + Key::Named(NamedKey::AudioBalanceLeft) => bevy_input::keyboard::Key::AudioBalanceLeft, + Key::Named(NamedKey::AudioBalanceRight) => bevy_input::keyboard::Key::AudioBalanceRight, + Key::Named(NamedKey::AudioBassBoostDown) => bevy_input::keyboard::Key::AudioBassBoostDown, + Key::Named(NamedKey::AudioBassBoostToggle) => { + bevy_input::keyboard::Key::AudioBassBoostToggle + } + Key::Named(NamedKey::AudioBassBoostUp) => bevy_input::keyboard::Key::AudioBassBoostUp, + Key::Named(NamedKey::AudioFaderFront) => bevy_input::keyboard::Key::AudioFaderFront, + Key::Named(NamedKey::AudioFaderRear) => bevy_input::keyboard::Key::AudioFaderRear, + Key::Named(NamedKey::AudioSurroundModeNext) => { + bevy_input::keyboard::Key::AudioSurroundModeNext + } + Key::Named(NamedKey::AudioTrebleDown) => bevy_input::keyboard::Key::AudioTrebleDown, + Key::Named(NamedKey::AudioTrebleUp) => bevy_input::keyboard::Key::AudioTrebleUp, + Key::Named(NamedKey::AudioVolumeDown) => bevy_input::keyboard::Key::AudioVolumeDown, + Key::Named(NamedKey::AudioVolumeUp) => bevy_input::keyboard::Key::AudioVolumeUp, + Key::Named(NamedKey::AudioVolumeMute) => bevy_input::keyboard::Key::AudioVolumeMute, + Key::Named(NamedKey::MicrophoneToggle) => bevy_input::keyboard::Key::MicrophoneToggle, + Key::Named(NamedKey::MicrophoneVolumeDown) => { + bevy_input::keyboard::Key::MicrophoneVolumeDown + } + Key::Named(NamedKey::MicrophoneVolumeUp) => bevy_input::keyboard::Key::MicrophoneVolumeUp, + Key::Named(NamedKey::MicrophoneVolumeMute) => { + bevy_input::keyboard::Key::MicrophoneVolumeMute + } + Key::Named(NamedKey::SpeechCorrectionList) => { + bevy_input::keyboard::Key::SpeechCorrectionList + } + Key::Named(NamedKey::SpeechInputToggle) => bevy_input::keyboard::Key::SpeechInputToggle, + Key::Named(NamedKey::LaunchApplication1) => bevy_input::keyboard::Key::LaunchApplication1, + Key::Named(NamedKey::LaunchApplication2) => bevy_input::keyboard::Key::LaunchApplication2, + Key::Named(NamedKey::LaunchCalendar) => bevy_input::keyboard::Key::LaunchCalendar, + Key::Named(NamedKey::LaunchContacts) => bevy_input::keyboard::Key::LaunchContacts, + Key::Named(NamedKey::LaunchMail) => bevy_input::keyboard::Key::LaunchMail, + Key::Named(NamedKey::LaunchMediaPlayer) => bevy_input::keyboard::Key::LaunchMediaPlayer, + Key::Named(NamedKey::LaunchMusicPlayer) => bevy_input::keyboard::Key::LaunchMusicPlayer, + Key::Named(NamedKey::LaunchPhone) => bevy_input::keyboard::Key::LaunchPhone, + Key::Named(NamedKey::LaunchScreenSaver) => bevy_input::keyboard::Key::LaunchScreenSaver, + Key::Named(NamedKey::LaunchSpreadsheet) => bevy_input::keyboard::Key::LaunchSpreadsheet, + Key::Named(NamedKey::LaunchWebBrowser) => bevy_input::keyboard::Key::LaunchWebBrowser, + Key::Named(NamedKey::LaunchWebCam) => bevy_input::keyboard::Key::LaunchWebCam, + Key::Named(NamedKey::LaunchWordProcessor) => bevy_input::keyboard::Key::LaunchWordProcessor, + Key::Named(NamedKey::BrowserBack) => bevy_input::keyboard::Key::BrowserBack, + Key::Named(NamedKey::BrowserFavorites) => bevy_input::keyboard::Key::BrowserFavorites, + Key::Named(NamedKey::BrowserForward) => bevy_input::keyboard::Key::BrowserForward, + Key::Named(NamedKey::BrowserHome) => bevy_input::keyboard::Key::BrowserHome, + Key::Named(NamedKey::BrowserRefresh) => bevy_input::keyboard::Key::BrowserRefresh, + Key::Named(NamedKey::BrowserSearch) => bevy_input::keyboard::Key::BrowserSearch, + Key::Named(NamedKey::BrowserStop) => bevy_input::keyboard::Key::BrowserStop, + Key::Named(NamedKey::AppSwitch) => bevy_input::keyboard::Key::AppSwitch, + Key::Named(NamedKey::Call) => bevy_input::keyboard::Key::Call, + Key::Named(NamedKey::Camera) => bevy_input::keyboard::Key::Camera, + Key::Named(NamedKey::CameraFocus) => bevy_input::keyboard::Key::CameraFocus, + Key::Named(NamedKey::EndCall) => bevy_input::keyboard::Key::EndCall, + Key::Named(NamedKey::GoBack) => bevy_input::keyboard::Key::GoBack, + Key::Named(NamedKey::GoHome) => bevy_input::keyboard::Key::GoHome, + Key::Named(NamedKey::HeadsetHook) => bevy_input::keyboard::Key::HeadsetHook, + Key::Named(NamedKey::LastNumberRedial) => bevy_input::keyboard::Key::LastNumberRedial, + Key::Named(NamedKey::Notification) => bevy_input::keyboard::Key::Notification, + Key::Named(NamedKey::MannerMode) => bevy_input::keyboard::Key::MannerMode, + Key::Named(NamedKey::VoiceDial) => bevy_input::keyboard::Key::VoiceDial, + Key::Named(NamedKey::TV) => bevy_input::keyboard::Key::TV, + Key::Named(NamedKey::TV3DMode) => bevy_input::keyboard::Key::TV3DMode, + Key::Named(NamedKey::TVAntennaCable) => bevy_input::keyboard::Key::TVAntennaCable, + Key::Named(NamedKey::TVAudioDescription) => bevy_input::keyboard::Key::TVAudioDescription, + Key::Named(NamedKey::TVAudioDescriptionMixDown) => { + bevy_input::keyboard::Key::TVAudioDescriptionMixDown + } + Key::Named(NamedKey::TVAudioDescriptionMixUp) => { + bevy_input::keyboard::Key::TVAudioDescriptionMixUp + } + Key::Named(NamedKey::TVContentsMenu) => bevy_input::keyboard::Key::TVContentsMenu, + Key::Named(NamedKey::TVDataService) => bevy_input::keyboard::Key::TVDataService, + Key::Named(NamedKey::TVInput) => bevy_input::keyboard::Key::TVInput, + Key::Named(NamedKey::TVInputComponent1) => bevy_input::keyboard::Key::TVInputComponent1, + Key::Named(NamedKey::TVInputComponent2) => bevy_input::keyboard::Key::TVInputComponent2, + Key::Named(NamedKey::TVInputComposite1) => bevy_input::keyboard::Key::TVInputComposite1, + Key::Named(NamedKey::TVInputComposite2) => bevy_input::keyboard::Key::TVInputComposite2, + Key::Named(NamedKey::TVInputHDMI1) => bevy_input::keyboard::Key::TVInputHDMI1, + Key::Named(NamedKey::TVInputHDMI2) => bevy_input::keyboard::Key::TVInputHDMI2, + Key::Named(NamedKey::TVInputHDMI3) => bevy_input::keyboard::Key::TVInputHDMI3, + Key::Named(NamedKey::TVInputHDMI4) => bevy_input::keyboard::Key::TVInputHDMI4, + Key::Named(NamedKey::TVInputVGA1) => bevy_input::keyboard::Key::TVInputVGA1, + Key::Named(NamedKey::TVMediaContext) => bevy_input::keyboard::Key::TVMediaContext, + Key::Named(NamedKey::TVNetwork) => bevy_input::keyboard::Key::TVNetwork, + Key::Named(NamedKey::TVNumberEntry) => bevy_input::keyboard::Key::TVNumberEntry, + Key::Named(NamedKey::TVPower) => bevy_input::keyboard::Key::TVPower, + Key::Named(NamedKey::TVRadioService) => bevy_input::keyboard::Key::TVRadioService, + Key::Named(NamedKey::TVSatellite) => bevy_input::keyboard::Key::TVSatellite, + Key::Named(NamedKey::TVSatelliteBS) => bevy_input::keyboard::Key::TVSatelliteBS, + Key::Named(NamedKey::TVSatelliteCS) => bevy_input::keyboard::Key::TVSatelliteCS, + Key::Named(NamedKey::TVSatelliteToggle) => bevy_input::keyboard::Key::TVSatelliteToggle, + Key::Named(NamedKey::TVTerrestrialAnalog) => bevy_input::keyboard::Key::TVTerrestrialAnalog, + Key::Named(NamedKey::TVTerrestrialDigital) => { + bevy_input::keyboard::Key::TVTerrestrialDigital + } + Key::Named(NamedKey::TVTimer) => bevy_input::keyboard::Key::TVTimer, + Key::Named(NamedKey::AVRInput) => bevy_input::keyboard::Key::AVRInput, + Key::Named(NamedKey::AVRPower) => bevy_input::keyboard::Key::AVRPower, + Key::Named(NamedKey::ColorF0Red) => bevy_input::keyboard::Key::ColorF0Red, + Key::Named(NamedKey::ColorF1Green) => bevy_input::keyboard::Key::ColorF1Green, + Key::Named(NamedKey::ColorF2Yellow) => bevy_input::keyboard::Key::ColorF2Yellow, + Key::Named(NamedKey::ColorF3Blue) => bevy_input::keyboard::Key::ColorF3Blue, + Key::Named(NamedKey::ColorF4Grey) => bevy_input::keyboard::Key::ColorF4Grey, + Key::Named(NamedKey::ColorF5Brown) => bevy_input::keyboard::Key::ColorF5Brown, + Key::Named(NamedKey::ClosedCaptionToggle) => bevy_input::keyboard::Key::ClosedCaptionToggle, + Key::Named(NamedKey::Dimmer) => bevy_input::keyboard::Key::Dimmer, + Key::Named(NamedKey::DisplaySwap) => bevy_input::keyboard::Key::DisplaySwap, + Key::Named(NamedKey::DVR) => bevy_input::keyboard::Key::DVR, + Key::Named(NamedKey::Exit) => bevy_input::keyboard::Key::Exit, + Key::Named(NamedKey::FavoriteClear0) => bevy_input::keyboard::Key::FavoriteClear0, + Key::Named(NamedKey::FavoriteClear1) => bevy_input::keyboard::Key::FavoriteClear1, + Key::Named(NamedKey::FavoriteClear2) => bevy_input::keyboard::Key::FavoriteClear2, + Key::Named(NamedKey::FavoriteClear3) => bevy_input::keyboard::Key::FavoriteClear3, + Key::Named(NamedKey::FavoriteRecall0) => bevy_input::keyboard::Key::FavoriteRecall0, + Key::Named(NamedKey::FavoriteRecall1) => bevy_input::keyboard::Key::FavoriteRecall1, + Key::Named(NamedKey::FavoriteRecall2) => bevy_input::keyboard::Key::FavoriteRecall2, + Key::Named(NamedKey::FavoriteRecall3) => bevy_input::keyboard::Key::FavoriteRecall3, + Key::Named(NamedKey::FavoriteStore0) => bevy_input::keyboard::Key::FavoriteStore0, + Key::Named(NamedKey::FavoriteStore1) => bevy_input::keyboard::Key::FavoriteStore1, + Key::Named(NamedKey::FavoriteStore2) => bevy_input::keyboard::Key::FavoriteStore2, + Key::Named(NamedKey::FavoriteStore3) => bevy_input::keyboard::Key::FavoriteStore3, + Key::Named(NamedKey::Guide) => bevy_input::keyboard::Key::Guide, + Key::Named(NamedKey::GuideNextDay) => bevy_input::keyboard::Key::GuideNextDay, + Key::Named(NamedKey::GuidePreviousDay) => bevy_input::keyboard::Key::GuidePreviousDay, + Key::Named(NamedKey::Info) => bevy_input::keyboard::Key::Info, + Key::Named(NamedKey::InstantReplay) => bevy_input::keyboard::Key::InstantReplay, + Key::Named(NamedKey::Link) => bevy_input::keyboard::Key::Link, + Key::Named(NamedKey::ListProgram) => bevy_input::keyboard::Key::ListProgram, + Key::Named(NamedKey::LiveContent) => bevy_input::keyboard::Key::LiveContent, + Key::Named(NamedKey::Lock) => bevy_input::keyboard::Key::Lock, + Key::Named(NamedKey::MediaApps) => bevy_input::keyboard::Key::MediaApps, + Key::Named(NamedKey::MediaAudioTrack) => bevy_input::keyboard::Key::MediaAudioTrack, + Key::Named(NamedKey::MediaLast) => bevy_input::keyboard::Key::MediaLast, + Key::Named(NamedKey::MediaSkipBackward) => bevy_input::keyboard::Key::MediaSkipBackward, + Key::Named(NamedKey::MediaSkipForward) => bevy_input::keyboard::Key::MediaSkipForward, + Key::Named(NamedKey::MediaStepBackward) => bevy_input::keyboard::Key::MediaStepBackward, + Key::Named(NamedKey::MediaStepForward) => bevy_input::keyboard::Key::MediaStepForward, + Key::Named(NamedKey::MediaTopMenu) => bevy_input::keyboard::Key::MediaTopMenu, + Key::Named(NamedKey::NavigateIn) => bevy_input::keyboard::Key::NavigateIn, + Key::Named(NamedKey::NavigateNext) => bevy_input::keyboard::Key::NavigateNext, + Key::Named(NamedKey::NavigateOut) => bevy_input::keyboard::Key::NavigateOut, + Key::Named(NamedKey::NavigatePrevious) => bevy_input::keyboard::Key::NavigatePrevious, + Key::Named(NamedKey::NextFavoriteChannel) => bevy_input::keyboard::Key::NextFavoriteChannel, + Key::Named(NamedKey::NextUserProfile) => bevy_input::keyboard::Key::NextUserProfile, + Key::Named(NamedKey::OnDemand) => bevy_input::keyboard::Key::OnDemand, + Key::Named(NamedKey::Pairing) => bevy_input::keyboard::Key::Pairing, + Key::Named(NamedKey::PinPDown) => bevy_input::keyboard::Key::PinPDown, + Key::Named(NamedKey::PinPMove) => bevy_input::keyboard::Key::PinPMove, + Key::Named(NamedKey::PinPToggle) => bevy_input::keyboard::Key::PinPToggle, + Key::Named(NamedKey::PinPUp) => bevy_input::keyboard::Key::PinPUp, + Key::Named(NamedKey::PlaySpeedDown) => bevy_input::keyboard::Key::PlaySpeedDown, + Key::Named(NamedKey::PlaySpeedReset) => bevy_input::keyboard::Key::PlaySpeedReset, + Key::Named(NamedKey::PlaySpeedUp) => bevy_input::keyboard::Key::PlaySpeedUp, + Key::Named(NamedKey::RandomToggle) => bevy_input::keyboard::Key::RandomToggle, + Key::Named(NamedKey::RcLowBattery) => bevy_input::keyboard::Key::RcLowBattery, + Key::Named(NamedKey::RecordSpeedNext) => bevy_input::keyboard::Key::RecordSpeedNext, + Key::Named(NamedKey::RfBypass) => bevy_input::keyboard::Key::RfBypass, + Key::Named(NamedKey::ScanChannelsToggle) => bevy_input::keyboard::Key::ScanChannelsToggle, + Key::Named(NamedKey::ScreenModeNext) => bevy_input::keyboard::Key::ScreenModeNext, + Key::Named(NamedKey::Settings) => bevy_input::keyboard::Key::Settings, + Key::Named(NamedKey::SplitScreenToggle) => bevy_input::keyboard::Key::SplitScreenToggle, + Key::Named(NamedKey::STBInput) => bevy_input::keyboard::Key::STBInput, + Key::Named(NamedKey::STBPower) => bevy_input::keyboard::Key::STBPower, + Key::Named(NamedKey::Subtitle) => bevy_input::keyboard::Key::Subtitle, + Key::Named(NamedKey::Teletext) => bevy_input::keyboard::Key::Teletext, + Key::Named(NamedKey::VideoModeNext) => bevy_input::keyboard::Key::VideoModeNext, + Key::Named(NamedKey::Wink) => bevy_input::keyboard::Key::Wink, + Key::Named(NamedKey::ZoomToggle) => bevy_input::keyboard::Key::ZoomToggle, + Key::Named(NamedKey::F1) => bevy_input::keyboard::Key::F1, + Key::Named(NamedKey::F2) => bevy_input::keyboard::Key::F2, + Key::Named(NamedKey::F3) => bevy_input::keyboard::Key::F3, + Key::Named(NamedKey::F4) => bevy_input::keyboard::Key::F4, + Key::Named(NamedKey::F5) => bevy_input::keyboard::Key::F5, + Key::Named(NamedKey::F6) => bevy_input::keyboard::Key::F6, + Key::Named(NamedKey::F7) => bevy_input::keyboard::Key::F7, + Key::Named(NamedKey::F8) => bevy_input::keyboard::Key::F8, + Key::Named(NamedKey::F9) => bevy_input::keyboard::Key::F9, + Key::Named(NamedKey::F10) => bevy_input::keyboard::Key::F10, + Key::Named(NamedKey::F11) => bevy_input::keyboard::Key::F11, + Key::Named(NamedKey::F12) => bevy_input::keyboard::Key::F12, + Key::Named(NamedKey::F13) => bevy_input::keyboard::Key::F13, + Key::Named(NamedKey::F14) => bevy_input::keyboard::Key::F14, + Key::Named(NamedKey::F15) => bevy_input::keyboard::Key::F15, + Key::Named(NamedKey::F16) => bevy_input::keyboard::Key::F16, + Key::Named(NamedKey::F17) => bevy_input::keyboard::Key::F17, + Key::Named(NamedKey::F18) => bevy_input::keyboard::Key::F18, + Key::Named(NamedKey::F19) => bevy_input::keyboard::Key::F19, + Key::Named(NamedKey::F20) => bevy_input::keyboard::Key::F20, + Key::Named(NamedKey::F21) => bevy_input::keyboard::Key::F21, + Key::Named(NamedKey::F22) => bevy_input::keyboard::Key::F22, + Key::Named(NamedKey::F23) => bevy_input::keyboard::Key::F23, + Key::Named(NamedKey::F24) => bevy_input::keyboard::Key::F24, + Key::Named(NamedKey::F25) => bevy_input::keyboard::Key::F25, + Key::Named(NamedKey::F26) => bevy_input::keyboard::Key::F26, + Key::Named(NamedKey::F27) => bevy_input::keyboard::Key::F27, + Key::Named(NamedKey::F28) => bevy_input::keyboard::Key::F28, + Key::Named(NamedKey::F29) => bevy_input::keyboard::Key::F29, + Key::Named(NamedKey::F30) => bevy_input::keyboard::Key::F30, + Key::Named(NamedKey::F31) => bevy_input::keyboard::Key::F31, + Key::Named(NamedKey::F32) => bevy_input::keyboard::Key::F32, + Key::Named(NamedKey::F33) => bevy_input::keyboard::Key::F33, + Key::Named(NamedKey::F34) => bevy_input::keyboard::Key::F34, + Key::Named(NamedKey::F35) => bevy_input::keyboard::Key::F35, + _ => todo!(), + } +} + +pub fn convert_native_key(native_key: &NativeKey) -> bevy_input::keyboard::NativeKey { + match native_key { + NativeKey::Unidentified => bevy_input::keyboard::NativeKey::Unidentified, + NativeKey::Android(v) => bevy_input::keyboard::NativeKey::Android(*v), + NativeKey::MacOS(v) => bevy_input::keyboard::NativeKey::MacOS(*v), + NativeKey::Windows(v) => bevy_input::keyboard::NativeKey::Windows(*v), + NativeKey::Xkb(v) => bevy_input::keyboard::NativeKey::Xkb(*v), + NativeKey::Web(v) => bevy_input::keyboard::NativeKey::Web(v.clone()), } } pub fn convert_cursor_icon(cursor_icon: CursorIcon) -> winit::window::CursorIcon { match cursor_icon { - CursorIcon::Default => winit::window::CursorIcon::Default, CursorIcon::Crosshair => winit::window::CursorIcon::Crosshair, - CursorIcon::Hand => winit::window::CursorIcon::Hand, - CursorIcon::Arrow => winit::window::CursorIcon::Arrow, + CursorIcon::Pointer => winit::window::CursorIcon::Pointer, CursorIcon::Move => winit::window::CursorIcon::Move, CursorIcon::Text => winit::window::CursorIcon::Text, CursorIcon::Wait => winit::window::CursorIcon::Wait, @@ -269,6 +662,7 @@ pub fn convert_cursor_icon(cursor_icon: CursorIcon) -> winit::window::CursorIcon CursorIcon::NwseResize => winit::window::CursorIcon::NwseResize, CursorIcon::ColResize => winit::window::CursorIcon::ColResize, CursorIcon::RowResize => winit::window::CursorIcon::RowResize, + _ => winit::window::CursorIcon::Default, } } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 7d531a281a432..fba7bf66676f9 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -15,14 +15,16 @@ mod winit_config; mod winit_windows; use bevy_a11y::AccessibilityRequested; +use bevy_ecs::system::{SystemParam, SystemState}; +use bevy_utils::{Duration, Instant}; use system::{changed_windows, create_windows, despawn_windows, CachedWindow}; + pub use winit_config::*; pub use winit_windows::*; use bevy_app::{App, AppExit, Last, Plugin, PluginsState}; use bevy_ecs::event::{Events, ManualEventReader}; use bevy_ecs::prelude::*; -use bevy_ecs::system::{SystemParam, SystemState}; use bevy_input::{ keyboard::KeyboardInput, mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}, @@ -30,12 +32,11 @@ use bevy_input::{ touchpad::{TouchpadMagnify, TouchpadRotate}, }; use bevy_math::{ivec2, DVec2, Vec2}; + #[cfg(not(target_arch = "wasm32"))] use bevy_tasks::tick_global_task_pools_on_main_thread; -use bevy_utils::{ - tracing::{trace, warn}, - Duration, Instant, -}; + +use bevy_utils::tracing::{error, trace, warn}; use bevy_window::{ exit_on_all_closed, ApplicationLifetime, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, Ime, ReceivedCharacter, RequestRedraw, Window, @@ -146,7 +147,9 @@ impl Plugin for WinitPlugin { #[cfg(target_arch = "wasm32")] app.add_plugins(CanvasParentResizePlugin); - let event_loop = event_loop_builder.build(); + let event_loop = event_loop_builder + .build() + .expect("Failed creating event loop"); // iOS, macOS, and Android don't like it if you create windows before the event loop is // initialized. @@ -227,46 +230,6 @@ impl Plugin for WinitPlugin { } } -fn run(event_loop: EventLoop, event_handler: F) -> ! -where - F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), -{ - event_loop.run(event_handler) -} - -#[cfg(any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] -fn run_return(event_loop: &mut EventLoop, event_handler: F) -where - F: FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), -{ - use winit::platform::run_return::EventLoopExtRunReturn; - event_loop.run_return(event_handler); -} - -#[cfg(not(any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -)))] -fn run_return(_event_loop: &mut EventLoop, _event_handler: F) -where - F: FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), -{ - panic!("Run return is not supported on this platform!") -} - #[derive(SystemParam)] struct WindowAndInputEventWriters<'w> { // `winit` `WindowEvent`s @@ -361,8 +324,6 @@ pub fn winit_runner(mut app: App) { .remove_non_send_resource::>() .unwrap(); - let return_from_run = app.world.resource::().return_from_run; - app.world .insert_non_send_resource(event_loop.create_proxy()); @@ -406,9 +367,7 @@ pub fn winit_runner(mut app: App) { )> = SystemState::from_world(&mut app.world); // setup up the event loop - let event_handler = move |event: Event<()>, - event_loop: &EventLoopWindowTarget<()>, - control_flow: &mut ControlFlow| { + let event_handler = move |event: Event<()>, event_loop: &EventLoopWindowTarget<()>| { #[cfg(feature = "trace")] let _span = bevy_utils::tracing::info_span!("winit event_handler").entered(); @@ -423,7 +382,7 @@ pub fn winit_runner(mut app: App) { if let Some(app_exit_events) = app.world.get_resource::>() { if app_exit_event_reader.read(app_exit_events).last().is_some() { - *control_flow = ControlFlow::Exit; + event_loop.exit(); return; } } @@ -507,11 +466,7 @@ pub fn winit_runner(mut app: App) { // the engine. if let Some(adapter) = access_kit_adapters.get(&window_entity) { if let Some(window) = winit_windows.get_window(window_entity) { - // Somewhat surprisingly, this call has meaningful side effects - // See https://github.com/AccessKit/accesskit/issues/300 - // AccessKit might later need to filter events based on this, but we currently do not. - // See https://github.com/bevyengine/bevy/pull/10239#issuecomment-1775572176 - let _ = adapter.on_event(window, &event); + adapter.process_event(window, &event); } } @@ -519,15 +474,7 @@ pub fn winit_runner(mut app: App) { match event { WindowEvent::Resized(size) => { - window - .resolution - .set_physical_resolution(size.width, size.height); - - event_writers.window_resized.send(WindowResized { - window: window_entity, - width: window.width(), - height: window.height(), - }); + react_to_resize(&mut window, size, &mut event_writers, window_entity); } WindowEvent::CloseRequested => { event_writers @@ -536,10 +483,20 @@ pub fn winit_runner(mut app: App) { window: window_entity, }); } - WindowEvent::KeyboardInput { ref input, .. } => { - event_writers - .keyboard_input - .send(converters::convert_keyboard_input(input, window_entity)); + WindowEvent::KeyboardInput { ref event, .. } => { + let keyboard_event = + converters::convert_keyboard_input(event, window_entity); + if let bevy_input::keyboard::Key::Character(c) = + converters::convert_logical_key_code(&event.logical_key) + { + if let Some(first_char) = c.chars().next() { + event_writers.character_input.send(ReceivedCharacter { + window: window_entity, + char: first_char, + }); + } + } + event_writers.keyboard_input.send(keyboard_event); } WindowEvent::CursorMoved { position, .. } => { let physical_position = DVec2::new(position.x, position.y); @@ -602,15 +559,9 @@ pub fn winit_runner(mut app: App) { .touch_input .send(converters::convert_touch_input(touch, location)); } - WindowEvent::ReceivedCharacter(char) => { - event_writers.character_input.send(ReceivedCharacter { - window: window_entity, - char, - }); - } WindowEvent::ScaleFactorChanged { scale_factor, - new_inner_size, + mut inner_size_writer, } => { event_writers.window_backend_scale_factor_changed.send( WindowBackendScaleFactorChanged { @@ -623,13 +574,22 @@ pub fn winit_runner(mut app: App) { window.resolution.set_scale_factor(scale_factor); let new_factor = window.resolution.scale_factor(); + let mut new_inner_size = winit::dpi::PhysicalSize::new( + window.physical_width(), + window.physical_height(), + ); if let Some(forced_factor) = window.resolution.scale_factor_override() { // This window is overriding the OS-suggested DPI, so its physical size // should be set based on the overriding value. Its logical size already // incorporates any resize constraints. - *new_inner_size = + let maybe_new_inner_size = winit::dpi::LogicalSize::new(window.width(), window.height()) .to_physical::(forced_factor); + if let Err(err) = inner_size_writer.request_inner_size(new_inner_size) { + warn!("Winit Failed to resize the window: {err}"); + } else { + new_inner_size = maybe_new_inner_size; + } } else if approx::relative_ne!(new_factor, prior_factor) { event_writers.window_scale_factor_changed.send( WindowScaleFactorChanged { @@ -641,6 +601,7 @@ pub fn winit_runner(mut app: App) { let new_logical_width = (new_inner_size.width as f64 / new_factor) as f32; let new_logical_height = (new_inner_size.height as f64 / new_factor) as f32; + if approx::relative_ne!(window.width(), new_logical_width) || approx::relative_ne!(window.height(), new_logical_height) { @@ -802,7 +763,7 @@ pub fn winit_runner(mut app: App) { *control_flow = ControlFlow::Poll; } } - event::Event::MainEventsCleared => { + event::Event::AboutToWait => { if runner_state.active.should_run() { if runner_state.active == ActiveState::WillSuspend { runner_state.active = ActiveState::Suspended; @@ -847,15 +808,17 @@ pub fn winit_runner(mut app: App) { let (config, windows) = focused_windows_state.get(&app.world); let focused = windows.iter().any(|window| window.focused); match config.update_mode(focused) { - UpdateMode::Continuous => *control_flow = ControlFlow::Poll, + UpdateMode::Continuous => { + event_loop.set_control_flow(ControlFlow::Poll); + } UpdateMode::Reactive { wait } | UpdateMode::ReactiveLowPower { wait } => { if let Some(next) = runner_state.last_update.checked_add(*wait) { runner_state.scheduled_update = Some(next); - *control_flow = ControlFlow::WaitUntil(next); + event_loop.set_control_flow(ControlFlow::WaitUntil(next)); } else { runner_state.scheduled_update = None; - *control_flow = ControlFlow::Wait; + event_loop.set_control_flow(ControlFlow::Wait); } } } @@ -865,13 +828,13 @@ pub fn winit_runner(mut app: App) { { if redraw_event_reader.read(app_redraw_events).last().is_some() { runner_state.redraw_requested = true; - *control_flow = ControlFlow::Poll; + event_loop.set_control_flow(ControlFlow::Poll); } } if let Some(app_exit_events) = app.world.get_resource::>() { if app_exit_event_reader.read(app_exit_events).last().is_some() { - *control_flow = ControlFlow::Exit; + event_loop.exit(); } } } @@ -922,9 +885,24 @@ pub fn winit_runner(mut app: App) { }; trace!("starting winit event loop"); - if return_from_run { - run_return(&mut event_loop, event_handler); - } else { - run(event_loop, event_handler); + if let Err(err) = event_loop.run(event_handler) { + error!("winit event loop returned an error: {err}"); } } + +fn react_to_resize( + window: &mut Mut<'_, Window>, + size: winit::dpi::PhysicalSize, + event_writers: &mut WindowAndInputEventWriters<'_>, + window_entity: Entity, +) { + window + .resolution + .set_physical_resolution(size.width, size.height); + + event_writers.window_resized.send(WindowResized { + window: window_entity, + width: window.width(), + height: window.height(), + }); +} diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 896466f3c7073..c6a61ab4e4292 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -27,7 +27,7 @@ use crate::{ self, convert_enabled_buttons, convert_window_level, convert_window_theme, convert_winit_theme, }, - get_best_videomode, get_fitting_videomode, WinitWindows, + get_best_videomode, get_fitting_videomode, WindowAndInputEventWriters, WinitWindows, }; /// Creates new windows on the [`winit`] backend for each entity with a newly-added @@ -138,6 +138,7 @@ pub struct CachedWindow { pub(crate) fn changed_windows( mut changed_windows: Query<(Entity, &mut Window, &mut CachedWindow), Changed>, winit_windows: NonSendMut, + mut event_writers: WindowAndInputEventWriters<'_>, ) { for (entity, mut window, mut cache) in &mut changed_windows { if let Some(winit_window) = winit_windows.get_window(entity) { @@ -174,7 +175,9 @@ pub(crate) fn changed_windows( window.resolution.physical_width(), window.resolution.physical_height(), ); - winit_window.set_inner_size(physical_size); + if let Some(size_now) = winit_window.request_inner_size(physical_size) { + crate::react_to_resize(&mut window, size_now, &mut event_writers, entity); + } } if window.physical_cursor_position() != cache.window.physical_cursor_position() { @@ -298,10 +301,10 @@ pub(crate) fn changed_windows( } if window.ime_position != cache.window.ime_position { - winit_window.set_ime_position(LogicalPosition::new( - window.ime_position.x, - window.ime_position.y, - )); + winit_window.set_ime_cursor_area( + LogicalPosition::new(window.ime_position.x, window.ime_position.y), + PhysicalSize::new(10, 10), + ); } if window.window_theme != cache.window.window_theme { diff --git a/crates/bevy_winit/src/web_resize.rs b/crates/bevy_winit/src/web_resize.rs index a53075dea3883..4a43bfb911b05 100644 --- a/crates/bevy_winit/src/web_resize.rs +++ b/crates/bevy_winit/src/web_resize.rs @@ -31,7 +31,7 @@ fn canvas_parent_resize_event_handler( ) { for event in resize_events.receiver.try_iter() { if let Some(window) = winit_windows.get_window(event.window) { - window.set_inner_size(event.size); + let _ = window.request_inner_size(event.size); } } } diff --git a/crates/bevy_winit/src/winit_config.rs b/crates/bevy_winit/src/winit_config.rs index d6b22ecf21535..b91e25d340afa 100644 --- a/crates/bevy_winit/src/winit_config.rs +++ b/crates/bevy_winit/src/winit_config.rs @@ -4,32 +4,6 @@ use bevy_utils::Duration; /// Settings for the [`WinitPlugin`](super::WinitPlugin). #[derive(Debug, Resource)] pub struct WinitSettings { - /// Controls how the [`EventLoop`](winit::event_loop::EventLoop) is deployed. - /// - /// - If this value is set to `false` (default), [`run`] is called, and exiting the loop will - /// terminate the program. - /// - If this value is set to `true`, [`run_return`] is called, and exiting the loop will - /// return control to the caller. - /// - /// **Note:** This cannot be changed while the loop is running. `winit` also discourages use of - /// `run_return`. - /// - /// # Supported platforms - /// - /// `run_return` is only available on the following `target_os` environments: - /// - `windows` - /// - `macos` - /// - `linux` - /// - `freebsd` - /// - `openbsd` - /// - `netbsd` - /// - `dragonfly` - /// - /// The runner will panic if this is set to `true` on other platforms. - /// - /// [`run`]: https://docs.rs/winit/latest/winit/event_loop/struct.EventLoop.html#method.run - /// [`run_return`]: https://docs.rs/winit/latest/winit/platform/run_return/trait.EventLoopExtRunReturn.html#tymethod.run_return - pub return_from_run: bool, /// Determines how frequently the application can update when it has focus. pub focused_mode: UpdateMode, /// Determines how frequently the application can update when it's out of focus. @@ -47,7 +21,6 @@ impl WinitSettings { unfocused_mode: UpdateMode::ReactiveLowPower { wait: Duration::from_secs_f64(1.0 / 60.0), // 60Hz }, - ..Default::default() } } @@ -63,7 +36,6 @@ impl WinitSettings { unfocused_mode: UpdateMode::ReactiveLowPower { wait: Duration::from_secs(60), }, - ..Default::default() } } @@ -81,7 +53,6 @@ impl WinitSettings { impl Default for WinitSettings { fn default() -> Self { WinitSettings { - return_from_run: false, focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, } diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 43c0e414b2956..628f9cf486646 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -194,7 +194,7 @@ impl WinitWindows { use winit::platform::web::WindowExtWebSys; if window.canvas.is_none() { - let canvas = winit_window.canvas(); + let canvas = winit_window.canvas().unwrap(); let window = web_sys::window().unwrap(); let document = window.document().unwrap(); diff --git a/examples/2d/2d_gizmos.rs b/examples/2d/2d_gizmos.rs index a5aadbb2ade7d..740f83803e989 100644 --- a/examples/2d/2d_gizmos.rs +++ b/examples/2d/2d_gizmos.rs @@ -62,10 +62,10 @@ fn system(mut gizmos: Gizmos, time: Res