From cbe91d4a7cc6ef105747884425a3f12e00247856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 13 Sep 2024 03:02:07 +0200 Subject: [PATCH 1/3] Add `physical_key` to `keyboard::Event` Co-authored-by: Exidex <16986685+Exidex@users.noreply.github.com> --- core/src/keyboard/event.rs | 4 + core/src/keyboard/key.rs | 533 +++++++++++++++++++++++++++++++++++++ winit/src/conversion.rs | 260 +++++++++++++++++- 3 files changed, 795 insertions(+), 2 deletions(-) diff --git a/core/src/keyboard/event.rs b/core/src/keyboard/event.rs index 1eb4233476..09625b1836 100644 --- a/core/src/keyboard/event.rs +++ b/core/src/keyboard/event.rs @@ -1,3 +1,4 @@ +use crate::keyboard::key; use crate::keyboard::{Key, Location, Modifiers}; use crate::SmolStr; @@ -14,6 +15,9 @@ pub enum Event { /// The key pressed. key: Key, + /// The physical key pressed. + physical_key: key::Physical, + /// The location of the key. location: Location, diff --git a/core/src/keyboard/key.rs b/core/src/keyboard/key.rs index dbde51965c..219452d788 100644 --- a/core/src/keyboard/key.rs +++ b/core/src/keyboard/key.rs @@ -742,3 +742,536 @@ pub enum Named { /// General-purpose function key. F35, } + +/// Code representing the location of a physical key. +/// +/// This mostly conforms to the UI Events Specification's [`KeyboardEvent.code`] with a few +/// exceptions: +/// - The keys that the specification calls "MetaLeft" and "MetaRight" are named "SuperLeft" and +/// "SuperRight" here. +/// - The key that the specification calls "Super" is reported as `Unidentified` here. +/// +/// [`KeyboardEvent.code`]: https://w3c.github.io/uievents-code/#code-value-tables +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[allow(missing_docs)] +#[non_exhaustive] +pub enum Code { + /// ` 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, + 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, + /// 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, + /// Some laptops place this key to the right of the key. + BrowserForward, + /// The "home" button on Android. + BrowserHome, + BrowserRefresh, + BrowserSearch, + 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, + MediaPlayPause, + MediaSelect, + MediaStop, + MediaTrackNext, + MediaTrackPrevious, + /// This key is placed in the function section on some Apple keyboards, replacing the + /// Eject key. + Power, + Sleep, + AudioVolumeDown, + AudioVolumeMute, + AudioVolumeUp, + WakeUp, + // Legacy modifier key. Also called "Super" in certain places. + Meta, + // Legacy modifier key. + Hyper, + Turbo, + Abort, + Resume, + 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, + /// 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, +} + +/// 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, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum NativeCode { + /// An unidentified code. + Unidentified, + /// An Android "scancode". + Android(u32), + /// A macOS "scancode". + MacOS(u16), + /// A Windows "scancode". + Windows(u16), + /// An XKB "keycode". + Xkb(u32), +} + +/// Represents the location of a physical key. +/// +/// This type is a superset of [`KeyCode`], including an [`Unidentified`][Self::Unidentified] +/// variant. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Physical { + /// A known key code + Code(Code), + /// This variant is used when the key cannot be translated to a [`KeyCode`] + /// + /// The native keycode is provided (if available) so you're able to more reliably match + /// key-press and key-release events by hashing the [`PhysicalKey`]. It is also possible to use + /// this for keybinds for non-standard keys, but such keybinds are tied to a given platform. + Unidentified(NativeCode), +} + +impl PartialEq for Physical { + #[inline] + fn eq(&self, rhs: &Code) -> bool { + match self { + Physical::Code(ref code) => code == rhs, + Physical::Unidentified(_) => false, + } + } +} + +impl PartialEq for Code { + #[inline] + fn eq(&self, rhs: &Physical) -> bool { + rhs == self + } +} + +impl PartialEq for Physical { + #[inline] + fn eq(&self, rhs: &NativeCode) -> bool { + match self { + Physical::Unidentified(ref code) => code == rhs, + Physical::Code(_) => false, + } + } +} + +impl PartialEq for NativeCode { + #[inline] + fn eq(&self, rhs: &Physical) -> bool { + rhs == self + } +} diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index aaaca1a98a..0f336cc7df 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -223,9 +223,13 @@ pub fn window_event( }.filter(|text| !text.as_str().chars().any(is_private_use)); let winit::event::KeyEvent { - state, location, .. + state, + location, + physical_key, + .. } = event; let key = key(logical_key); + let physical_key = self::physical_key(physical_key); let modifiers = self::modifiers(modifiers); let location = match location { @@ -245,6 +249,7 @@ pub fn window_event( winit::event::ElementState::Pressed => { keyboard::Event::KeyPressed { key, + physical_key, modifiers, location, text, @@ -510,7 +515,7 @@ pub fn touch_event( } } -/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced`] key code. +/// Converts a `Key` from [`winit`] to an [`iced`] key. /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 @@ -839,6 +844,257 @@ pub fn key(key: winit::keyboard::Key) -> keyboard::Key { } } +/// Converts a `PhysicalKey` from [`winit`] to an [`iced`] physical key. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn physical_key( + physical_key: winit::keyboard::PhysicalKey, +) -> keyboard::key::Physical { + match physical_key { + winit::keyboard::PhysicalKey::Code(code) => key_code(code) + .map(keyboard::key::Physical::Code) + .unwrap_or(keyboard::key::Physical::Unidentified( + keyboard::key::NativeCode::Unidentified, + )), + winit::keyboard::PhysicalKey::Unidentified(code) => { + keyboard::key::Physical::Unidentified(native_key_code(code)) + } + } +} + +/// Converts a `KeyCode` from [`winit`] to an [`iced`] key code. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn key_code( + key_code: winit::keyboard::KeyCode, +) -> Option { + use winit::keyboard::KeyCode; + + Some(match key_code { + KeyCode::Backquote => keyboard::key::Code::Backquote, + KeyCode::Backslash => keyboard::key::Code::Backslash, + KeyCode::BracketLeft => keyboard::key::Code::BracketLeft, + KeyCode::BracketRight => keyboard::key::Code::BracketRight, + KeyCode::Comma => keyboard::key::Code::Comma, + KeyCode::Digit0 => keyboard::key::Code::Digit0, + KeyCode::Digit1 => keyboard::key::Code::Digit1, + KeyCode::Digit2 => keyboard::key::Code::Digit2, + KeyCode::Digit3 => keyboard::key::Code::Digit3, + KeyCode::Digit4 => keyboard::key::Code::Digit4, + KeyCode::Digit5 => keyboard::key::Code::Digit5, + KeyCode::Digit6 => keyboard::key::Code::Digit6, + KeyCode::Digit7 => keyboard::key::Code::Digit7, + KeyCode::Digit8 => keyboard::key::Code::Digit8, + KeyCode::Digit9 => keyboard::key::Code::Digit9, + KeyCode::Equal => keyboard::key::Code::Equal, + KeyCode::IntlBackslash => keyboard::key::Code::IntlBackslash, + KeyCode::IntlRo => keyboard::key::Code::IntlRo, + KeyCode::IntlYen => keyboard::key::Code::IntlYen, + KeyCode::KeyA => keyboard::key::Code::KeyA, + KeyCode::KeyB => keyboard::key::Code::KeyB, + KeyCode::KeyC => keyboard::key::Code::KeyC, + KeyCode::KeyD => keyboard::key::Code::KeyD, + KeyCode::KeyE => keyboard::key::Code::KeyE, + KeyCode::KeyF => keyboard::key::Code::KeyF, + KeyCode::KeyG => keyboard::key::Code::KeyG, + KeyCode::KeyH => keyboard::key::Code::KeyH, + KeyCode::KeyI => keyboard::key::Code::KeyI, + KeyCode::KeyJ => keyboard::key::Code::KeyJ, + KeyCode::KeyK => keyboard::key::Code::KeyK, + KeyCode::KeyL => keyboard::key::Code::KeyL, + KeyCode::KeyM => keyboard::key::Code::KeyM, + KeyCode::KeyN => keyboard::key::Code::KeyN, + KeyCode::KeyO => keyboard::key::Code::KeyO, + KeyCode::KeyP => keyboard::key::Code::KeyP, + KeyCode::KeyQ => keyboard::key::Code::KeyQ, + KeyCode::KeyR => keyboard::key::Code::KeyR, + KeyCode::KeyS => keyboard::key::Code::KeyS, + KeyCode::KeyT => keyboard::key::Code::KeyT, + KeyCode::KeyU => keyboard::key::Code::KeyU, + KeyCode::KeyV => keyboard::key::Code::KeyV, + KeyCode::KeyW => keyboard::key::Code::KeyW, + KeyCode::KeyX => keyboard::key::Code::KeyX, + KeyCode::KeyY => keyboard::key::Code::KeyY, + KeyCode::KeyZ => keyboard::key::Code::KeyZ, + KeyCode::Minus => keyboard::key::Code::Minus, + KeyCode::Period => keyboard::key::Code::Period, + KeyCode::Quote => keyboard::key::Code::Quote, + KeyCode::Semicolon => keyboard::key::Code::Semicolon, + KeyCode::Slash => keyboard::key::Code::Slash, + KeyCode::AltLeft => keyboard::key::Code::AltLeft, + KeyCode::AltRight => keyboard::key::Code::AltRight, + KeyCode::Backspace => keyboard::key::Code::Backspace, + KeyCode::CapsLock => keyboard::key::Code::CapsLock, + KeyCode::ContextMenu => keyboard::key::Code::ContextMenu, + KeyCode::ControlLeft => keyboard::key::Code::ControlLeft, + KeyCode::ControlRight => keyboard::key::Code::ControlRight, + KeyCode::Enter => keyboard::key::Code::Enter, + KeyCode::SuperLeft => keyboard::key::Code::SuperLeft, + KeyCode::SuperRight => keyboard::key::Code::SuperRight, + KeyCode::ShiftLeft => keyboard::key::Code::ShiftLeft, + KeyCode::ShiftRight => keyboard::key::Code::ShiftRight, + KeyCode::Space => keyboard::key::Code::Space, + KeyCode::Tab => keyboard::key::Code::Tab, + KeyCode::Convert => keyboard::key::Code::Convert, + KeyCode::KanaMode => keyboard::key::Code::KanaMode, + KeyCode::Lang1 => keyboard::key::Code::Lang1, + KeyCode::Lang2 => keyboard::key::Code::Lang2, + KeyCode::Lang3 => keyboard::key::Code::Lang3, + KeyCode::Lang4 => keyboard::key::Code::Lang4, + KeyCode::Lang5 => keyboard::key::Code::Lang5, + KeyCode::NonConvert => keyboard::key::Code::NonConvert, + KeyCode::Delete => keyboard::key::Code::Delete, + KeyCode::End => keyboard::key::Code::End, + KeyCode::Help => keyboard::key::Code::Help, + KeyCode::Home => keyboard::key::Code::Home, + KeyCode::Insert => keyboard::key::Code::Insert, + KeyCode::PageDown => keyboard::key::Code::PageDown, + KeyCode::PageUp => keyboard::key::Code::PageUp, + KeyCode::ArrowDown => keyboard::key::Code::ArrowDown, + KeyCode::ArrowLeft => keyboard::key::Code::ArrowLeft, + KeyCode::ArrowRight => keyboard::key::Code::ArrowRight, + KeyCode::ArrowUp => keyboard::key::Code::ArrowUp, + KeyCode::NumLock => keyboard::key::Code::NumLock, + KeyCode::Numpad0 => keyboard::key::Code::Numpad0, + KeyCode::Numpad1 => keyboard::key::Code::Numpad1, + KeyCode::Numpad2 => keyboard::key::Code::Numpad2, + KeyCode::Numpad3 => keyboard::key::Code::Numpad3, + KeyCode::Numpad4 => keyboard::key::Code::Numpad4, + KeyCode::Numpad5 => keyboard::key::Code::Numpad5, + KeyCode::Numpad6 => keyboard::key::Code::Numpad6, + KeyCode::Numpad7 => keyboard::key::Code::Numpad7, + KeyCode::Numpad8 => keyboard::key::Code::Numpad8, + KeyCode::Numpad9 => keyboard::key::Code::Numpad9, + KeyCode::NumpadAdd => keyboard::key::Code::NumpadAdd, + KeyCode::NumpadBackspace => keyboard::key::Code::NumpadBackspace, + KeyCode::NumpadClear => keyboard::key::Code::NumpadClear, + KeyCode::NumpadClearEntry => keyboard::key::Code::NumpadClearEntry, + KeyCode::NumpadComma => keyboard::key::Code::NumpadComma, + KeyCode::NumpadDecimal => keyboard::key::Code::NumpadDecimal, + KeyCode::NumpadDivide => keyboard::key::Code::NumpadDivide, + KeyCode::NumpadEnter => keyboard::key::Code::NumpadEnter, + KeyCode::NumpadEqual => keyboard::key::Code::NumpadEqual, + KeyCode::NumpadHash => keyboard::key::Code::NumpadHash, + KeyCode::NumpadMemoryAdd => keyboard::key::Code::NumpadMemoryAdd, + KeyCode::NumpadMemoryClear => keyboard::key::Code::NumpadMemoryClear, + KeyCode::NumpadMemoryRecall => keyboard::key::Code::NumpadMemoryRecall, + KeyCode::NumpadMemoryStore => keyboard::key::Code::NumpadMemoryStore, + KeyCode::NumpadMemorySubtract => { + keyboard::key::Code::NumpadMemorySubtract + } + KeyCode::NumpadMultiply => keyboard::key::Code::NumpadMultiply, + KeyCode::NumpadParenLeft => keyboard::key::Code::NumpadParenLeft, + KeyCode::NumpadParenRight => keyboard::key::Code::NumpadParenRight, + KeyCode::NumpadStar => keyboard::key::Code::NumpadStar, + KeyCode::NumpadSubtract => keyboard::key::Code::NumpadSubtract, + KeyCode::Escape => keyboard::key::Code::Escape, + KeyCode::Fn => keyboard::key::Code::Fn, + KeyCode::FnLock => keyboard::key::Code::FnLock, + KeyCode::PrintScreen => keyboard::key::Code::PrintScreen, + KeyCode::ScrollLock => keyboard::key::Code::ScrollLock, + KeyCode::Pause => keyboard::key::Code::Pause, + KeyCode::BrowserBack => keyboard::key::Code::BrowserBack, + KeyCode::BrowserFavorites => keyboard::key::Code::BrowserFavorites, + KeyCode::BrowserForward => keyboard::key::Code::BrowserForward, + KeyCode::BrowserHome => keyboard::key::Code::BrowserHome, + KeyCode::BrowserRefresh => keyboard::key::Code::BrowserRefresh, + KeyCode::BrowserSearch => keyboard::key::Code::BrowserSearch, + KeyCode::BrowserStop => keyboard::key::Code::BrowserStop, + KeyCode::Eject => keyboard::key::Code::Eject, + KeyCode::LaunchApp1 => keyboard::key::Code::LaunchApp1, + KeyCode::LaunchApp2 => keyboard::key::Code::LaunchApp2, + KeyCode::LaunchMail => keyboard::key::Code::LaunchMail, + KeyCode::MediaPlayPause => keyboard::key::Code::MediaPlayPause, + KeyCode::MediaSelect => keyboard::key::Code::MediaSelect, + KeyCode::MediaStop => keyboard::key::Code::MediaStop, + KeyCode::MediaTrackNext => keyboard::key::Code::MediaTrackNext, + KeyCode::MediaTrackPrevious => keyboard::key::Code::MediaTrackPrevious, + KeyCode::Power => keyboard::key::Code::Power, + KeyCode::Sleep => keyboard::key::Code::Sleep, + KeyCode::AudioVolumeDown => keyboard::key::Code::AudioVolumeDown, + KeyCode::AudioVolumeMute => keyboard::key::Code::AudioVolumeMute, + KeyCode::AudioVolumeUp => keyboard::key::Code::AudioVolumeUp, + KeyCode::WakeUp => keyboard::key::Code::WakeUp, + KeyCode::Meta => keyboard::key::Code::Meta, + KeyCode::Hyper => keyboard::key::Code::Hyper, + KeyCode::Turbo => keyboard::key::Code::Turbo, + KeyCode::Abort => keyboard::key::Code::Abort, + KeyCode::Resume => keyboard::key::Code::Resume, + KeyCode::Suspend => keyboard::key::Code::Suspend, + KeyCode::Again => keyboard::key::Code::Again, + KeyCode::Copy => keyboard::key::Code::Copy, + KeyCode::Cut => keyboard::key::Code::Cut, + KeyCode::Find => keyboard::key::Code::Find, + KeyCode::Open => keyboard::key::Code::Open, + KeyCode::Paste => keyboard::key::Code::Paste, + KeyCode::Props => keyboard::key::Code::Props, + KeyCode::Select => keyboard::key::Code::Select, + KeyCode::Undo => keyboard::key::Code::Undo, + KeyCode::Hiragana => keyboard::key::Code::Hiragana, + KeyCode::Katakana => keyboard::key::Code::Katakana, + KeyCode::F1 => keyboard::key::Code::F1, + KeyCode::F2 => keyboard::key::Code::F2, + KeyCode::F3 => keyboard::key::Code::F3, + KeyCode::F4 => keyboard::key::Code::F4, + KeyCode::F5 => keyboard::key::Code::F5, + KeyCode::F6 => keyboard::key::Code::F6, + KeyCode::F7 => keyboard::key::Code::F7, + KeyCode::F8 => keyboard::key::Code::F8, + KeyCode::F9 => keyboard::key::Code::F9, + KeyCode::F10 => keyboard::key::Code::F10, + KeyCode::F11 => keyboard::key::Code::F11, + KeyCode::F12 => keyboard::key::Code::F12, + KeyCode::F13 => keyboard::key::Code::F13, + KeyCode::F14 => keyboard::key::Code::F14, + KeyCode::F15 => keyboard::key::Code::F15, + KeyCode::F16 => keyboard::key::Code::F16, + KeyCode::F17 => keyboard::key::Code::F17, + KeyCode::F18 => keyboard::key::Code::F18, + KeyCode::F19 => keyboard::key::Code::F19, + KeyCode::F20 => keyboard::key::Code::F20, + KeyCode::F21 => keyboard::key::Code::F21, + KeyCode::F22 => keyboard::key::Code::F22, + KeyCode::F23 => keyboard::key::Code::F23, + KeyCode::F24 => keyboard::key::Code::F24, + KeyCode::F25 => keyboard::key::Code::F25, + KeyCode::F26 => keyboard::key::Code::F26, + KeyCode::F27 => keyboard::key::Code::F27, + KeyCode::F28 => keyboard::key::Code::F28, + KeyCode::F29 => keyboard::key::Code::F29, + KeyCode::F30 => keyboard::key::Code::F30, + KeyCode::F31 => keyboard::key::Code::F31, + KeyCode::F32 => keyboard::key::Code::F32, + KeyCode::F33 => keyboard::key::Code::F33, + KeyCode::F34 => keyboard::key::Code::F34, + KeyCode::F35 => keyboard::key::Code::F35, + _ => None?, + }) +} + +/// Converts a `NativeKeyCode` from [`winit`] to an [`iced`] native key code. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn native_key_code( + native_key_code: winit::keyboard::NativeKeyCode, +) -> keyboard::key::NativeCode { + use winit::keyboard::NativeKeyCode; + + match native_key_code { + NativeKeyCode::Unidentified => keyboard::key::NativeCode::Unidentified, + NativeKeyCode::Android(code) => { + keyboard::key::NativeCode::Android(code) + } + NativeKeyCode::MacOS(code) => keyboard::key::NativeCode::MacOS(code), + NativeKeyCode::Windows(code) => { + keyboard::key::NativeCode::Windows(code) + } + NativeKeyCode::Xkb(code) => keyboard::key::NativeCode::Xkb(code), + } +} + /// Converts some [`UserAttention`] into it's `winit` counterpart. /// /// [`UserAttention`]: window::UserAttention From 94c8b9639ca2d287c504345390585b80dc0d78cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 13 Sep 2024 03:07:52 +0200 Subject: [PATCH 2/3] Add `modified_key` to `keyboard::Event` --- core/src/keyboard/event.rs | 3 +++ winit/src/conversion.rs | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/keyboard/event.rs b/core/src/keyboard/event.rs index 09625b1836..26c457170a 100644 --- a/core/src/keyboard/event.rs +++ b/core/src/keyboard/event.rs @@ -15,6 +15,9 @@ pub enum Event { /// The key pressed. key: Key, + /// The key pressed with all keyboard modifiers applied, except Ctrl. + modified_key: Key, + /// The physical key pressed. physical_key: key::Physical, diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 0f336cc7df..13b0f15bbf 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -192,7 +192,7 @@ pub fn window_event( } }, WindowEvent::KeyboardInput { event, .. } => Some(Event::Keyboard({ - let logical_key = { + let key = { #[cfg(not(target_arch = "wasm32"))] { use winit::platform::modifier_supplement::KeyEventExtModifierSupplement; @@ -202,7 +202,7 @@ pub fn window_event( #[cfg(target_arch = "wasm32")] { // TODO: Fix inconsistent API on Wasm - event.logical_key + event.logical_key.clone() } }; @@ -225,10 +225,13 @@ pub fn window_event( let winit::event::KeyEvent { state, location, + logical_key, physical_key, .. } = event; - let key = key(logical_key); + + let key = self::key(key); + let modified_key = self::key(logical_key); let physical_key = self::physical_key(physical_key); let modifiers = self::modifiers(modifiers); @@ -249,6 +252,7 @@ pub fn window_event( winit::event::ElementState::Pressed => { keyboard::Event::KeyPressed { key, + modified_key, physical_key, modifiers, location, From 4e9428bc5ad99c521858aae61cb6acc6d2c8bf52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 13 Sep 2024 03:18:17 +0200 Subject: [PATCH 3/3] Fix broken doc links in `keyboard::key` --- core/src/keyboard/key.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/keyboard/key.rs b/core/src/keyboard/key.rs index 219452d788..479d999bc9 100644 --- a/core/src/keyboard/key.rs +++ b/core/src/keyboard/key.rs @@ -1201,14 +1201,14 @@ pub enum Code { F35, } -/// Contains the platform-native physical key identifier +/// 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: +/// physical key identifier to a meaningful [`Code`] variant. In the presence of identifiers we +/// haven't mapped for you yet, this lets you use use [`Code`] to: /// /// - Correctly match key press and release events. /// - On non-web platforms, support assigning keybinds to virtually any key through a UI. @@ -1228,16 +1228,16 @@ pub enum NativeCode { /// Represents the location of a physical key. /// -/// This type is a superset of [`KeyCode`], including an [`Unidentified`][Self::Unidentified] +/// This type is a superset of [`Code`], including an [`Unidentified`][Self::Unidentified] /// variant. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Physical { /// A known key code Code(Code), - /// This variant is used when the key cannot be translated to a [`KeyCode`] + /// This variant is used when the key cannot be translated to a [`Code`] /// /// The native keycode is provided (if available) so you're able to more reliably match - /// key-press and key-release events by hashing the [`PhysicalKey`]. It is also possible to use + /// key-press and key-release events by hashing the [`Physical`] key. It is also possible to use /// this for keybinds for non-standard keys, but such keybinds are tied to a given platform. Unidentified(NativeCode), }