Use keyboard-types types directly instead of druid wrappers
This commit is contained in:
parent
86b2aff624
commit
546b0d6eae
|
@ -1,9 +1,9 @@
|
||||||
use crate::{WindowInfo, Point, KeyEvent};
|
use crate::{WindowInfo, Point};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum KeyboardEvent {
|
pub enum KeyboardEvent {
|
||||||
KeyPressed(KeyEvent),
|
KeyPressed(keyboard_types::KeyboardEvent),
|
||||||
KeyReleased(KeyEvent),
|
KeyReleased(keyboard_types::KeyboardEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
209
src/keyboard.rs
209
src/keyboard.rs
|
@ -13,216 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// Baseview modifications to druid code:
|
// Baseview modifications to druid code:
|
||||||
// - move code_to_location function to this file
|
// - only keep code_to_location function
|
||||||
|
|
||||||
//! Keyboard types.
|
//! Keyboard types.
|
||||||
|
|
||||||
// This is a reasonable lint, but we keep signatures in sync with the
|
use keyboard_types::{Code, Location};
|
||||||
// bitflags implementation of the inner Modifiers type.
|
|
||||||
#![allow(clippy::trivially_copy_pass_by_ref)]
|
|
||||||
|
|
||||||
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
|
|
||||||
|
|
||||||
pub use keyboard_types::{Code, KeyState, Location};
|
|
||||||
|
|
||||||
/// The meaning (mapped value) of a keypress.
|
|
||||||
pub type KbKey = keyboard_types::Key;
|
|
||||||
|
|
||||||
/// Information about a keyboard event.
|
|
||||||
///
|
|
||||||
/// Note that this type is similar to [`KeyboardEvent`] in keyboard-types,
|
|
||||||
/// but has a few small differences for convenience. It is missing the `state`
|
|
||||||
/// field because that is already implicit in the event.
|
|
||||||
///
|
|
||||||
/// [`KeyboardEvent`]: keyboard_types::KeyboardEvent
|
|
||||||
#[non_exhaustive]
|
|
||||||
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
|
|
||||||
pub struct KeyEvent {
|
|
||||||
/// Whether the key is pressed or released.
|
|
||||||
pub state: KeyState,
|
|
||||||
/// Logical key value.
|
|
||||||
pub key: KbKey,
|
|
||||||
/// Physical key position.
|
|
||||||
pub code: Code,
|
|
||||||
/// Location for keys with multiple instances on common keyboards.
|
|
||||||
pub location: Location,
|
|
||||||
/// Flags for pressed modifier keys.
|
|
||||||
pub mods: Modifiers,
|
|
||||||
/// True if the key is currently auto-repeated.
|
|
||||||
pub repeat: bool,
|
|
||||||
/// Events with this flag should be ignored in a text editor
|
|
||||||
/// and instead composition events should be used.
|
|
||||||
pub is_composing: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The modifiers.
|
|
||||||
///
|
|
||||||
/// This type is a thin wrappers around [`keyboard_types::Modifiers`],
|
|
||||||
/// mostly for the convenience methods. If those get upstreamed, it
|
|
||||||
/// will simply become that type.
|
|
||||||
///
|
|
||||||
/// [`keyboard_types::Modifiers`]: keyboard_types::Modifiers
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
|
|
||||||
pub struct Modifiers(keyboard_types::Modifiers);
|
|
||||||
|
|
||||||
/// A convenience trait for creating Key objects.
|
|
||||||
///
|
|
||||||
/// This trait is implemented by [`KbKey`] itself and also strings, which are
|
|
||||||
/// converted into the `Character` variant. It is defined this way and not
|
|
||||||
/// using the standard `Into` mechanism because `KbKey` is a type in an external
|
|
||||||
/// crate.
|
|
||||||
///
|
|
||||||
/// [`KbKey`]: KbKey
|
|
||||||
pub trait IntoKey {
|
|
||||||
fn into_key(self) -> KbKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KeyEvent {
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Create a key event for testing purposes.
|
|
||||||
pub fn for_test(mods: impl Into<Modifiers>, key: impl IntoKey) -> KeyEvent {
|
|
||||||
let mods = mods.into();
|
|
||||||
let key = key.into_key();
|
|
||||||
KeyEvent {
|
|
||||||
key,
|
|
||||||
code: Code::Unidentified,
|
|
||||||
location: Location::Standard,
|
|
||||||
state: KeyState::Down,
|
|
||||||
mods,
|
|
||||||
is_composing: false,
|
|
||||||
repeat: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Modifiers {
|
|
||||||
pub const ALT: Modifiers = Modifiers(keyboard_types::Modifiers::ALT);
|
|
||||||
pub const ALT_GRAPH: Modifiers = Modifiers(keyboard_types::Modifiers::ALT_GRAPH);
|
|
||||||
pub const CAPS_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::CAPS_LOCK);
|
|
||||||
pub const CONTROL: Modifiers = Modifiers(keyboard_types::Modifiers::CONTROL);
|
|
||||||
pub const FN: Modifiers = Modifiers(keyboard_types::Modifiers::FN);
|
|
||||||
pub const FN_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::FN_LOCK);
|
|
||||||
pub const META: Modifiers = Modifiers(keyboard_types::Modifiers::META);
|
|
||||||
pub const NUM_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::NUM_LOCK);
|
|
||||||
pub const SCROLL_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::SCROLL_LOCK);
|
|
||||||
pub const SHIFT: Modifiers = Modifiers(keyboard_types::Modifiers::SHIFT);
|
|
||||||
pub const SYMBOL: Modifiers = Modifiers(keyboard_types::Modifiers::SYMBOL);
|
|
||||||
pub const SYMBOL_LOCK: Modifiers = Modifiers(keyboard_types::Modifiers::SYMBOL_LOCK);
|
|
||||||
pub const HYPER: Modifiers = Modifiers(keyboard_types::Modifiers::HYPER);
|
|
||||||
pub const SUPER: Modifiers = Modifiers(keyboard_types::Modifiers::SUPER);
|
|
||||||
|
|
||||||
/// Get the inner value.
|
|
||||||
///
|
|
||||||
/// Note that this function might go away if our changes are upstreamed.
|
|
||||||
pub fn raw(&self) -> keyboard_types::Modifiers {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine whether Shift is set.
|
|
||||||
pub fn shift(&self) -> bool {
|
|
||||||
self.contains(Modifiers::SHIFT)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine whether Ctrl is set.
|
|
||||||
pub fn ctrl(&self) -> bool {
|
|
||||||
self.contains(Modifiers::CONTROL)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine whether Alt is set.
|
|
||||||
pub fn alt(&self) -> bool {
|
|
||||||
self.contains(Modifiers::ALT)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine whether Meta is set.
|
|
||||||
pub fn meta(&self) -> bool {
|
|
||||||
self.contains(Modifiers::META)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an empty set of modifiers.
|
|
||||||
pub fn empty() -> Modifiers {
|
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if no modifiers are set.
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if all the modifiers in `other` are set.
|
|
||||||
pub fn contains(&self, other: Modifiers) -> bool {
|
|
||||||
self.0.contains(other.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inserts or removes the specified modifiers depending on the passed value.
|
|
||||||
pub fn set(&mut self, other: Modifiers, value: bool) {
|
|
||||||
self.0.set(other.0, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitAnd for Modifiers {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn bitand(self, rhs: Self) -> Self {
|
|
||||||
Modifiers(self.0 & rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitAndAssign for Modifiers {
|
|
||||||
// rhs is the "right-hand side" of the expression `a &= b`
|
|
||||||
fn bitand_assign(&mut self, rhs: Self) {
|
|
||||||
*self = Modifiers(self.0 & rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitOr for Modifiers {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn bitor(self, rhs: Self) -> Self {
|
|
||||||
Modifiers(self.0 | rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitOrAssign for Modifiers {
|
|
||||||
// rhs is the "right-hand side" of the expression `a &= b`
|
|
||||||
fn bitor_assign(&mut self, rhs: Self) {
|
|
||||||
*self = Modifiers(self.0 | rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitXor for Modifiers {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn bitxor(self, rhs: Self) -> Self {
|
|
||||||
Modifiers(self.0 ^ rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitXorAssign for Modifiers {
|
|
||||||
// rhs is the "right-hand side" of the expression `a &= b`
|
|
||||||
fn bitxor_assign(&mut self, rhs: Self) {
|
|
||||||
*self = Modifiers(self.0 ^ rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Not for Modifiers {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn not(self) -> Self {
|
|
||||||
Modifiers(!self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoKey for KbKey {
|
|
||||||
fn into_key(self) -> KbKey {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoKey for &str {
|
|
||||||
fn into_key(self) -> KbKey {
|
|
||||||
KbKey::Character(self.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||||
|
|
|
@ -21,7 +21,6 @@ mod mouse_cursor;
|
||||||
mod window_info;
|
mod window_info;
|
||||||
mod window_open_options;
|
mod window_open_options;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use keyboard::KeyEvent;
|
|
||||||
pub use mouse_cursor::MouseCursor;
|
pub use mouse_cursor::MouseCursor;
|
||||||
pub use window_info::*;
|
pub use window_info::*;
|
||||||
pub use window_open_options::*;
|
pub use window_open_options::*;
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
|
use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
|
||||||
use cocoa::foundation::NSString;
|
use cocoa::foundation::NSString;
|
||||||
use cocoa::base::id;
|
use cocoa::base::id;
|
||||||
use keyboard_types::{Code, KeyState};
|
use keyboard_types::{Code, KeyState, Key, KeyboardEvent, Modifiers};
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
|
|
||||||
use crate::keyboard::{code_to_location, KbKey, KeyEvent, Modifiers};
|
use crate::keyboard::code_to_location;
|
||||||
|
|
||||||
|
|
||||||
pub(crate) fn from_nsstring(s: id) -> String {
|
pub(crate) fn from_nsstring(s: id) -> String {
|
||||||
|
@ -195,52 +195,52 @@ fn key_code_to_code(key_code: u16) -> Code {
|
||||||
///
|
///
|
||||||
/// The logic for this function is derived from KEY_MAP_COCOA bindings in
|
/// The logic for this function is derived from KEY_MAP_COCOA bindings in
|
||||||
/// NativeKeyToDOMKeyName.h.
|
/// NativeKeyToDOMKeyName.h.
|
||||||
fn code_to_key(code: Code) -> Option<KbKey> {
|
fn code_to_key(code: Code) -> Option<Key> {
|
||||||
Some(match code {
|
Some(match code {
|
||||||
Code::Escape => KbKey::Escape,
|
Code::Escape => Key::Escape,
|
||||||
Code::ShiftLeft | Code::ShiftRight => KbKey::Shift,
|
Code::ShiftLeft | Code::ShiftRight => Key::Shift,
|
||||||
Code::AltLeft | Code::AltRight => KbKey::Alt,
|
Code::AltLeft | Code::AltRight => Key::Alt,
|
||||||
Code::MetaLeft | Code::MetaRight => KbKey::Meta,
|
Code::MetaLeft | Code::MetaRight => Key::Meta,
|
||||||
Code::ControlLeft | Code::ControlRight => KbKey::Control,
|
Code::ControlLeft | Code::ControlRight => Key::Control,
|
||||||
Code::CapsLock => KbKey::CapsLock,
|
Code::CapsLock => Key::CapsLock,
|
||||||
// kVK_ANSI_KeypadClear
|
// kVK_ANSI_KeypadClear
|
||||||
Code::NumLock => KbKey::Clear,
|
Code::NumLock => Key::Clear,
|
||||||
Code::Fn => KbKey::Fn,
|
Code::Fn => Key::Fn,
|
||||||
Code::F1 => KbKey::F1,
|
Code::F1 => Key::F1,
|
||||||
Code::F2 => KbKey::F2,
|
Code::F2 => Key::F2,
|
||||||
Code::F3 => KbKey::F3,
|
Code::F3 => Key::F3,
|
||||||
Code::F4 => KbKey::F4,
|
Code::F4 => Key::F4,
|
||||||
Code::F5 => KbKey::F5,
|
Code::F5 => Key::F5,
|
||||||
Code::F6 => KbKey::F6,
|
Code::F6 => Key::F6,
|
||||||
Code::F7 => KbKey::F7,
|
Code::F7 => Key::F7,
|
||||||
Code::F8 => KbKey::F8,
|
Code::F8 => Key::F8,
|
||||||
Code::F9 => KbKey::F9,
|
Code::F9 => Key::F9,
|
||||||
Code::F10 => KbKey::F10,
|
Code::F10 => Key::F10,
|
||||||
Code::F11 => KbKey::F11,
|
Code::F11 => Key::F11,
|
||||||
Code::F12 => KbKey::F12,
|
Code::F12 => Key::F12,
|
||||||
Code::Pause => KbKey::Pause,
|
Code::Pause => Key::Pause,
|
||||||
Code::ScrollLock => KbKey::ScrollLock,
|
Code::ScrollLock => Key::ScrollLock,
|
||||||
Code::PrintScreen => KbKey::PrintScreen,
|
Code::PrintScreen => Key::PrintScreen,
|
||||||
Code::Insert => KbKey::Insert,
|
Code::Insert => Key::Insert,
|
||||||
Code::Delete => KbKey::Delete,
|
Code::Delete => Key::Delete,
|
||||||
Code::Tab => KbKey::Tab,
|
Code::Tab => Key::Tab,
|
||||||
Code::Backspace => KbKey::Backspace,
|
Code::Backspace => Key::Backspace,
|
||||||
Code::ContextMenu => KbKey::ContextMenu,
|
Code::ContextMenu => Key::ContextMenu,
|
||||||
// kVK_JIS_Kana
|
// kVK_JIS_Kana
|
||||||
Code::Lang1 => KbKey::KanjiMode,
|
Code::Lang1 => Key::KanjiMode,
|
||||||
// kVK_JIS_Eisu
|
// kVK_JIS_Eisu
|
||||||
Code::Lang2 => KbKey::Eisu,
|
Code::Lang2 => Key::Eisu,
|
||||||
Code::Home => KbKey::Home,
|
Code::Home => Key::Home,
|
||||||
Code::End => KbKey::End,
|
Code::End => Key::End,
|
||||||
Code::PageUp => KbKey::PageUp,
|
Code::PageUp => Key::PageUp,
|
||||||
Code::PageDown => KbKey::PageDown,
|
Code::PageDown => Key::PageDown,
|
||||||
Code::ArrowLeft => KbKey::ArrowLeft,
|
Code::ArrowLeft => Key::ArrowLeft,
|
||||||
Code::ArrowRight => KbKey::ArrowRight,
|
Code::ArrowRight => Key::ArrowRight,
|
||||||
Code::ArrowUp => KbKey::ArrowUp,
|
Code::ArrowUp => Key::ArrowUp,
|
||||||
Code::ArrowDown => KbKey::ArrowDown,
|
Code::ArrowDown => Key::ArrowDown,
|
||||||
Code::Enter => KbKey::Enter,
|
Code::Enter => Key::Enter,
|
||||||
Code::NumpadEnter => KbKey::Enter,
|
Code::NumpadEnter => Key::Enter,
|
||||||
Code::Help => KbKey::Help,
|
Code::Help => Key::Help,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -277,14 +277,14 @@ impl KeyboardState {
|
||||||
KeyboardState { last_mods }
|
KeyboardState { last_mods }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn process_native_event(&mut self, event: id) -> Option<KeyEvent> {
|
pub(crate) fn process_native_event(&mut self, event: id) -> Option<KeyboardEvent> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let event_type = event.eventType();
|
let event_type = event.eventType();
|
||||||
let key_code = event.keyCode();
|
let key_code = event.keyCode();
|
||||||
let code = key_code_to_code(key_code);
|
let code = key_code_to_code(key_code);
|
||||||
let location = code_to_location(code);
|
let location = code_to_location(code);
|
||||||
let raw_mods = event.modifierFlags();
|
let raw_mods = event.modifierFlags();
|
||||||
let mods = make_modifiers(raw_mods);
|
let modifiers = make_modifiers(raw_mods);
|
||||||
let state = match event_type {
|
let state = match event_type {
|
||||||
NSEventType::NSKeyDown => KeyState::Down,
|
NSEventType::NSKeyDown => KeyState::Down,
|
||||||
NSEventType::NSKeyUp => KeyState::Up,
|
NSEventType::NSKeyUp => KeyState::Up,
|
||||||
|
@ -318,22 +318,22 @@ impl KeyboardState {
|
||||||
} else {
|
} else {
|
||||||
let characters = from_nsstring(event.characters());
|
let characters = from_nsstring(event.characters());
|
||||||
if is_valid_key(&characters) {
|
if is_valid_key(&characters) {
|
||||||
KbKey::Character(characters)
|
Key::Character(characters)
|
||||||
} else {
|
} else {
|
||||||
let chars_ignoring = from_nsstring(event.charactersIgnoringModifiers());
|
let chars_ignoring = from_nsstring(event.charactersIgnoringModifiers());
|
||||||
if is_valid_key(&chars_ignoring) {
|
if is_valid_key(&chars_ignoring) {
|
||||||
KbKey::Character(chars_ignoring)
|
Key::Character(chars_ignoring)
|
||||||
} else {
|
} else {
|
||||||
// There may be more heroic things we can do here.
|
// There may be more heroic things we can do here.
|
||||||
KbKey::Unidentified
|
Key::Unidentified
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let event = KeyEvent {
|
let event = KeyboardEvent {
|
||||||
code,
|
code,
|
||||||
key,
|
key,
|
||||||
location,
|
location,
|
||||||
mods,
|
modifiers,
|
||||||
state,
|
state,
|
||||||
is_composing,
|
is_composing,
|
||||||
repeat,
|
repeat,
|
||||||
|
|
|
@ -11,13 +11,14 @@ use cocoa::appkit::{
|
||||||
};
|
};
|
||||||
use cocoa::base::{id, nil, NO};
|
use cocoa::base::{id, nil, NO};
|
||||||
use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
|
use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
|
||||||
|
use keyboard_types::KeyboardEvent;
|
||||||
|
|
||||||
use objc::{msg_send, runtime::Object, sel, sel_impl};
|
use objc::{msg_send, runtime::Object, sel, sel_impl};
|
||||||
|
|
||||||
use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle};
|
use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Event, keyboard::KeyEvent, Parent, WindowHandler, WindowOpenOptions,
|
Event, Parent, WindowHandler, WindowOpenOptions,
|
||||||
WindowScalePolicy, WindowInfo
|
WindowScalePolicy, WindowInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,7 +203,7 @@ impl <H: WindowHandler>WindowState<H> {
|
||||||
pub(super) fn process_native_key_event(
|
pub(super) fn process_native_key_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: *mut Object
|
event: *mut Object
|
||||||
) -> Option<KeyEvent> {
|
) -> Option<KeyboardEvent> {
|
||||||
self.keyboard_state.process_native_event(event)
|
self.keyboard_state.process_native_event(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,27 +20,29 @@
|
||||||
|
|
||||||
use xcb::xproto;
|
use xcb::xproto;
|
||||||
|
|
||||||
use crate::keyboard::*;
|
use keyboard_types::*;
|
||||||
|
|
||||||
|
use crate::keyboard::code_to_location;
|
||||||
|
|
||||||
|
|
||||||
/// Convert a hardware scan code to a key.
|
/// Convert a hardware scan code to a key.
|
||||||
///
|
///
|
||||||
/// Note: this is a hardcoded layout. We need to detect the user's
|
/// Note: this is a hardcoded layout. We need to detect the user's
|
||||||
/// layout from the system and apply it.
|
/// layout from the system and apply it.
|
||||||
fn code_to_key(code: Code, m: Modifiers) -> KbKey {
|
fn code_to_key(code: Code, m: Modifiers) -> Key {
|
||||||
fn a(s: &str) -> KbKey {
|
fn a(s: &str) -> Key {
|
||||||
KbKey::Character(s.into())
|
Key::Character(s.into())
|
||||||
}
|
}
|
||||||
fn s(mods: Modifiers, base: &str, shifted: &str) -> KbKey {
|
fn s(mods: Modifiers, base: &str, shifted: &str) -> Key {
|
||||||
if mods.shift() {
|
if mods.contains(Modifiers::SHIFT) {
|
||||||
KbKey::Character(shifted.into())
|
Key::Character(shifted.into())
|
||||||
} else {
|
} else {
|
||||||
KbKey::Character(base.into())
|
Key::Character(base.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn n(mods: Modifiers, base: KbKey, num: &str) -> KbKey {
|
fn n(mods: Modifiers, base: Key, num: &str) -> Key {
|
||||||
if mods.contains(Modifiers::NUM_LOCK) != mods.shift() {
|
if mods.contains(Modifiers::NUM_LOCK) != mods.contains(Modifiers::SHIFT) {
|
||||||
KbKey::Character(num.into())
|
Key::Character(num.into())
|
||||||
} else {
|
} else {
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
|
@ -98,105 +100,105 @@ fn code_to_key(code: Code, m: Modifiers) -> KbKey {
|
||||||
|
|
||||||
Code::Space => a(" "),
|
Code::Space => a(" "),
|
||||||
|
|
||||||
Code::Escape => KbKey::Escape,
|
Code::Escape => Key::Escape,
|
||||||
Code::Backspace => KbKey::Backspace,
|
Code::Backspace => Key::Backspace,
|
||||||
Code::Tab => KbKey::Tab,
|
Code::Tab => Key::Tab,
|
||||||
Code::Enter => KbKey::Enter,
|
Code::Enter => Key::Enter,
|
||||||
Code::ControlLeft => KbKey::Control,
|
Code::ControlLeft => Key::Control,
|
||||||
Code::ShiftLeft => KbKey::Shift,
|
Code::ShiftLeft => Key::Shift,
|
||||||
Code::ShiftRight => KbKey::Shift,
|
Code::ShiftRight => Key::Shift,
|
||||||
Code::NumpadMultiply => a("*"),
|
Code::NumpadMultiply => a("*"),
|
||||||
Code::AltLeft => KbKey::Alt,
|
Code::AltLeft => Key::Alt,
|
||||||
Code::CapsLock => KbKey::CapsLock,
|
Code::CapsLock => Key::CapsLock,
|
||||||
Code::F1 => KbKey::F1,
|
Code::F1 => Key::F1,
|
||||||
Code::F2 => KbKey::F2,
|
Code::F2 => Key::F2,
|
||||||
Code::F3 => KbKey::F3,
|
Code::F3 => Key::F3,
|
||||||
Code::F4 => KbKey::F4,
|
Code::F4 => Key::F4,
|
||||||
Code::F5 => KbKey::F5,
|
Code::F5 => Key::F5,
|
||||||
Code::F6 => KbKey::F6,
|
Code::F6 => Key::F6,
|
||||||
Code::F7 => KbKey::F7,
|
Code::F7 => Key::F7,
|
||||||
Code::F8 => KbKey::F8,
|
Code::F8 => Key::F8,
|
||||||
Code::F9 => KbKey::F9,
|
Code::F9 => Key::F9,
|
||||||
Code::F10 => KbKey::F10,
|
Code::F10 => Key::F10,
|
||||||
Code::NumLock => KbKey::NumLock,
|
Code::NumLock => Key::NumLock,
|
||||||
Code::ScrollLock => KbKey::ScrollLock,
|
Code::ScrollLock => Key::ScrollLock,
|
||||||
Code::Numpad0 => n(m, KbKey::Insert, "0"),
|
Code::Numpad0 => n(m, Key::Insert, "0"),
|
||||||
Code::Numpad1 => n(m, KbKey::End, "1"),
|
Code::Numpad1 => n(m, Key::End, "1"),
|
||||||
Code::Numpad2 => n(m, KbKey::ArrowDown, "2"),
|
Code::Numpad2 => n(m, Key::ArrowDown, "2"),
|
||||||
Code::Numpad3 => n(m, KbKey::PageDown, "3"),
|
Code::Numpad3 => n(m, Key::PageDown, "3"),
|
||||||
Code::Numpad4 => n(m, KbKey::ArrowLeft, "4"),
|
Code::Numpad4 => n(m, Key::ArrowLeft, "4"),
|
||||||
Code::Numpad5 => n(m, KbKey::Clear, "5"),
|
Code::Numpad5 => n(m, Key::Clear, "5"),
|
||||||
Code::Numpad6 => n(m, KbKey::ArrowRight, "6"),
|
Code::Numpad6 => n(m, Key::ArrowRight, "6"),
|
||||||
Code::Numpad7 => n(m, KbKey::Home, "7"),
|
Code::Numpad7 => n(m, Key::Home, "7"),
|
||||||
Code::Numpad8 => n(m, KbKey::ArrowUp, "8"),
|
Code::Numpad8 => n(m, Key::ArrowUp, "8"),
|
||||||
Code::Numpad9 => n(m, KbKey::PageUp, "9"),
|
Code::Numpad9 => n(m, Key::PageUp, "9"),
|
||||||
Code::NumpadSubtract => a("-"),
|
Code::NumpadSubtract => a("-"),
|
||||||
Code::NumpadAdd => a("+"),
|
Code::NumpadAdd => a("+"),
|
||||||
Code::NumpadDecimal => n(m, KbKey::Delete, "."),
|
Code::NumpadDecimal => n(m, Key::Delete, "."),
|
||||||
Code::IntlBackslash => s(m, "\\", "|"),
|
Code::IntlBackslash => s(m, "\\", "|"),
|
||||||
Code::F11 => KbKey::F11,
|
Code::F11 => Key::F11,
|
||||||
Code::F12 => KbKey::F12,
|
Code::F12 => Key::F12,
|
||||||
// This mapping is based on the picture in the w3c spec.
|
// This mapping is based on the picture in the w3c spec.
|
||||||
Code::IntlRo => a("\\"),
|
Code::IntlRo => a("\\"),
|
||||||
Code::Convert => KbKey::Convert,
|
Code::Convert => Key::Convert,
|
||||||
Code::KanaMode => KbKey::KanaMode,
|
Code::KanaMode => Key::KanaMode,
|
||||||
Code::NonConvert => KbKey::NonConvert,
|
Code::NonConvert => Key::NonConvert,
|
||||||
Code::NumpadEnter => KbKey::Enter,
|
Code::NumpadEnter => Key::Enter,
|
||||||
Code::ControlRight => KbKey::Control,
|
Code::ControlRight => Key::Control,
|
||||||
Code::NumpadDivide => a("/"),
|
Code::NumpadDivide => a("/"),
|
||||||
Code::PrintScreen => KbKey::PrintScreen,
|
Code::PrintScreen => Key::PrintScreen,
|
||||||
Code::AltRight => KbKey::Alt,
|
Code::AltRight => Key::Alt,
|
||||||
Code::Home => KbKey::Home,
|
Code::Home => Key::Home,
|
||||||
Code::ArrowUp => KbKey::ArrowUp,
|
Code::ArrowUp => Key::ArrowUp,
|
||||||
Code::PageUp => KbKey::PageUp,
|
Code::PageUp => Key::PageUp,
|
||||||
Code::ArrowLeft => KbKey::ArrowLeft,
|
Code::ArrowLeft => Key::ArrowLeft,
|
||||||
Code::ArrowRight => KbKey::ArrowRight,
|
Code::ArrowRight => Key::ArrowRight,
|
||||||
Code::End => KbKey::End,
|
Code::End => Key::End,
|
||||||
Code::ArrowDown => KbKey::ArrowDown,
|
Code::ArrowDown => Key::ArrowDown,
|
||||||
Code::PageDown => KbKey::PageDown,
|
Code::PageDown => Key::PageDown,
|
||||||
Code::Insert => KbKey::Insert,
|
Code::Insert => Key::Insert,
|
||||||
Code::Delete => KbKey::Delete,
|
Code::Delete => Key::Delete,
|
||||||
Code::AudioVolumeMute => KbKey::AudioVolumeMute,
|
Code::AudioVolumeMute => Key::AudioVolumeMute,
|
||||||
Code::AudioVolumeDown => KbKey::AudioVolumeDown,
|
Code::AudioVolumeDown => Key::AudioVolumeDown,
|
||||||
Code::AudioVolumeUp => KbKey::AudioVolumeUp,
|
Code::AudioVolumeUp => Key::AudioVolumeUp,
|
||||||
Code::NumpadEqual => a("="),
|
Code::NumpadEqual => a("="),
|
||||||
Code::Pause => KbKey::Pause,
|
Code::Pause => Key::Pause,
|
||||||
Code::NumpadComma => a(","),
|
Code::NumpadComma => a(","),
|
||||||
Code::Lang1 => KbKey::HangulMode,
|
Code::Lang1 => Key::HangulMode,
|
||||||
Code::Lang2 => KbKey::HanjaMode,
|
Code::Lang2 => Key::HanjaMode,
|
||||||
Code::IntlYen => a("¥"),
|
Code::IntlYen => a("¥"),
|
||||||
Code::MetaLeft => KbKey::Meta,
|
Code::MetaLeft => Key::Meta,
|
||||||
Code::MetaRight => KbKey::Meta,
|
Code::MetaRight => Key::Meta,
|
||||||
Code::ContextMenu => KbKey::ContextMenu,
|
Code::ContextMenu => Key::ContextMenu,
|
||||||
Code::BrowserStop => KbKey::BrowserStop,
|
Code::BrowserStop => Key::BrowserStop,
|
||||||
Code::Again => KbKey::Again,
|
Code::Again => Key::Again,
|
||||||
Code::Props => KbKey::Props,
|
Code::Props => Key::Props,
|
||||||
Code::Undo => KbKey::Undo,
|
Code::Undo => Key::Undo,
|
||||||
Code::Select => KbKey::Select,
|
Code::Select => Key::Select,
|
||||||
Code::Copy => KbKey::Copy,
|
Code::Copy => Key::Copy,
|
||||||
Code::Open => KbKey::Open,
|
Code::Open => Key::Open,
|
||||||
Code::Paste => KbKey::Paste,
|
Code::Paste => Key::Paste,
|
||||||
Code::Find => KbKey::Find,
|
Code::Find => Key::Find,
|
||||||
Code::Cut => KbKey::Cut,
|
Code::Cut => Key::Cut,
|
||||||
Code::Help => KbKey::Help,
|
Code::Help => Key::Help,
|
||||||
Code::LaunchApp2 => KbKey::LaunchApplication2,
|
Code::LaunchApp2 => Key::LaunchApplication2,
|
||||||
Code::WakeUp => KbKey::WakeUp,
|
Code::WakeUp => Key::WakeUp,
|
||||||
Code::LaunchApp1 => KbKey::LaunchApplication1,
|
Code::LaunchApp1 => Key::LaunchApplication1,
|
||||||
Code::LaunchMail => KbKey::LaunchMail,
|
Code::LaunchMail => Key::LaunchMail,
|
||||||
Code::BrowserFavorites => KbKey::BrowserFavorites,
|
Code::BrowserFavorites => Key::BrowserFavorites,
|
||||||
Code::BrowserBack => KbKey::BrowserBack,
|
Code::BrowserBack => Key::BrowserBack,
|
||||||
Code::BrowserForward => KbKey::BrowserForward,
|
Code::BrowserForward => Key::BrowserForward,
|
||||||
Code::Eject => KbKey::Eject,
|
Code::Eject => Key::Eject,
|
||||||
Code::MediaTrackNext => KbKey::MediaTrackNext,
|
Code::MediaTrackNext => Key::MediaTrackNext,
|
||||||
Code::MediaPlayPause => KbKey::MediaPlayPause,
|
Code::MediaPlayPause => Key::MediaPlayPause,
|
||||||
Code::MediaTrackPrevious => KbKey::MediaTrackPrevious,
|
Code::MediaTrackPrevious => Key::MediaTrackPrevious,
|
||||||
Code::MediaStop => KbKey::MediaStop,
|
Code::MediaStop => Key::MediaStop,
|
||||||
Code::MediaSelect => KbKey::LaunchMediaPlayer,
|
Code::MediaSelect => Key::LaunchMediaPlayer,
|
||||||
Code::BrowserHome => KbKey::BrowserHome,
|
Code::BrowserHome => Key::BrowserHome,
|
||||||
Code::BrowserRefresh => KbKey::BrowserRefresh,
|
Code::BrowserRefresh => Key::BrowserRefresh,
|
||||||
Code::BrowserSearch => KbKey::BrowserSearch,
|
Code::BrowserSearch => Key::BrowserSearch,
|
||||||
|
|
||||||
_ => KbKey::Unidentified,
|
_ => Key::Unidentified,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,18 +388,18 @@ fn key_mods(mods: u16) -> Modifiers {
|
||||||
|
|
||||||
pub(super) fn convert_key_press_event(
|
pub(super) fn convert_key_press_event(
|
||||||
key_press: &xcb::KeyPressEvent,
|
key_press: &xcb::KeyPressEvent,
|
||||||
) -> KeyEvent {
|
) -> KeyboardEvent {
|
||||||
let hw_keycode = key_press.detail();
|
let hw_keycode = key_press.detail();
|
||||||
let code = hardware_keycode_to_code(hw_keycode.into());
|
let code = hardware_keycode_to_code(hw_keycode.into());
|
||||||
let mods = key_mods(key_press.state());
|
let modifiers = key_mods(key_press.state());
|
||||||
let key = code_to_key(code, mods);
|
let key = code_to_key(code, modifiers);
|
||||||
let location = code_to_location(code);
|
let location = code_to_location(code);
|
||||||
let state = KeyState::Down;
|
let state = KeyState::Down;
|
||||||
|
|
||||||
KeyEvent {
|
KeyboardEvent {
|
||||||
code,
|
code,
|
||||||
key,
|
key,
|
||||||
mods,
|
modifiers,
|
||||||
location,
|
location,
|
||||||
state,
|
state,
|
||||||
repeat: false,
|
repeat: false,
|
||||||
|
@ -408,18 +410,18 @@ pub(super) fn convert_key_press_event(
|
||||||
|
|
||||||
pub(super) fn convert_key_release_event(
|
pub(super) fn convert_key_release_event(
|
||||||
key_release: &xcb::KeyReleaseEvent
|
key_release: &xcb::KeyReleaseEvent
|
||||||
) -> KeyEvent {
|
) -> KeyboardEvent {
|
||||||
let hw_keycode = key_release.detail();
|
let hw_keycode = key_release.detail();
|
||||||
let code = hardware_keycode_to_code(hw_keycode.into());
|
let code = hardware_keycode_to_code(hw_keycode.into());
|
||||||
let mods = key_mods(key_release.state());
|
let modifiers = key_mods(key_release.state());
|
||||||
let key = code_to_key(code, mods);
|
let key = code_to_key(code, modifiers);
|
||||||
let location = code_to_location(code);
|
let location = code_to_location(code);
|
||||||
let state = KeyState::Up;
|
let state = KeyState::Up;
|
||||||
|
|
||||||
KeyEvent {
|
KeyboardEvent {
|
||||||
code,
|
code,
|
||||||
key,
|
key,
|
||||||
mods,
|
modifiers,
|
||||||
location,
|
location,
|
||||||
state,
|
state,
|
||||||
repeat: false,
|
repeat: false,
|
||||||
|
|
Loading…
Reference in a new issue