diff --git a/packages/blitz-dom/src/document.rs b/packages/blitz-dom/src/document.rs index d23aa2c9..ee208636 100644 --- a/packages/blitz-dom/src/document.rs +++ b/packages/blitz-dom/src/document.rs @@ -63,9 +63,8 @@ pub trait DocumentLike: AsRef + AsMut + Into + 'st false } - fn handle_event(&mut self, _event: RendererEvent) -> bool { + fn handle_event(&mut self, _event: RendererEvent) { // Default implementation does nothing - false } fn as_any_mut(&mut self) -> &mut dyn Any { @@ -125,8 +124,10 @@ pub struct Document { } impl DocumentLike for Document { - fn handle_event(&mut self, event: RendererEvent) -> bool { - // let node_id = event.target; + fn handle_event(&mut self, event: RendererEvent) { + let target_node_id = event.target; + + let event = dbg!(event); match event.data { EventData::Click { x, y, mods } => { @@ -140,12 +141,12 @@ impl DocumentLike for Document { y: node.final_layout.padding.top + node.final_layout.border.top, }; let Some(el) = node.raw_dom_data.downcast_element_mut() else { - return true; + return; }; let disabled = el.attr(local_name!("disabled")).is_some(); if disabled { - return true; + return; } if let NodeSpecificData::TextInput(ref mut text_input_data) = @@ -185,6 +186,10 @@ impl DocumentLike for Document { } EventData::KeyPress { event, mods } => { if let Some(node_id) = self.focus_node_id { + if target_node_id != node_id { + return; + } + let node = &mut self.nodes[node_id]; let text_input_data = node .raw_dom_data @@ -213,8 +218,6 @@ impl DocumentLike for Document { } EventData::Hover => {} } - - true } } diff --git a/packages/blitz-dom/src/events.rs b/packages/blitz-dom/src/events.rs index a72733a3..9193b4c9 100644 --- a/packages/blitz-dom/src/events.rs +++ b/packages/blitz-dom/src/events.rs @@ -4,7 +4,7 @@ pub struct EventListener { pub name: String, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RendererEvent { pub target: usize, pub data: EventData, @@ -17,7 +17,7 @@ impl RendererEvent { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum EventData { Click { x: f32, y: f32, mods: Modifiers }, KeyPress { event: KeyEvent, mods: Modifiers }, diff --git a/packages/blitz-dom/src/html_document.rs b/packages/blitz-dom/src/html_document.rs index 286de5a4..7b0bca7d 100644 --- a/packages/blitz-dom/src/html_document.rs +++ b/packages/blitz-dom/src/html_document.rs @@ -27,8 +27,8 @@ impl From for Document { } } impl DocumentLike for HtmlDocument { - fn handle_event(&mut self, event: RendererEvent) -> bool { - self.inner.as_mut().handle_event(event) + fn handle_event(&mut self, event: RendererEvent) { + self.inner.as_mut().handle_event(event); } } diff --git a/packages/dioxus-blitz/Cargo.toml b/packages/dioxus-blitz/Cargo.toml index a04a0fe9..97d61067 100644 --- a/packages/dioxus-blitz/Cargo.toml +++ b/packages/dioxus-blitz/Cargo.toml @@ -31,6 +31,7 @@ tracing = { workspace = true, optional = true } url = { version = "2.5.0", features = ["serde"] } ureq = "2.9" rustc-hash = "1.1.0" +keyboard-types = "0.7" [target.'cfg(target_os = "android")'.dependencies] android-activity = { version = "0.6.0", features = ["native-activity"] } diff --git a/packages/dioxus-blitz/src/documents/dioxus_document.rs b/packages/dioxus-blitz/src/documents/dioxus_document.rs index c0cad3ad..f9e4aa9b 100644 --- a/packages/dioxus-blitz/src/documents/dioxus_document.rs +++ b/packages/dioxus-blitz/src/documents/dioxus_document.rs @@ -7,7 +7,7 @@ use std::{ }; use blitz_dom::{ - events::EventData, + events::{EventData, RendererEvent}, local_name, namespace_url, node::{Attribute, NodeSpecificData}, ns, Atom, Document, DocumentLike, ElementNodeData, Node, NodeData, QualName, Viewport, @@ -29,6 +29,8 @@ use style::{ properties::{style_structs::Font, ComputedValues}, }; +use crate::documents::keyboard_event::BlitzKeyboardData; + use super::event_handler::{NativeClickData, NativeConverter, NativeFormData}; type NodeId = usize; @@ -49,6 +51,11 @@ pub struct DioxusDocument { // Implement DocumentLike and required traits for DioxusDocument +pub struct DxNodeIds { + node_id: usize, + dioxus_id: Option, +} + impl AsRef for DioxusDocument { fn as_ref(&self) -> &Document { &self.inner @@ -82,12 +89,11 @@ impl DocumentLike for DioxusDocument { true } - fn handle_event(&mut self, event: blitz_dom::events::RendererEvent) -> bool { + fn handle_event(&mut self, event: blitz_dom::events::RendererEvent) { // Collect the nodes into a chain by traversing upwards // This is important so the "capture" phase can be implemented - let mut node_id = event.target; + let mut next_node_id = Some(event.target); let mut chain = Vec::with_capacity(16); - chain.push(node_id); // if it's a capturing event, we want to fill in the chain with the parent nodes // until we reach the root - that way we can call the listeners in the correct order @@ -95,98 +101,186 @@ impl DocumentLike for DioxusDocument { // // todo: this is harcoded for "click" events - eventually we actually need to handle proper propagation // if event.name == "click" { - while let Some(parent) = self.inner.tree()[node_id].parent { - chain.push(parent); - node_id = parent; + while let Some(node_id) = next_node_id { + let node = &self.inner.tree()[node_id]; + + if let Some(element) = node.element_data() { + let dioxus_id = DioxusDocument::dioxus_id(element); + chain.push(DxNodeIds { node_id, dioxus_id }) + } + + next_node_id = node.parent; } set_event_converter(Box::new(NativeConverter {})); - let mut handled = false; - - if matches!(event.data, EventData::Click { .. }) { - // look for the data-dioxus-id attribute on the element - // todo: we might need to walk upwards to find the first element with a data-dioxus-id attribute - for node in chain.iter() { - let Some(element) = self.inner.tree()[*node].element_data() else { - #[cfg(feature = "tracing")] - tracing::info!( - "No element data found for node {}: {:?}", - node, - self.inner.tree()[*node] - ); - - continue; - }; + let renderer_event = event.clone(); - if let Some(id) = DioxusDocument::dioxus_id(element) { - // let data = dioxus::html::EventData::Mouse() - let click_event = Event::new(self.click_event_data(), true); - self.vdom.runtime().handle_event("click", click_event, id); - //TODO Check for other inputs which trigger input event on click here, eg radio - let triggers_input_event = element.name.local == local_name!("input") - && element.attr(local_name!("type")) == Some("checkbox"); - if triggers_input_event { - let form_data = self.input_event_form_data(&chain, element); - let input_event = Event::new(form_data, true); - self.vdom.runtime().handle_event("input", input_event, id); - } - handled = true; - // return true; - } + let mut prevent_default = false; + let mut stop_propagation = false; - //Clicking labels triggers click, and possibly input event, of bound input - if *element.name.local == *"label" { - let bound_input_elements = self.inner.label_bound_input_elements(*node); - //Filter down bound elements to those which have dioxus id - if let Some((element_data, dioxus_id)) = - bound_input_elements.into_iter().find_map(|n| { - let target_element_data = n.element_data()?; - let dioxus_id = DioxusDocument::dioxus_id(target_element_data)?; - Some((target_element_data, dioxus_id)) - }) - { - let click_event = Event::new(self.click_event_data(), true); + match &event.data { + EventData::Click { .. } => { + // look for the data-dioxus-id attribute on the element + // todo: we might need to walk upwards to find the first element with a data-dioxus-id attribute + + let click_event_data = wrap_event_data(NativeClickData); + + for &DxNodeIds { node_id, dioxus_id } in chain.iter() { + let element = self.inner.tree()[node_id].element_data().unwrap(); + + if let Some(id) = dioxus_id { + // Trigger click event + let click_event = Event::new(click_event_data.clone(), true); self.vdom .runtime() - .handle_event("click", click_event, dioxus_id); + .handle_event("click", click_event.clone(), id); + prevent_default |= !click_event.default_action_enabled(); + stop_propagation |= !click_event.propagates(); + //TODO Check for other inputs which trigger input event on click here, eg radio - let triggers_input_event = - element_data.attr(local_name!("type")) == Some("checkbox"); + let triggers_input_event = element.name.local == local_name!("input") + && element.attr(local_name!("type")) == Some("checkbox"); if triggers_input_event { - let form_data = self.input_event_form_data(&chain, element_data); + let form_data = + wrap_event_data(self.input_event_form_data(&chain, element)); let input_event = Event::new(form_data, true); + self.vdom.runtime().handle_event("input", input_event, id); + } + } + + //Clicking labels triggers click, and possibly input event, of bound input + if *element.name.local == *"label" { + let bound_input_elements = self.inner.label_bound_input_elements(node_id); + //Filter down bound elements to those which have dioxus id + if let Some((element_data, dioxus_id)) = + bound_input_elements.into_iter().find_map(|n| { + let target_element_data = n.element_data()?; + let dioxus_id = DioxusDocument::dioxus_id(target_element_data)?; + Some((target_element_data, dioxus_id)) + }) + { + let click_event = Event::new(click_event_data.clone(), true); self.vdom .runtime() - .handle_event("input", input_event, dioxus_id); + .handle_event("click", click_event, dioxus_id); + + // TODO: Generated click events should bubble separatedly + // prevent_default |= !click_event.default_action_enabled(); + + //TODO Check for other inputs which trigger input event on click here, eg radio + let triggers_input_event = + element_data.attr(local_name!("type")) == Some("checkbox"); + if triggers_input_event { + let form_data = wrap_event_data( + self.input_event_form_data(&chain, element_data), + ); + let input_event = Event::new(form_data, true); + self.vdom + .runtime() + .handle_event("input", input_event, dioxus_id); + } } - handled = true; - // return true; + } + + if stop_propagation { + break; } } } - } + EventData::KeyPress { + event: wevent, + mods, + } => { + let key_event_data = + wrap_event_data(BlitzKeyboardData::from_winit(wevent, mods.state())); + + for &DxNodeIds { node_id, dioxus_id } in chain.iter() { + println!("{} {:?}", node_id, dioxus_id); + + if let Some(id) = dioxus_id { + if wevent.state.is_pressed() { + // Handle keydown event + let event = Event::new(key_event_data.clone(), true); + self.vdom + .runtime() + .handle_event("keydown", event.clone(), id); + prevent_default |= !event.default_action_enabled(); + stop_propagation |= !event.propagates(); + + if !prevent_default && wevent.text.is_some() { + // Handle keypress event + let event = Event::new(key_event_data.clone(), true); + self.vdom + .runtime() + .handle_event("keypress", event.clone(), id); + prevent_default |= !event.default_action_enabled(); + stop_propagation |= !event.propagates(); + + if !prevent_default { + // Handle default DOM event + let default_event = RendererEvent { + target: node_id, + data: renderer_event.data.clone(), + }; + self.inner.as_mut().handle_event(default_event); + prevent_default = true; + + // Handle input event + let element = + self.inner.tree()[node_id].element_data().unwrap(); + let triggers_input_event = &element.name.local == "input" + && matches!( + element.attr(local_name!("type")), + None | Some("text" | "password" | "email" | "search") + ); + if triggers_input_event { + let form_data = wrap_event_data(dbg!( + self.input_event_form_data(&chain, element) + )); + let input_event = Event::new(form_data, true); + self.vdom.runtime().handle_event("input", input_event, id); + } + } + } + } else { + // Handle keyup event + let event = Event::new(key_event_data.clone(), true); + self.vdom.runtime().handle_event("keyup", event.clone(), id); + prevent_default |= !event.default_action_enabled(); + stop_propagation |= !event.propagates(); + } + } - self.inner.as_mut().handle_event(event); + if stop_propagation { + break; + } + } + } + EventData::Ime(_) => todo!(), + EventData::Hover => todo!(), + } - handled + if !prevent_default { + self.inner.as_mut().handle_event(event); + } } } -impl DioxusDocument { - pub fn click_event_data(&self) -> Rc { - Rc::new(PlatformEventData::new(Box::new(NativeClickData {}))) - } +fn wrap_event_data(value: T) -> Rc { + Rc::new(PlatformEventData::new(Box::new(value))) +} +impl DioxusDocument { /// Generate the FormData from an input event /// Currently only cares about input checkboxes pub fn input_event_form_data( &self, - parent_chain: &[usize], + parent_chain: &[DxNodeIds], element_node_data: &ElementNodeData, - ) -> Rc { - let parent_form = parent_chain.iter().find_map(|id| { - let node = self.inner.get_node(*id)?; + ) -> NativeFormData { + let parent_form = parent_chain.iter().map(|ids| ids.node_id).find_map(|id| { + let node = self.inner.get_node(id)?; let element_data = node.element_data()?; if element_data.name.local == local_name!("form") { Some(node) @@ -220,15 +314,16 @@ impl DioxusDocument { } else { Default::default() }; - let value = match element_node_data.node_specific_data { + let value = match &element_node_data.node_specific_data { NodeSpecificData::CheckboxInput(checked) => checked.to_string(), + NodeSpecificData::TextInput(input_data) => input_data.editor.layout.text().clone(), _ => element_node_data .attr(local_name!("value")) .unwrap_or_default() .to_string(), }; - let form_data = NativeFormData { value, values }; - Rc::new(PlatformEventData::new(Box::new(form_data))) + + NativeFormData { value, values } } /// Collect all the inputs which are descendents of a given node @@ -587,6 +682,13 @@ impl WriteMutations for MutationWriter<'_> { } // FIXME: support other non-text attributes else if let AttributeValue::Text(val) = value { + // Update text input value + if let Some(input_data) = element.text_input_data_mut() { + if input_data.editor.text() != val { + input_data.editor.set_text(val.clone()); + } + } + // FIXME check namespace let existing_attr = element .attrs @@ -612,6 +714,11 @@ impl WriteMutations for MutationWriter<'_> { } if let AttributeValue::None = value { + // Update text input value + if let Some(input_data) = element.text_input_data_mut() { + input_data.editor.set_text("".to_string()); + } + // FIXME: check namespace element.attrs.retain(|attr| attr.name.local != *name); } diff --git a/packages/dioxus-blitz/src/documents/event_handler.rs b/packages/dioxus-blitz/src/documents/event_handler.rs index 676396eb..d8a82cf4 100644 --- a/packages/dioxus-blitz/src/documents/event_handler.rs +++ b/packages/dioxus-blitz/src/documents/event_handler.rs @@ -5,8 +5,10 @@ use dioxus::{ prelude::{HtmlEventConverter, PlatformEventData}, }; +use super::keyboard_event::BlitzKeyboardData; + #[derive(Clone)] -pub struct NativeClickData {} +pub struct NativeClickData; impl dioxus::html::point_interaction::InteractionLocation for NativeClickData { fn client_coordinates(&self) -> dioxus::prelude::dioxus_elements::geometry::ClientPoint { @@ -82,8 +84,9 @@ impl HtmlEventConverter for NativeConverter { todo!() } - fn convert_keyboard_data(&self, _event: &PlatformEventData) -> dioxus::prelude::KeyboardData { - todo!() + fn convert_keyboard_data(&self, event: &PlatformEventData) -> dioxus::prelude::KeyboardData { + let data = event.downcast::().unwrap().clone(); + dioxus::prelude::KeyboardData::from(data) } fn convert_media_data(&self, _event: &PlatformEventData) -> dioxus::prelude::MediaData { diff --git a/packages/dioxus-blitz/src/documents/keyboard_event.rs b/packages/dioxus-blitz/src/documents/keyboard_event.rs new file mode 100644 index 00000000..25375036 --- /dev/null +++ b/packages/dioxus-blitz/src/documents/keyboard_event.rs @@ -0,0 +1,615 @@ +use std::any::Any; + +use dioxus::events::{HasKeyboardData, ModifiersInteraction}; +use keyboard_types::{Code, Key, Location, Modifiers}; + +use winit::event::KeyEvent as WinitKeyEvent; +use winit::keyboard::Key as WinitKey; +use winit::keyboard::KeyCode as WinitKeyCode; +use winit::keyboard::KeyLocation as WinitKeyLocation; +use winit::keyboard::ModifiersState as WinitModifiers; +use winit::keyboard::NamedKey as WinitNamedKey; +use winit::keyboard::PhysicalKey as WinitPhysicalKey; + +#[derive(Clone, Debug)] +pub(crate) struct BlitzKeyboardData { + key: Key, + code: Code, + modifiers: Modifiers, + location: Location, + is_auto_repeating: bool, + is_composing: bool, +} + +impl ModifiersInteraction for BlitzKeyboardData { + fn modifiers(&self) -> Modifiers { + self.modifiers + } +} + +impl HasKeyboardData for BlitzKeyboardData { + fn key(&self) -> Key { + self.key.clone() + } + + fn code(&self) -> Code { + self.code + } + + fn location(&self) -> Location { + self.location + } + + fn is_auto_repeating(&self) -> bool { + self.is_auto_repeating + } + + fn is_composing(&self) -> bool { + self.is_composing + } + + fn as_any(&self) -> &dyn std::any::Any { + self as &dyn Any + } +} + +impl BlitzKeyboardData { + pub(crate) fn from_winit(event: &WinitKeyEvent, mods: WinitModifiers) -> Self { + Self { + key: winit_key_to_kbt_key(&event.logical_key), + code: winit_physical_key_to_kbt_code(&event.physical_key), + modifiers: winit_modifiers_to_kbt_modifiers(mods), + location: winit_key_location_to_kbt_location(event.location), + is_auto_repeating: event.repeat, + is_composing: false, + } + } +} + +fn winit_modifiers_to_kbt_modifiers(winit_modifiers: WinitModifiers) -> Modifiers { + let mut modifiers = Modifiers::default(); + if winit_modifiers.control_key() { + modifiers.insert(Modifiers::CONTROL); + } + if winit_modifiers.alt_key() { + modifiers.insert(Modifiers::ALT); + } + if winit_modifiers.shift_key() { + modifiers.insert(Modifiers::SHIFT); + } + if winit_modifiers.super_key() { + modifiers.insert(Modifiers::SUPER); + } + modifiers +} + +fn winit_key_location_to_kbt_location(location: WinitKeyLocation) -> Location { + match location { + WinitKeyLocation::Standard => Location::Standard, + WinitKeyLocation::Left => Location::Left, + WinitKeyLocation::Right => Location::Right, + WinitKeyLocation::Numpad => Location::Numpad, + } +} + +fn winit_physical_key_to_kbt_code(physical_key: &WinitPhysicalKey) -> Code { + match physical_key { + WinitPhysicalKey::Unidentified(_) => Code::Unidentified, + WinitPhysicalKey::Code(key_code) => match key_code { + // Variants that don't match 1:1 + WinitKeyCode::Meta => Code::Super, + WinitKeyCode::SuperLeft => Code::Super, + WinitKeyCode::SuperRight => Code::Super, + + WinitKeyCode::Backquote => Code::Backquote, + WinitKeyCode::Backslash => Code::Backslash, + WinitKeyCode::BracketLeft => Code::BracketLeft, + WinitKeyCode::BracketRight => Code::BracketRight, + WinitKeyCode::Comma => Code::Comma, + WinitKeyCode::Digit0 => Code::Digit0, + WinitKeyCode::Digit1 => Code::Digit1, + WinitKeyCode::Digit2 => Code::Digit2, + WinitKeyCode::Digit3 => Code::Digit3, + WinitKeyCode::Digit4 => Code::Digit4, + WinitKeyCode::Digit5 => Code::Digit5, + WinitKeyCode::Digit6 => Code::Digit6, + WinitKeyCode::Digit7 => Code::Digit7, + WinitKeyCode::Digit8 => Code::Digit8, + WinitKeyCode::Digit9 => Code::Digit9, + WinitKeyCode::Equal => Code::Equal, + WinitKeyCode::IntlBackslash => Code::IntlBackslash, + WinitKeyCode::IntlRo => Code::IntlRo, + WinitKeyCode::IntlYen => Code::IntlYen, + WinitKeyCode::KeyA => Code::KeyA, + WinitKeyCode::KeyB => Code::KeyB, + WinitKeyCode::KeyC => Code::KeyC, + WinitKeyCode::KeyD => Code::KeyD, + WinitKeyCode::KeyE => Code::KeyE, + WinitKeyCode::KeyF => Code::KeyF, + WinitKeyCode::KeyG => Code::KeyG, + WinitKeyCode::KeyH => Code::KeyH, + WinitKeyCode::KeyI => Code::KeyI, + WinitKeyCode::KeyJ => Code::KeyJ, + WinitKeyCode::KeyK => Code::KeyK, + WinitKeyCode::KeyL => Code::KeyL, + WinitKeyCode::KeyM => Code::KeyM, + WinitKeyCode::KeyN => Code::KeyN, + WinitKeyCode::KeyO => Code::KeyO, + WinitKeyCode::KeyP => Code::KeyP, + WinitKeyCode::KeyQ => Code::KeyQ, + WinitKeyCode::KeyR => Code::KeyR, + WinitKeyCode::KeyS => Code::KeyS, + WinitKeyCode::KeyT => Code::KeyT, + WinitKeyCode::KeyU => Code::KeyU, + WinitKeyCode::KeyV => Code::KeyV, + WinitKeyCode::KeyW => Code::KeyW, + WinitKeyCode::KeyX => Code::KeyX, + WinitKeyCode::KeyY => Code::KeyY, + WinitKeyCode::KeyZ => Code::KeyZ, + WinitKeyCode::Minus => Code::Minus, + WinitKeyCode::Period => Code::Period, + WinitKeyCode::Quote => Code::Quote, + WinitKeyCode::Semicolon => Code::Semicolon, + WinitKeyCode::Slash => Code::Slash, + WinitKeyCode::AltLeft => Code::AltLeft, + WinitKeyCode::AltRight => Code::AltRight, + WinitKeyCode::Backspace => Code::Backspace, + WinitKeyCode::CapsLock => Code::CapsLock, + WinitKeyCode::ContextMenu => Code::ContextMenu, + WinitKeyCode::ControlLeft => Code::ControlLeft, + WinitKeyCode::ControlRight => Code::ControlRight, + WinitKeyCode::Enter => Code::Enter, + WinitKeyCode::ShiftLeft => Code::ShiftLeft, + WinitKeyCode::ShiftRight => Code::ShiftRight, + WinitKeyCode::Space => Code::Space, + WinitKeyCode::Tab => Code::Tab, + WinitKeyCode::Convert => Code::Convert, + WinitKeyCode::KanaMode => Code::KanaMode, + WinitKeyCode::Lang1 => Code::Lang1, + WinitKeyCode::Lang2 => Code::Lang2, + WinitKeyCode::Lang3 => Code::Lang3, + WinitKeyCode::Lang4 => Code::Lang4, + WinitKeyCode::Lang5 => Code::Lang5, + WinitKeyCode::NonConvert => Code::NonConvert, + WinitKeyCode::Delete => Code::Delete, + WinitKeyCode::End => Code::End, + WinitKeyCode::Help => Code::Help, + WinitKeyCode::Home => Code::Home, + WinitKeyCode::Insert => Code::Insert, + WinitKeyCode::PageDown => Code::PageDown, + WinitKeyCode::PageUp => Code::PageUp, + WinitKeyCode::ArrowDown => Code::ArrowDown, + WinitKeyCode::ArrowLeft => Code::ArrowLeft, + WinitKeyCode::ArrowRight => Code::ArrowRight, + WinitKeyCode::ArrowUp => Code::ArrowUp, + WinitKeyCode::NumLock => Code::NumLock, + WinitKeyCode::Numpad0 => Code::Numpad0, + WinitKeyCode::Numpad1 => Code::Numpad1, + WinitKeyCode::Numpad2 => Code::Numpad2, + WinitKeyCode::Numpad3 => Code::Numpad3, + WinitKeyCode::Numpad4 => Code::Numpad4, + WinitKeyCode::Numpad5 => Code::Numpad5, + WinitKeyCode::Numpad6 => Code::Numpad6, + WinitKeyCode::Numpad7 => Code::Numpad7, + WinitKeyCode::Numpad8 => Code::Numpad8, + WinitKeyCode::Numpad9 => Code::Numpad9, + WinitKeyCode::NumpadAdd => Code::NumpadAdd, + WinitKeyCode::NumpadBackspace => Code::NumpadBackspace, + WinitKeyCode::NumpadClear => Code::NumpadClear, + WinitKeyCode::NumpadClearEntry => Code::NumpadClearEntry, + WinitKeyCode::NumpadComma => Code::NumpadComma, + WinitKeyCode::NumpadDecimal => Code::NumpadDecimal, + WinitKeyCode::NumpadDivide => Code::NumpadDivide, + WinitKeyCode::NumpadEnter => Code::NumpadEnter, + WinitKeyCode::NumpadEqual => Code::NumpadEqual, + WinitKeyCode::NumpadHash => Code::NumpadHash, + WinitKeyCode::NumpadMemoryAdd => Code::NumpadMemoryAdd, + WinitKeyCode::NumpadMemoryClear => Code::NumpadMemoryClear, + WinitKeyCode::NumpadMemoryRecall => Code::NumpadMemoryRecall, + WinitKeyCode::NumpadMemoryStore => Code::NumpadMemoryStore, + WinitKeyCode::NumpadMemorySubtract => Code::NumpadMemorySubtract, + WinitKeyCode::NumpadMultiply => Code::NumpadMultiply, + WinitKeyCode::NumpadParenLeft => Code::NumpadParenLeft, + WinitKeyCode::NumpadParenRight => Code::NumpadParenRight, + WinitKeyCode::NumpadStar => Code::NumpadStar, + WinitKeyCode::NumpadSubtract => Code::NumpadSubtract, + WinitKeyCode::Escape => Code::Escape, + WinitKeyCode::Fn => Code::Fn, + WinitKeyCode::FnLock => Code::FnLock, + WinitKeyCode::PrintScreen => Code::PrintScreen, + WinitKeyCode::ScrollLock => Code::ScrollLock, + WinitKeyCode::Pause => Code::Pause, + WinitKeyCode::BrowserBack => Code::BrowserBack, + WinitKeyCode::BrowserFavorites => Code::BrowserFavorites, + WinitKeyCode::BrowserForward => Code::BrowserForward, + WinitKeyCode::BrowserHome => Code::BrowserHome, + WinitKeyCode::BrowserRefresh => Code::BrowserRefresh, + WinitKeyCode::BrowserSearch => Code::BrowserSearch, + WinitKeyCode::BrowserStop => Code::BrowserStop, + WinitKeyCode::Eject => Code::Eject, + WinitKeyCode::LaunchApp1 => Code::LaunchApp1, + WinitKeyCode::LaunchApp2 => Code::LaunchApp2, + WinitKeyCode::LaunchMail => Code::LaunchMail, + WinitKeyCode::MediaPlayPause => Code::MediaPlayPause, + WinitKeyCode::MediaSelect => Code::MediaSelect, + WinitKeyCode::MediaStop => Code::MediaStop, + WinitKeyCode::MediaTrackNext => Code::MediaTrackNext, + WinitKeyCode::MediaTrackPrevious => Code::MediaTrackPrevious, + WinitKeyCode::Power => Code::Power, + WinitKeyCode::Sleep => Code::Sleep, + WinitKeyCode::AudioVolumeDown => Code::AudioVolumeDown, + WinitKeyCode::AudioVolumeMute => Code::AudioVolumeMute, + WinitKeyCode::AudioVolumeUp => Code::AudioVolumeUp, + WinitKeyCode::WakeUp => Code::WakeUp, + WinitKeyCode::Hyper => Code::Hyper, + WinitKeyCode::Turbo => Code::Turbo, + WinitKeyCode::Abort => Code::Abort, + WinitKeyCode::Resume => Code::Resume, + WinitKeyCode::Suspend => Code::Suspend, + WinitKeyCode::Again => Code::Again, + WinitKeyCode::Copy => Code::Copy, + WinitKeyCode::Cut => Code::Cut, + WinitKeyCode::Find => Code::Find, + WinitKeyCode::Open => Code::Open, + WinitKeyCode::Paste => Code::Paste, + WinitKeyCode::Props => Code::Props, + WinitKeyCode::Select => Code::Select, + WinitKeyCode::Undo => Code::Undo, + WinitKeyCode::Hiragana => Code::Hiragana, + WinitKeyCode::Katakana => Code::Katakana, + WinitKeyCode::F1 => Code::F1, + WinitKeyCode::F2 => Code::F2, + WinitKeyCode::F3 => Code::F3, + WinitKeyCode::F4 => Code::F4, + WinitKeyCode::F5 => Code::F5, + WinitKeyCode::F6 => Code::F6, + WinitKeyCode::F7 => Code::F7, + WinitKeyCode::F8 => Code::F8, + WinitKeyCode::F9 => Code::F9, + WinitKeyCode::F10 => Code::F10, + WinitKeyCode::F11 => Code::F11, + WinitKeyCode::F12 => Code::F12, + WinitKeyCode::F13 => Code::F13, + WinitKeyCode::F14 => Code::F14, + WinitKeyCode::F15 => Code::F15, + WinitKeyCode::F16 => Code::F16, + WinitKeyCode::F17 => Code::F17, + WinitKeyCode::F18 => Code::F18, + WinitKeyCode::F19 => Code::F19, + WinitKeyCode::F20 => Code::F20, + WinitKeyCode::F21 => Code::F21, + WinitKeyCode::F22 => Code::F22, + WinitKeyCode::F23 => Code::F23, + WinitKeyCode::F24 => Code::F24, + WinitKeyCode::F25 => Code::F25, + WinitKeyCode::F26 => Code::F26, + WinitKeyCode::F27 => Code::F27, + WinitKeyCode::F28 => Code::F28, + WinitKeyCode::F29 => Code::F29, + WinitKeyCode::F30 => Code::F30, + WinitKeyCode::F31 => Code::F31, + WinitKeyCode::F32 => Code::F32, + WinitKeyCode::F33 => Code::F33, + WinitKeyCode::F34 => Code::F34, + WinitKeyCode::F35 => Code::F35, + _ => todo!(), + }, + } +} + +fn winit_key_to_kbt_key(winit_key: &WinitKey) -> Key { + match winit_key { + WinitKey::Character(c) => Key::Character(c.to_string()), + WinitKey::Unidentified(_) => Key::Unidentified, + WinitKey::Dead(_) => Key::Dead, + WinitKey::Named(named_key) => match named_key { + WinitNamedKey::Alt => Key::Alt, + WinitNamedKey::AltGraph => Key::AltGraph, + WinitNamedKey::CapsLock => Key::CapsLock, + WinitNamedKey::Control => Key::Control, + WinitNamedKey::Fn => Key::Fn, + WinitNamedKey::FnLock => Key::FnLock, + WinitNamedKey::NumLock => Key::NumLock, + WinitNamedKey::ScrollLock => Key::ScrollLock, + WinitNamedKey::Shift => Key::Shift, + WinitNamedKey::Symbol => Key::Symbol, + WinitNamedKey::SymbolLock => Key::SymbolLock, + WinitNamedKey::Meta => Key::Meta, + WinitNamedKey::Hyper => Key::Hyper, + WinitNamedKey::Super => Key::Super, + WinitNamedKey::Enter => Key::Enter, + WinitNamedKey::Tab => Key::Tab, + WinitNamedKey::Space => Key::Character(" ".to_string()), + WinitNamedKey::ArrowDown => Key::ArrowDown, + WinitNamedKey::ArrowLeft => Key::ArrowLeft, + WinitNamedKey::ArrowRight => Key::ArrowRight, + WinitNamedKey::ArrowUp => Key::ArrowUp, + WinitNamedKey::End => Key::End, + WinitNamedKey::Home => Key::Home, + WinitNamedKey::PageDown => Key::PageDown, + WinitNamedKey::PageUp => Key::PageUp, + WinitNamedKey::Backspace => Key::Backspace, + WinitNamedKey::Clear => Key::Clear, + WinitNamedKey::Copy => Key::Copy, + WinitNamedKey::CrSel => Key::CrSel, + WinitNamedKey::Cut => Key::Cut, + WinitNamedKey::Delete => Key::Delete, + WinitNamedKey::EraseEof => Key::EraseEof, + WinitNamedKey::ExSel => Key::ExSel, + WinitNamedKey::Insert => Key::Insert, + WinitNamedKey::Paste => Key::Paste, + WinitNamedKey::Redo => Key::Redo, + WinitNamedKey::Undo => Key::Undo, + WinitNamedKey::Accept => Key::Accept, + WinitNamedKey::Again => Key::Again, + WinitNamedKey::Attn => Key::Attn, + WinitNamedKey::Cancel => Key::Cancel, + WinitNamedKey::ContextMenu => Key::ContextMenu, + WinitNamedKey::Escape => Key::Escape, + WinitNamedKey::Execute => Key::Execute, + WinitNamedKey::Find => Key::Find, + WinitNamedKey::Help => Key::Help, + WinitNamedKey::Pause => Key::Pause, + WinitNamedKey::Play => Key::Play, + WinitNamedKey::Props => Key::Props, + WinitNamedKey::Select => Key::Select, + WinitNamedKey::ZoomIn => Key::ZoomIn, + WinitNamedKey::ZoomOut => Key::ZoomOut, + WinitNamedKey::BrightnessDown => Key::BrightnessDown, + WinitNamedKey::BrightnessUp => Key::BrightnessUp, + WinitNamedKey::Eject => Key::Eject, + WinitNamedKey::LogOff => Key::LogOff, + WinitNamedKey::Power => Key::Power, + WinitNamedKey::PowerOff => Key::PowerOff, + WinitNamedKey::PrintScreen => Key::PrintScreen, + WinitNamedKey::Hibernate => Key::Hibernate, + WinitNamedKey::Standby => Key::Standby, + WinitNamedKey::WakeUp => Key::WakeUp, + WinitNamedKey::AllCandidates => Key::AllCandidates, + WinitNamedKey::Alphanumeric => Key::Alphanumeric, + WinitNamedKey::CodeInput => Key::CodeInput, + WinitNamedKey::Compose => Key::Compose, + WinitNamedKey::Convert => Key::Convert, + WinitNamedKey::FinalMode => Key::FinalMode, + WinitNamedKey::GroupFirst => Key::GroupFirst, + WinitNamedKey::GroupLast => Key::GroupLast, + WinitNamedKey::GroupNext => Key::GroupNext, + WinitNamedKey::GroupPrevious => Key::GroupPrevious, + WinitNamedKey::ModeChange => Key::ModeChange, + WinitNamedKey::NextCandidate => Key::NextCandidate, + WinitNamedKey::NonConvert => Key::NonConvert, + WinitNamedKey::PreviousCandidate => Key::PreviousCandidate, + WinitNamedKey::Process => Key::Process, + WinitNamedKey::SingleCandidate => Key::SingleCandidate, + WinitNamedKey::HangulMode => Key::HangulMode, + WinitNamedKey::HanjaMode => Key::HanjaMode, + WinitNamedKey::JunjaMode => Key::JunjaMode, + WinitNamedKey::Eisu => Key::Eisu, + WinitNamedKey::Hankaku => Key::Hankaku, + WinitNamedKey::Hiragana => Key::Hiragana, + WinitNamedKey::HiraganaKatakana => Key::HiraganaKatakana, + WinitNamedKey::KanaMode => Key::KanaMode, + WinitNamedKey::KanjiMode => Key::KanjiMode, + WinitNamedKey::Katakana => Key::Katakana, + WinitNamedKey::Romaji => Key::Romaji, + WinitNamedKey::Zenkaku => Key::Zenkaku, + WinitNamedKey::ZenkakuHankaku => Key::ZenkakuHankaku, + WinitNamedKey::Soft1 => Key::Soft1, + WinitNamedKey::Soft2 => Key::Soft2, + WinitNamedKey::Soft3 => Key::Soft3, + WinitNamedKey::Soft4 => Key::Soft4, + WinitNamedKey::ChannelDown => Key::ChannelDown, + WinitNamedKey::ChannelUp => Key::ChannelUp, + WinitNamedKey::Close => Key::Close, + WinitNamedKey::MailForward => Key::MailForward, + WinitNamedKey::MailReply => Key::MailReply, + WinitNamedKey::MailSend => Key::MailSend, + WinitNamedKey::MediaClose => Key::MediaClose, + WinitNamedKey::MediaFastForward => Key::MediaFastForward, + WinitNamedKey::MediaPause => Key::MediaPause, + WinitNamedKey::MediaPlay => Key::MediaPlay, + WinitNamedKey::MediaPlayPause => Key::MediaPlayPause, + WinitNamedKey::MediaRecord => Key::MediaRecord, + WinitNamedKey::MediaRewind => Key::MediaRewind, + WinitNamedKey::MediaStop => Key::MediaStop, + WinitNamedKey::MediaTrackNext => Key::MediaTrackNext, + WinitNamedKey::MediaTrackPrevious => Key::MediaTrackPrevious, + WinitNamedKey::New => Key::New, + WinitNamedKey::Open => Key::Open, + WinitNamedKey::Print => Key::Print, + WinitNamedKey::Save => Key::Save, + WinitNamedKey::SpellCheck => Key::SpellCheck, + WinitNamedKey::Key11 => Key::Key11, + WinitNamedKey::Key12 => Key::Key12, + WinitNamedKey::AudioBalanceLeft => Key::AudioBalanceLeft, + WinitNamedKey::AudioBalanceRight => Key::AudioBalanceRight, + WinitNamedKey::AudioBassBoostDown => Key::AudioBassBoostDown, + WinitNamedKey::AudioBassBoostToggle => Key::AudioBassBoostToggle, + WinitNamedKey::AudioBassBoostUp => Key::AudioBassBoostUp, + WinitNamedKey::AudioFaderFront => Key::AudioFaderFront, + WinitNamedKey::AudioFaderRear => Key::AudioFaderRear, + WinitNamedKey::AudioSurroundModeNext => Key::AudioSurroundModeNext, + WinitNamedKey::AudioTrebleDown => Key::AudioTrebleDown, + WinitNamedKey::AudioTrebleUp => Key::AudioTrebleUp, + WinitNamedKey::AudioVolumeDown => Key::AudioVolumeDown, + WinitNamedKey::AudioVolumeUp => Key::AudioVolumeUp, + WinitNamedKey::AudioVolumeMute => Key::AudioVolumeMute, + WinitNamedKey::MicrophoneToggle => Key::MicrophoneToggle, + WinitNamedKey::MicrophoneVolumeDown => Key::MicrophoneVolumeDown, + WinitNamedKey::MicrophoneVolumeUp => Key::MicrophoneVolumeUp, + WinitNamedKey::MicrophoneVolumeMute => Key::MicrophoneVolumeMute, + WinitNamedKey::SpeechCorrectionList => Key::SpeechCorrectionList, + WinitNamedKey::SpeechInputToggle => Key::SpeechInputToggle, + WinitNamedKey::LaunchApplication1 => Key::LaunchApplication1, + WinitNamedKey::LaunchApplication2 => Key::LaunchApplication2, + WinitNamedKey::LaunchCalendar => Key::LaunchCalendar, + WinitNamedKey::LaunchContacts => Key::LaunchContacts, + WinitNamedKey::LaunchMail => Key::LaunchMail, + WinitNamedKey::LaunchMediaPlayer => Key::LaunchMediaPlayer, + WinitNamedKey::LaunchMusicPlayer => Key::LaunchMusicPlayer, + WinitNamedKey::LaunchPhone => Key::LaunchPhone, + WinitNamedKey::LaunchScreenSaver => Key::LaunchScreenSaver, + WinitNamedKey::LaunchSpreadsheet => Key::LaunchSpreadsheet, + WinitNamedKey::LaunchWebBrowser => Key::LaunchWebBrowser, + WinitNamedKey::LaunchWebCam => Key::LaunchWebCam, + WinitNamedKey::LaunchWordProcessor => Key::LaunchWordProcessor, + WinitNamedKey::BrowserBack => Key::BrowserBack, + WinitNamedKey::BrowserFavorites => Key::BrowserFavorites, + WinitNamedKey::BrowserForward => Key::BrowserForward, + WinitNamedKey::BrowserHome => Key::BrowserHome, + WinitNamedKey::BrowserRefresh => Key::BrowserRefresh, + WinitNamedKey::BrowserSearch => Key::BrowserSearch, + WinitNamedKey::BrowserStop => Key::BrowserStop, + WinitNamedKey::AppSwitch => Key::AppSwitch, + WinitNamedKey::Call => Key::Call, + WinitNamedKey::Camera => Key::Camera, + WinitNamedKey::CameraFocus => Key::CameraFocus, + WinitNamedKey::EndCall => Key::EndCall, + WinitNamedKey::GoBack => Key::GoBack, + WinitNamedKey::GoHome => Key::GoHome, + WinitNamedKey::HeadsetHook => Key::HeadsetHook, + WinitNamedKey::LastNumberRedial => Key::LastNumberRedial, + WinitNamedKey::Notification => Key::Notification, + WinitNamedKey::MannerMode => Key::MannerMode, + WinitNamedKey::VoiceDial => Key::VoiceDial, + WinitNamedKey::TV => Key::TV, + WinitNamedKey::TV3DMode => Key::TV3DMode, + WinitNamedKey::TVAntennaCable => Key::TVAntennaCable, + WinitNamedKey::TVAudioDescription => Key::TVAudioDescription, + WinitNamedKey::TVAudioDescriptionMixDown => Key::TVAudioDescriptionMixDown, + WinitNamedKey::TVAudioDescriptionMixUp => Key::TVAudioDescriptionMixUp, + WinitNamedKey::TVContentsMenu => Key::TVContentsMenu, + WinitNamedKey::TVDataService => Key::TVDataService, + WinitNamedKey::TVInput => Key::TVInput, + WinitNamedKey::TVInputComponent1 => Key::TVInputComponent1, + WinitNamedKey::TVInputComponent2 => Key::TVInputComponent2, + WinitNamedKey::TVInputComposite1 => Key::TVInputComposite1, + WinitNamedKey::TVInputComposite2 => Key::TVInputComposite2, + WinitNamedKey::TVInputHDMI1 => Key::TVInputHDMI1, + WinitNamedKey::TVInputHDMI2 => Key::TVInputHDMI2, + WinitNamedKey::TVInputHDMI3 => Key::TVInputHDMI3, + WinitNamedKey::TVInputHDMI4 => Key::TVInputHDMI4, + WinitNamedKey::TVInputVGA1 => Key::TVInputVGA1, + WinitNamedKey::TVMediaContext => Key::TVMediaContext, + WinitNamedKey::TVNetwork => Key::TVNetwork, + WinitNamedKey::TVNumberEntry => Key::TVNumberEntry, + WinitNamedKey::TVPower => Key::TVPower, + WinitNamedKey::TVRadioService => Key::TVRadioService, + WinitNamedKey::TVSatellite => Key::TVSatellite, + WinitNamedKey::TVSatelliteBS => Key::TVSatelliteBS, + WinitNamedKey::TVSatelliteCS => Key::TVSatelliteCS, + WinitNamedKey::TVSatelliteToggle => Key::TVSatelliteToggle, + WinitNamedKey::TVTerrestrialAnalog => Key::TVTerrestrialAnalog, + WinitNamedKey::TVTerrestrialDigital => Key::TVTerrestrialDigital, + WinitNamedKey::TVTimer => Key::TVTimer, + WinitNamedKey::AVRInput => Key::AVRInput, + WinitNamedKey::AVRPower => Key::AVRPower, + WinitNamedKey::ColorF0Red => Key::ColorF0Red, + WinitNamedKey::ColorF1Green => Key::ColorF1Green, + WinitNamedKey::ColorF2Yellow => Key::ColorF2Yellow, + WinitNamedKey::ColorF3Blue => Key::ColorF3Blue, + WinitNamedKey::ColorF4Grey => Key::ColorF4Grey, + WinitNamedKey::ColorF5Brown => Key::ColorF5Brown, + WinitNamedKey::ClosedCaptionToggle => Key::ClosedCaptionToggle, + WinitNamedKey::Dimmer => Key::Dimmer, + WinitNamedKey::DisplaySwap => Key::DisplaySwap, + WinitNamedKey::DVR => Key::DVR, + WinitNamedKey::Exit => Key::Exit, + WinitNamedKey::FavoriteClear0 => Key::FavoriteClear0, + WinitNamedKey::FavoriteClear1 => Key::FavoriteClear1, + WinitNamedKey::FavoriteClear2 => Key::FavoriteClear2, + WinitNamedKey::FavoriteClear3 => Key::FavoriteClear3, + WinitNamedKey::FavoriteRecall0 => Key::FavoriteRecall0, + WinitNamedKey::FavoriteRecall1 => Key::FavoriteRecall1, + WinitNamedKey::FavoriteRecall2 => Key::FavoriteRecall2, + WinitNamedKey::FavoriteRecall3 => Key::FavoriteRecall3, + WinitNamedKey::FavoriteStore0 => Key::FavoriteStore0, + WinitNamedKey::FavoriteStore1 => Key::FavoriteStore1, + WinitNamedKey::FavoriteStore2 => Key::FavoriteStore2, + WinitNamedKey::FavoriteStore3 => Key::FavoriteStore3, + WinitNamedKey::Guide => Key::Guide, + WinitNamedKey::GuideNextDay => Key::GuideNextDay, + WinitNamedKey::GuidePreviousDay => Key::GuidePreviousDay, + WinitNamedKey::Info => Key::Info, + WinitNamedKey::InstantReplay => Key::InstantReplay, + WinitNamedKey::Link => Key::Link, + WinitNamedKey::ListProgram => Key::ListProgram, + WinitNamedKey::LiveContent => Key::LiveContent, + WinitNamedKey::Lock => Key::Lock, + WinitNamedKey::MediaApps => Key::MediaApps, + WinitNamedKey::MediaAudioTrack => Key::MediaAudioTrack, + WinitNamedKey::MediaLast => Key::MediaLast, + WinitNamedKey::MediaSkipBackward => Key::MediaSkipBackward, + WinitNamedKey::MediaSkipForward => Key::MediaSkipForward, + WinitNamedKey::MediaStepBackward => Key::MediaStepBackward, + WinitNamedKey::MediaStepForward => Key::MediaStepForward, + WinitNamedKey::MediaTopMenu => Key::MediaTopMenu, + WinitNamedKey::NavigateIn => Key::NavigateIn, + WinitNamedKey::NavigateNext => Key::NavigateNext, + WinitNamedKey::NavigateOut => Key::NavigateOut, + WinitNamedKey::NavigatePrevious => Key::NavigatePrevious, + WinitNamedKey::NextFavoriteChannel => Key::NextFavoriteChannel, + WinitNamedKey::NextUserProfile => Key::NextUserProfile, + WinitNamedKey::OnDemand => Key::OnDemand, + WinitNamedKey::Pairing => Key::Pairing, + WinitNamedKey::PinPDown => Key::PinPDown, + WinitNamedKey::PinPMove => Key::PinPMove, + WinitNamedKey::PinPToggle => Key::PinPToggle, + WinitNamedKey::PinPUp => Key::PinPUp, + WinitNamedKey::PlaySpeedDown => Key::PlaySpeedDown, + WinitNamedKey::PlaySpeedReset => Key::PlaySpeedReset, + WinitNamedKey::PlaySpeedUp => Key::PlaySpeedUp, + WinitNamedKey::RandomToggle => Key::RandomToggle, + WinitNamedKey::RcLowBattery => Key::RcLowBattery, + WinitNamedKey::RecordSpeedNext => Key::RecordSpeedNext, + WinitNamedKey::RfBypass => Key::RfBypass, + WinitNamedKey::ScanChannelsToggle => Key::ScanChannelsToggle, + WinitNamedKey::ScreenModeNext => Key::ScreenModeNext, + WinitNamedKey::Settings => Key::Settings, + WinitNamedKey::SplitScreenToggle => Key::SplitScreenToggle, + WinitNamedKey::STBInput => Key::STBInput, + WinitNamedKey::STBPower => Key::STBPower, + WinitNamedKey::Subtitle => Key::Subtitle, + WinitNamedKey::Teletext => Key::Teletext, + WinitNamedKey::VideoModeNext => Key::VideoModeNext, + WinitNamedKey::Wink => Key::Wink, + WinitNamedKey::ZoomToggle => Key::ZoomToggle, + WinitNamedKey::F1 => Key::F1, + WinitNamedKey::F2 => Key::F2, + WinitNamedKey::F3 => Key::F3, + WinitNamedKey::F4 => Key::F4, + WinitNamedKey::F5 => Key::F5, + WinitNamedKey::F6 => Key::F6, + WinitNamedKey::F7 => Key::F7, + WinitNamedKey::F8 => Key::F8, + WinitNamedKey::F9 => Key::F9, + WinitNamedKey::F10 => Key::F10, + WinitNamedKey::F11 => Key::F11, + WinitNamedKey::F12 => Key::F12, + WinitNamedKey::F13 => Key::F13, + WinitNamedKey::F14 => Key::F14, + WinitNamedKey::F15 => Key::F15, + WinitNamedKey::F16 => Key::F16, + WinitNamedKey::F17 => Key::F17, + WinitNamedKey::F18 => Key::F18, + WinitNamedKey::F19 => Key::F19, + WinitNamedKey::F20 => Key::F20, + WinitNamedKey::F21 => Key::F21, + WinitNamedKey::F22 => Key::F22, + WinitNamedKey::F23 => Key::F23, + WinitNamedKey::F24 => Key::F24, + WinitNamedKey::F25 => Key::F25, + WinitNamedKey::F26 => Key::F26, + WinitNamedKey::F27 => Key::F27, + WinitNamedKey::F28 => Key::F28, + WinitNamedKey::F29 => Key::F29, + WinitNamedKey::F30 => Key::F30, + WinitNamedKey::F31 => Key::F31, + WinitNamedKey::F32 => Key::F32, + WinitNamedKey::F33 => Key::F33, + WinitNamedKey::F34 => Key::F34, + WinitNamedKey::F35 => Key::F35, + _ => Key::Unidentified, + }, + } +} diff --git a/packages/dioxus-blitz/src/documents/mod.rs b/packages/dioxus-blitz/src/documents/mod.rs index 27fe011f..eb80d20c 100644 --- a/packages/dioxus-blitz/src/documents/mod.rs +++ b/packages/dioxus-blitz/src/documents/mod.rs @@ -1,4 +1,5 @@ mod dioxus_document; mod event_handler; +mod keyboard_event; pub use dioxus_document::DioxusDocument;