1#[cfg(feature = "std")]
2mod distinct_reports;
3mod event_scheduler;
4pub mod hid_keyboard_reporter;
6#[cfg(feature = "std")]
7mod observed_keymap;
8
9use core::cmp::PartialEq;
10use core::fmt::Debug;
11use core::marker::Copy;
12use core::ops::Index;
13
14use serde::Deserialize;
15
16use crate::input;
17use crate::key;
18
19use key::Event;
20
21#[cfg(feature = "std")]
22pub use distinct_reports::DistinctReports;
23use event_scheduler::EventScheduler;
24use hid_keyboard_reporter::HIDKeyboardReporter;
25#[cfg(feature = "std")]
26pub use observed_keymap::ObservedKeymap;
27
28pub const MAX_PRESSED_KEYS: usize = 16;
30
31const MAX_QUEUED_INPUT_EVENTS: usize = 32;
32
33pub const INPUT_QUEUE_TICK_DELAY: u8 = 1;
35
36#[derive(Debug, PartialEq)]
38pub struct KeymapOutput {
39 pressed_key_codes: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }>,
40}
41
42impl Default for KeymapOutput {
43 fn default() -> Self {
44 Self {
45 pressed_key_codes: heapless::Vec::new(),
46 }
47 }
48}
49
50impl KeymapOutput {
51 pub fn new(pressed_key_codes: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }>) -> Self {
53 Self { pressed_key_codes }
54 }
55
56 pub fn pressed_key_codes(&self) -> heapless::Vec<u8, 24> {
58 let mut result = heapless::Vec::new();
59
60 let modifiers = self
61 .pressed_key_codes
62 .iter()
63 .fold(key::KeyboardModifiers::new(), |acc, &ko| {
64 acc.union(&ko.key_modifiers())
65 });
66
67 result.extend(modifiers.as_key_codes());
68
69 result.extend(
70 self.pressed_key_codes
71 .iter()
72 .flat_map(|ko| match ko.key_code() {
73 key::KeyUsage::Keyboard(kc) => Some(kc),
74 _ => None,
75 }),
76 );
77
78 result
79 }
80
81 pub fn as_hid_boot_keyboard_report(&self) -> [u8; 8] {
83 let mut report = [0u8; 8];
84
85 let modifiers = self
86 .pressed_key_codes
87 .iter()
88 .fold(key::KeyboardModifiers::new(), |acc, &ko| {
89 acc.union(&ko.key_modifiers())
90 });
91
92 report[0] = modifiers.as_byte();
93
94 let key_codes = self
95 .pressed_key_codes
96 .iter()
97 .flat_map(|ko| match ko.key_code() {
98 key::KeyUsage::Keyboard(kc) => Some(kc),
99 _ => None,
100 })
101 .filter(|&kc| kc != 0);
102
103 for (i, key_code) in key_codes.take(6).enumerate() {
104 report[i + 2] = key_code;
105 }
106
107 report
108 }
109
110 pub fn pressed_consumer_codes(&self) -> heapless::Vec<u8, 24> {
112 self.pressed_key_codes
113 .iter()
114 .flat_map(|ko| match ko.key_code() {
115 key::KeyUsage::Consumer(uc) => Some(uc),
116 _ => None,
117 })
118 .collect()
119 }
120
121 pub fn pressed_custom_codes(&self) -> heapless::Vec<u8, 24> {
123 self.pressed_key_codes
124 .iter()
125 .flat_map(|ko| match ko.key_code() {
126 key::KeyUsage::Custom(kc) => Some(kc),
127 _ => None,
128 })
129 .collect()
130 }
131
132 pub fn pressed_mouse_output(&self) -> key::MouseOutput {
134 self.pressed_key_codes
135 .iter()
136 .filter_map(|ko| match ko.key_code() {
137 key::KeyUsage::Mouse(mo) => Some(mo),
138 _ => None,
139 })
140 .fold(key::MouseOutput::NO_OUTPUT, |acc, mo| acc.combine(&mo))
141 }
142}
143
144#[derive(Debug)]
145struct PendingState<R, Ev, PKS> {
146 keymap_index: u16,
147 key_ref: R,
148 pending_key_state: PKS,
149 queued_events: heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
150}
151
152#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
154pub enum BluetoothProfileCommand {
155 Disconnect,
157 Clear,
159 ClearAll,
161 Previous,
163 Next,
165 Select(u8),
167}
168
169#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
171pub enum KeymapCallback {
172 Reset,
174 ResetToBootloader,
176 Bluetooth(BluetoothProfileCommand),
178 Custom(u8, u8),
180}
181
182#[derive(Debug, Clone, Copy)]
184pub struct KeymapContext {
185 pub time_ms: u32,
187
188 pub idle_time_ms: u32,
190}
191
192impl KeymapContext {
193 pub const fn new() -> Self {
195 KeymapContext {
196 time_ms: 0,
197 idle_time_ms: 0,
198 }
199 }
200}
201
202pub trait SetKeymapContext {
204 fn set_keymap_context(&mut self, context: KeymapContext);
206}
207
208#[derive(Debug, Clone, Copy, PartialEq, Eq)]
210pub enum KeymapEvent {
211 Callback(KeymapCallback),
213 ResolvedKeyOutput {
215 keymap_index: u16,
217 key_output: key::KeyOutput,
219 },
220}
221
222#[derive(Debug)]
223enum CallbackFunction {
224 ExternC(extern "C" fn() -> ()),
226 Rust(fn() -> ()),
228}
229
230pub struct Keymap<I: Index<usize, Output = R>, R, Ctx, Ev: Debug, PKS, KS, S> {
232 key_refs: I,
233 key_system: S,
234 context: Ctx,
235 pressed_inputs: heapless::Vec<input::PressedInput<R, KS>, { MAX_PRESSED_KEYS }>,
236 event_scheduler: EventScheduler<Ev>,
237 ms_per_tick: u8,
238 idle_time: u32,
239 hid_reporter: HIDKeyboardReporter,
240 pending_key_state: Option<PendingState<R, Ev, PKS>>,
241 input_queue: heapless::spsc::Queue<input::Event, { MAX_QUEUED_INPUT_EVENTS }>,
242 input_queue_delay_counter: u8,
243 callbacks: heapless::LinearMap<KeymapCallback, CallbackFunction, 2>,
244}
245
246impl<
247 I: Debug + Index<usize, Output = R>,
248 R: Debug,
249 Ctx: Debug,
250 Ev: Debug,
251 PKS: Debug,
252 KS: Debug,
253 S: Debug,
254 > core::fmt::Debug for Keymap<I, R, Ctx, Ev, PKS, KS, S>
255{
256 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
257 f.debug_struct("Keymap")
258 .field("context", &self.context)
259 .field("event_scheduler", &self.event_scheduler)
260 .field("ms_per_tick", &self.ms_per_tick)
261 .field("idle_time", &self.idle_time)
262 .field("hid_reporter", &self.hid_reporter)
263 .field("input_queue", &self.input_queue)
264 .field("input_queue_delay_counter", &self.input_queue_delay_counter)
265 .field("pending_key_state", &self.pending_key_state)
266 .field("pressed_inputs", &self.pressed_inputs)
267 .finish_non_exhaustive()
268 }
269}
270
271impl<
272 I: Debug + Index<usize, Output = R>,
273 R: Copy + Debug,
274 Ctx: Debug + key::Context<Event = Ev> + SetKeymapContext,
275 Ev: Copy + Debug,
276 PKS: Debug,
277 KS: Copy + Debug + From<key::NoOpKeyState>,
278 S: key::System<R, Ref = R, Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>,
279 > Keymap<I, R, Ctx, Ev, PKS, KS, S>
280{
281 pub const fn new(key_refs: I, context: Ctx, key_system: S) -> Self {
283 Self {
284 key_refs,
285 key_system,
286 context,
287 pressed_inputs: heapless::Vec::new(),
288 event_scheduler: EventScheduler::new(),
289 ms_per_tick: 1,
290 idle_time: 0,
291 hid_reporter: HIDKeyboardReporter::new(),
292 pending_key_state: None,
293 input_queue: heapless::spsc::Queue::new(),
294 input_queue_delay_counter: 0,
295 callbacks: heapless::LinearMap::new(),
296 }
297 }
298
299 pub fn init(&mut self) {
301 self.pressed_inputs.clear();
302 self.event_scheduler.init();
303 self.hid_reporter.init();
304 self.pending_key_state = None;
305 while !self.input_queue.is_empty() {
306 self.input_queue.dequeue().unwrap();
307 }
308 self.input_queue_delay_counter = 0;
309 self.ms_per_tick = 1;
310 self.idle_time = 0;
311 }
312
313 pub fn set_callback(&mut self, callback_id: KeymapCallback, callback_fn: fn() -> ()) {
317 self.callbacks
318 .insert(callback_id, CallbackFunction::Rust(callback_fn))
319 .unwrap();
320 }
321
322 pub fn set_callback_extern(
326 &mut self,
327 callback_id: KeymapCallback,
328 callback_fn: extern "C" fn() -> (),
329 ) {
330 self.callbacks
331 .insert(callback_id, CallbackFunction::ExternC(callback_fn))
332 .unwrap();
333 }
334
335 pub fn set_ms_per_tick(&mut self, ms_per_tick: u8) {
337 self.ms_per_tick = ms_per_tick;
338 }
339
340 fn resolve_pending_key_state(&mut self, key_state: KS) {
343 if let Some(PendingState {
344 keymap_index,
345 key_ref,
346 queued_events,
347 ..
348 }) = self.pending_key_state.take()
349 {
350 self.event_scheduler
352 .cancel_events_for_keymap_index(keymap_index);
353
354 self.pressed_inputs
356 .push(input::PressedInput::pressed_key(
357 keymap_index,
358 key_ref,
359 key_state,
360 ))
361 .unwrap();
362
363 let mut i = 1;
367 let mut old_input_queue: heapless::spsc::Queue<input::Event, MAX_QUEUED_INPUT_EVENTS> =
368 core::mem::take(&mut self.input_queue);
369
370 let (pending_input_ev, queued_events): (
374 heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
375 heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
376 ) = queued_events.iter().partition(|ev| match ev {
377 key::Event::Input(input::Event::Press {
378 keymap_index: queued_kmi,
379 }) => *queued_kmi == keymap_index,
380 key::Event::Input(input::Event::Release {
381 keymap_index: queued_kmi,
382 }) => *queued_kmi == keymap_index,
383 key::Event::Key {
384 keymap_index: queued_kmi,
385 ..
386 } => *queued_kmi == keymap_index,
387 _ => false,
388 });
389
390 for ev in queued_events.iter().chain(pending_input_ev.last()) {
391 match ev {
392 key::Event::Input(ie) => {
393 self.input_queue.enqueue(*ie).unwrap();
394 }
395 _ => {
396 self.event_scheduler.schedule_after(i, *ev);
397 i += 1;
398 }
399 }
400 }
401
402 while let Some(ie) = old_input_queue.dequeue() {
403 self.input_queue.enqueue(ie).unwrap();
404 }
405
406 self.handle_pending_events();
407
408 if let Some(key_output) = self.key_system.key_output(&key_ref, &key_state) {
410 let km_ev = KeymapEvent::ResolvedKeyOutput {
411 keymap_index,
412 key_output,
413 };
414 self.handle_event(key::Event::Keymap(km_ev));
415 }
416 }
417 }
418
419 pub fn handle_input(&mut self, ev: input::Event) {
421 self.idle_time = 0;
422
423 if self.input_queue.is_full() {
424 return;
425 }
426
427 self.input_queue.enqueue(ev).unwrap();
428
429 if self.input_queue_delay_counter == 0 {
430 let ie = self.input_queue.dequeue().unwrap();
431 self.process_input(ie);
432 self.input_queue_delay_counter = INPUT_QUEUE_TICK_DELAY;
433 }
434 }
435
436 fn has_pressed_input_with_keymap_index(&self, keymap_index: u16) -> bool {
437 self.pressed_inputs.iter().any(|pi| match pi {
438 &input::PressedInput::Key(input::PressedKey {
439 keymap_index: ki, ..
440 }) => keymap_index == ki,
441 _ => false,
442 })
443 }
444
445 fn update_pending_state(&mut self, ev: key::Event<Ev>) {
446 if let Some(PendingState {
447 keymap_index,
448 key_ref,
449 pending_key_state,
450 queued_events,
451 ..
452 }) = &mut self.pending_key_state
453 {
454 let (mut maybe_npk, pke) = self.key_system.update_pending_state(
455 pending_key_state,
456 *keymap_index,
457 &self.context,
458 *key_ref,
459 ev,
460 );
461
462 pke.into_iter()
463 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
464
465 while let Some(npk) = maybe_npk.take() {
466 let pkr = match npk {
467 key::NewPressedKey::Key(new_key_ref) => {
468 *key_ref = new_key_ref;
469 let (pkr, pke) = self.key_system.new_pressed_key(
470 *keymap_index,
471 &self.context,
472 new_key_ref,
473 );
474 pke.into_iter()
475 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
476 pkr
477 }
478 key::NewPressedKey::NoOp => {
479 let no_op_ks: KS = key::NoOpKeyState.into();
480 key::PressedKeyResult::Resolved(no_op_ks)
481 }
482 };
483
484 match pkr {
485 key::PressedKeyResult::Resolved(ks) => {
486 self.resolve_pending_key_state(ks);
487 break;
488 }
489 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(new_key_ref)) => {
490 maybe_npk = Some(key::NewPressedKey::Key(new_key_ref));
491 }
492 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp) => {
493 self.resolve_pending_key_state(key::NoOpKeyState.into());
494 break;
495 }
496 key::PressedKeyResult::Pending(pks) => {
497 *pending_key_state = pks;
498
499 let orig_input_queue = core::mem::take(&mut self.input_queue);
502 while let Some(ev) = queued_events.pop() {
503 if let key::Event::Input(input_ev) = ev {
504 self.input_queue.enqueue(input_ev).unwrap();
505 }
506 }
507 orig_input_queue.iter().for_each(|&ev| {
508 self.input_queue.enqueue(ev).unwrap();
509 });
510 }
511 }
512 }
513 }
514 }
515
516 fn process_input(&mut self, ev: input::Event) {
517 if let Some(pending_state) = &mut self.pending_key_state {
518 pending_state.queued_events.push(ev.into()).unwrap();
519 self.update_pending_state(ev.into());
520 } else {
521 self.pressed_inputs.iter_mut().for_each(|pi| {
523 if let input::PressedInput::Key(input::PressedKey {
524 key_ref,
525 key_state,
526 keymap_index,
527 }) = pi
528 {
529 self.key_system
530 .update_state(key_state, key_ref, &self.context, *keymap_index, ev.into())
531 .into_iter()
532 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
533 }
534 });
535
536 self.context
537 .handle_event(ev.into())
538 .into_iter()
539 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
540
541 match ev {
542 input::Event::Press { keymap_index }
543 if !self.has_pressed_input_with_keymap_index(keymap_index) =>
544 {
545 let mut maybe_key_ref = Some(self.key_refs[keymap_index as usize]);
546
547 while let Some(key_ref) = maybe_key_ref.take() {
548 let (pkr, pke) =
549 self.key_system
550 .new_pressed_key(keymap_index, &self.context, key_ref);
551
552 pke.into_iter()
553 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
554
555 match pkr {
556 key::PressedKeyResult::Resolved(key_state) => {
557 self.pressed_inputs
558 .push(input::PressedInput::pressed_key(
559 keymap_index,
560 key_ref,
561 key_state,
562 ))
563 .unwrap();
564
565 if let Some(key_output) =
567 self.key_system.key_output(&key_ref, &key_state)
568 {
569 let km_ev = KeymapEvent::ResolvedKeyOutput {
570 keymap_index,
571 key_output,
572 };
573 self.handle_event(key::Event::Keymap(km_ev));
574 }
575 }
576 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(
577 new_key_ref,
578 )) => {
579 maybe_key_ref = Some(new_key_ref);
580 }
581 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp) => {
582 let key_state: KS = key::NoOpKeyState.into();
583
584 self.pressed_inputs
585 .push(input::PressedInput::pressed_key(
586 keymap_index,
587 key_ref,
588 key_state,
589 ))
590 .unwrap();
591 }
592 key::PressedKeyResult::Pending(pending_key_state) => {
593 self.pending_key_state = Some(PendingState {
594 keymap_index,
595 key_ref,
596 pending_key_state,
597 queued_events: heapless::Vec::new(),
598 });
599 }
600 }
601 }
602 }
603 input::Event::Release { keymap_index } => {
604 self.pressed_inputs
605 .iter()
606 .position(|pi| match pi {
607 &input::PressedInput::Key(input::PressedKey {
608 keymap_index: ki,
609 ..
610 }) => keymap_index == ki,
611 _ => false,
612 })
613 .map(|i| self.pressed_inputs.remove(i));
614 }
615
616 input::Event::VirtualKeyPress { key_output } => {
617 let pressed_key = input::PressedInput::Virtual(key_output);
618 self.pressed_inputs.push(pressed_key).unwrap();
619 }
620 input::Event::VirtualKeyRelease { key_output } => {
621 self.pressed_inputs
623 .iter()
624 .position(|k| match k {
625 input::PressedInput::Virtual(ko) => key_output == *ko,
626 _ => false,
627 })
628 .map(|i| self.pressed_inputs.remove(i));
629 }
630
631 _ => {}
632 }
633 }
634
635 self.handle_pending_events();
636 }
637
638 fn handle_event(&mut self, ev: key::Event<Ev>) {
641 if let key::Event::Keymap(KeymapEvent::Callback(callback_id)) = ev {
642 match self.callbacks.get(&callback_id) {
643 Some(CallbackFunction::Rust(callback_fn)) => {
644 callback_fn();
645 }
646 Some(CallbackFunction::ExternC(callback_fn)) => {
647 callback_fn();
648 }
649 None => {}
650 }
651 }
652
653 self.update_pending_state(ev);
655
656 self.pressed_inputs.iter_mut().for_each(|pi| {
658 if let input::PressedInput::Key(input::PressedKey {
659 key_state,
660 key_ref,
661 keymap_index,
662 }) = pi
663 {
664 self.key_system
665 .update_state(key_state, key_ref, &self.context, *keymap_index, ev)
666 .into_iter()
667 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
668 }
669 });
670
671 self.context
673 .handle_event(ev)
674 .into_iter()
675 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
676
677 if let Event::Input(input_ev) = ev {
678 self.process_input(input_ev);
679 }
680 }
681
682 fn handle_pending_events(&mut self) {
683 while let Some(ev) = self.event_scheduler.dequeue() {
685 self.handle_event(ev);
686 }
687 }
688
689 pub fn tick(&mut self) {
691 let km_context = KeymapContext {
692 time_ms: self.event_scheduler.schedule_counter,
693 idle_time_ms: self.idle_time,
694 };
695 self.context.set_keymap_context(km_context);
696
697 if !self.input_queue.is_empty() && self.input_queue_delay_counter == 0 {
698 let ie = self.input_queue.dequeue().unwrap();
699 self.process_input(ie);
700 self.input_queue_delay_counter = INPUT_QUEUE_TICK_DELAY;
701 }
702
703 if self.input_queue_delay_counter > 0 {
704 self.input_queue_delay_counter -= 1;
705 }
706
707 self.event_scheduler.tick(self.ms_per_tick);
708
709 self.handle_pending_events();
710
711 self.idle_time += self.ms_per_tick as u32;
712 }
713
714 pub fn pressed_keys(&self) -> heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> {
716 let pressed_key_codes = self.pressed_inputs.iter().filter_map(|pi| match pi {
717 input::PressedInput::Key(input::PressedKey {
718 key_ref, key_state, ..
719 }) => self.key_system.key_output(key_ref, key_state),
720 &input::PressedInput::Virtual(key_output) => Some(key_output),
721 });
722
723 pressed_key_codes.collect()
724 }
725
726 pub fn report_output(&mut self) -> KeymapOutput {
728 self.hid_reporter.update(self.pressed_keys());
729 self.hid_reporter.report_sent();
730
731 KeymapOutput::new(self.hid_reporter.reportable_key_outputs())
732 }
733
734 #[doc(hidden)]
736 pub fn boot_keyboard_report(&self) -> [u8; 8] {
737 KeymapOutput::new(self.pressed_keys()).as_hid_boot_keyboard_report()
738 }
739
740 #[doc(hidden)]
741 pub fn has_scheduled_events(&self) -> bool {
742 !self.event_scheduler.pending_events.is_empty()
743 || !self.event_scheduler.scheduled_events.is_empty()
744 || !self.input_queue.is_empty()
745 }
746}
747
748#[cfg(test)]
749mod tests {
750 use super::*;
751
752 #[test]
753 fn test_keymap_output_pressed_key_codes_includes_modifier_key_code() {
754 let mut input: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> = heapless::Vec::new();
756 input.push(key::KeyOutput::from_key_code(0x04)).unwrap();
757 input.push(key::KeyOutput::from_key_code(0xE0)).unwrap();
758
759 let keymap_output = KeymapOutput::new(input);
761 let pressed_key_codes = keymap_output.pressed_key_codes();
762
763 assert!(pressed_key_codes.contains(&0xE0))
765 }
766
767 #[test]
768 fn test_keymap_output_as_hid_boot_keyboard_report_gathers_modifiers() {
769 let mut input: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> = heapless::Vec::new();
771 input.push(key::KeyOutput::from_key_code(0x04)).unwrap();
772 input.push(key::KeyOutput::from_key_code(0xE0)).unwrap();
773
774 let keymap_output = KeymapOutput::new(input);
776 let actual_report: [u8; 8] = keymap_output.as_hid_boot_keyboard_report();
777
778 let expected_report: [u8; 8] = [0x01, 0, 0x04, 0, 0, 0, 0, 0];
780 assert_eq!(expected_report, actual_report);
781 }
782
783 #[test]
784 fn test_keymap_many_input_events_without_tick_or_report() {
785 let mut keymap = {
787 use crate as smart_keymap;
788 use smart_keymap::key::composite as key_system;
789
790 use key_system::Context;
791 use key_system::Ref;
792 const KEY_COUNT: usize = 1;
793 const KEY_REFS: [Ref; KEY_COUNT] = [smart_keymap::key::composite::Ref::Keyboard(
794 smart_keymap::key::keyboard::Ref::KeyCode(0x04),
795 )];
796 const CONTEXT: Context = Context::from_config(key_system::Config::new());
797
798 smart_keymap::keymap::Keymap::new(
799 KEY_REFS,
800 CONTEXT,
801 smart_keymap::key::composite::System::array_based(
802 smart_keymap::key::automation::System::new([]),
803 smart_keymap::key::callback::System::new([]),
804 smart_keymap::key::chorded::System::new([], []),
805 smart_keymap::key::keyboard::System::new([]),
806 smart_keymap::key::layered::System::new([], []),
807 smart_keymap::key::sticky::System::new([]),
808 smart_keymap::key::tap_dance::System::new([]),
809 smart_keymap::key::tap_hold::System::new([]),
810 ),
811 )
812 };
813
814 for _ in 0..100 {
816 keymap.handle_input(input::Event::Press { keymap_index: 0 });
817 keymap.handle_input(input::Event::Release { keymap_index: 0 });
818 }
819
820 }
823}