1use core::fmt::Debug;
2
3use serde::{Deserialize, Serialize};
4
5use crate::input;
6
7pub mod automation;
9pub mod callback;
11pub mod caps_word;
13pub mod chorded;
15pub mod consumer;
17pub mod custom;
19pub mod history;
21pub mod keyboard;
23pub mod layered;
25pub mod mouse;
27pub mod sticky;
29pub mod tap_dance;
31pub mod tap_hold;
33
34pub const MAX_KEY_EVENTS: usize = 4;
36
37#[derive(Debug, PartialEq, Eq)]
39pub struct KeyEvents<E, const M: usize = { MAX_KEY_EVENTS }>(heapless::Vec<ScheduledEvent<E>, M>);
40
41impl<E: Copy + Debug> KeyEvents<E> {
42 pub fn no_events() -> Self {
44 KeyEvents(None.into_iter().collect())
45 }
46
47 pub fn event(event: Event<E>) -> Self {
49 KeyEvents(Some(ScheduledEvent::immediate(event)).into_iter().collect())
50 }
51
52 pub fn scheduled_event(sch_event: ScheduledEvent<E>) -> Self {
54 KeyEvents(Some(sch_event).into_iter().collect())
55 }
56
57 pub fn schedule_event(&mut self, delay: u16, event: Event<E>) {
59 let _ = self.0.push(ScheduledEvent::after(delay, event));
60 }
61
62 pub fn extend(&mut self, other: KeyEvents<E>) {
64 other.0.into_iter().for_each(|ev| {
65 let _ = self.0.push(ev);
66 });
67 }
68
69 pub fn add_event(&mut self, ev: ScheduledEvent<E>) {
71 let _ = self.0.push(ev);
72 }
73
74 pub fn map_events<F>(&self, f: fn(E) -> F) -> KeyEvents<F> {
76 KeyEvents(
77 self.0
78 .as_slice()
79 .iter()
80 .map(|sch_ev| sch_ev.map_scheduled_event(f))
81 .collect(),
82 )
83 }
84
85 pub fn into_events<F>(&self) -> KeyEvents<F>
87 where
88 E: Into<F>,
89 {
90 KeyEvents(
91 self.0
92 .as_slice()
93 .iter()
94 .map(|sch_ev| sch_ev.map_scheduled_event(|ev| ev.into()))
95 .collect(),
96 )
97 }
98}
99
100impl<E: Debug, const M: usize> IntoIterator for KeyEvents<E, M> {
101 type Item = ScheduledEvent<E>;
102 type IntoIter = <heapless::Vec<ScheduledEvent<E>, M> as IntoIterator>::IntoIter;
103
104 fn into_iter(self) -> Self::IntoIter {
105 self.0.into_iter()
106 }
107}
108
109#[derive(Debug, PartialEq)]
111pub enum NewPressedKey<R> {
112 Key(R),
114 NoOp,
116}
117
118impl<R> NewPressedKey<R> {
119 pub fn key(key_ref: R) -> Self {
121 NewPressedKey::Key(key_ref)
122 }
123
124 pub fn no_op() -> Self {
126 NewPressedKey::NoOp
127 }
128
129 pub fn map<TR>(self, f: fn(R) -> TR) -> NewPressedKey<TR> {
131 match self {
132 NewPressedKey::Key(r) => NewPressedKey::Key(f(r)),
133 NewPressedKey::NoOp => NewPressedKey::NoOp,
134 }
135 }
136}
137
138#[derive(Debug, PartialEq)]
140pub enum PressedKeyResult<R, PKS, KS> {
141 Pending(PKS),
143 NewPressedKey(NewPressedKey<R>),
145 Resolved(KS),
147}
148
149impl<R, PKS, KS> PressedKeyResult<R, PKS, KS> {
150 #[cfg(feature = "std")]
152 pub fn unwrap_resolved(self) -> KS {
153 match self {
154 PressedKeyResult::Resolved(r) => r,
155 _ => panic!("PressedKeyResult::unwrap_resolved: not Resolved"),
156 }
157 }
158
159 pub fn map<TPKS, TKS>(
161 self,
162 f: fn(PKS) -> TPKS,
163 g: fn(KS) -> TKS,
164 ) -> PressedKeyResult<R, TPKS, TKS> {
165 match self {
166 PressedKeyResult::Pending(pks) => PressedKeyResult::Pending(f(pks)),
167 PressedKeyResult::NewPressedKey(npk) => PressedKeyResult::NewPressedKey(npk),
168 PressedKeyResult::Resolved(ks) => PressedKeyResult::Resolved(g(ks)),
169 }
170 }
171
172 pub fn into_result<TPKS, TKS>(self) -> PressedKeyResult<R, TPKS, TKS>
174 where
175 PKS: Into<TPKS>,
176 KS: Into<TKS>,
177 {
178 self.map(|pks| pks.into(), |ks| ks.into())
179 }
180}
181
182pub type NewPressedKeyOutput<R, PKS, KS, E> = (PressedKeyResult<R, PKS, KS>, KeyEvents<E>);
184
185pub trait System<R>: Debug {
194 type Ref: Copy;
196
197 type Context: Copy;
202
203 type Event: Copy + Debug + PartialEq;
206
207 type PendingKeyState;
209
210 type KeyState;
212
213 fn new_pressed_key(
219 &self,
220 keymap_index: u16,
221 context: &Self::Context,
222 key_ref: Self::Ref,
223 ) -> NewPressedKeyOutput<R, Self::PendingKeyState, Self::KeyState, Self::Event>;
224
225 fn update_pending_state(
227 &self,
228 pending_state: &mut Self::PendingKeyState,
229 keymap_index: u16,
230 context: &Self::Context,
231 key_ref: Self::Ref,
232 event: Event<Self::Event>,
233 ) -> (Option<NewPressedKey<R>>, KeyEvents<Self::Event>);
234
235 fn update_state(
237 &self,
238 _key_state: &mut Self::KeyState,
239 _ref: &Self::Ref,
240 _context: &Self::Context,
241 _keymap_index: u16,
242 _event: Event<Self::Event>,
243 ) -> KeyEvents<Self::Event> {
244 KeyEvents::no_events()
245 }
246
247 fn key_output(&self, _ref: &Self::Ref, _key_state: &Self::KeyState) -> Option<KeyOutput> {
249 None
250 }
251}
252
253pub trait Context: Clone + Copy {
258 type Event;
260
261 fn handle_event(&mut self, event: Event<Self::Event>) -> KeyEvents<Self::Event>;
263
264 fn reset(&mut self);
269}
270
271#[derive(Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
273pub struct KeyboardModifiers(u8);
274
275impl core::ops::Deref for KeyboardModifiers {
276 type Target = u8;
277
278 fn deref(&self) -> &Self::Target {
279 &self.0
280 }
281}
282
283impl core::fmt::Debug for KeyboardModifiers {
284 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
285 let mut ds = f.debug_struct("KeyboardModifiers");
286 if self.0 & Self::LEFT_CTRL_U8 != 0 {
287 ds.field("left_ctrl", &true);
288 }
289 if self.0 & Self::LEFT_SHIFT_U8 != 0 {
290 ds.field("left_shift", &true);
291 }
292 if self.0 & Self::LEFT_ALT_U8 != 0 {
293 ds.field("left_alt", &true);
294 }
295 if self.0 & Self::LEFT_GUI_U8 != 0 {
296 ds.field("left_gui", &true);
297 }
298 if self.0 & Self::RIGHT_CTRL_U8 != 0 {
299 ds.field("right_ctrl", &true);
300 }
301 if self.0 & Self::RIGHT_SHIFT_U8 != 0 {
302 ds.field("right_shift", &true);
303 }
304 if self.0 & Self::RIGHT_ALT_U8 != 0 {
305 ds.field("right_alt", &true);
306 }
307 if self.0 & Self::RIGHT_GUI_U8 != 0 {
308 ds.field("right_gui", &true);
309 }
310 ds.finish_non_exhaustive()
311 }
312}
313
314impl KeyboardModifiers {
315 pub const LEFT_CTRL_U8: u8 = 0x01;
317 pub const LEFT_SHIFT_U8: u8 = 0x02;
319 pub const LEFT_ALT_U8: u8 = 0x04;
321 pub const LEFT_GUI_U8: u8 = 0x08;
323 pub const RIGHT_CTRL_U8: u8 = 0x10;
325 pub const RIGHT_SHIFT_U8: u8 = 0x20;
327 pub const RIGHT_ALT_U8: u8 = 0x40;
329 pub const RIGHT_GUI_U8: u8 = 0x80;
331
332 pub const fn new() -> Self {
334 KeyboardModifiers(0x00)
335 }
336
337 pub const fn from_byte(b: u8) -> Self {
339 KeyboardModifiers(b)
340 }
341
342 pub const fn from_key_code(key_code: u8) -> Option<Self> {
346 match key_code {
347 0xE0 => Some(Self::LEFT_CTRL),
348 0xE1 => Some(Self::LEFT_SHIFT),
349 0xE2 => Some(Self::LEFT_ALT),
350 0xE3 => Some(Self::LEFT_GUI),
351 0xE4 => Some(Self::RIGHT_CTRL),
352 0xE5 => Some(Self::RIGHT_SHIFT),
353 0xE6 => Some(Self::RIGHT_ALT),
354 0xE7 => Some(Self::RIGHT_GUI),
355 _ => None,
356 }
357 }
358
359 pub const NONE: KeyboardModifiers = KeyboardModifiers {
361 ..KeyboardModifiers::new()
362 };
363
364 pub const LEFT_CTRL: KeyboardModifiers = KeyboardModifiers(Self::LEFT_CTRL_U8);
366
367 pub const LEFT_SHIFT: KeyboardModifiers = KeyboardModifiers(Self::LEFT_SHIFT_U8);
369
370 pub const LEFT_ALT: KeyboardModifiers = KeyboardModifiers(Self::LEFT_ALT_U8);
372
373 pub const LEFT_GUI: KeyboardModifiers = KeyboardModifiers(Self::LEFT_GUI_U8);
375
376 pub const RIGHT_CTRL: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_CTRL_U8);
378
379 pub const RIGHT_SHIFT: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_SHIFT_U8);
381
382 pub const RIGHT_ALT: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_ALT_U8);
384
385 pub const RIGHT_GUI: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_GUI_U8);
387
388 pub const fn is_modifier_key_code(key_code: u8) -> bool {
390 matches!(key_code, 0xE0..=0xE7)
391 }
392
393 pub fn as_key_codes(&self) -> heapless::Vec<u8, 8> {
395 let mut key_codes = heapless::Vec::new();
396
397 if self.0 & Self::LEFT_CTRL_U8 != 0 {
398 let _ = key_codes.push(0xE0);
399 }
400 if self.0 & Self::LEFT_SHIFT_U8 != 0 {
401 let _ = key_codes.push(0xE1);
402 }
403 if self.0 & Self::LEFT_ALT_U8 != 0 {
404 let _ = key_codes.push(0xE2);
405 }
406 if self.0 & Self::LEFT_GUI_U8 != 0 {
407 let _ = key_codes.push(0xE3);
408 }
409 if self.0 & Self::RIGHT_CTRL_U8 != 0 {
410 let _ = key_codes.push(0xE4);
411 }
412 if self.0 & Self::RIGHT_SHIFT_U8 != 0 {
413 let _ = key_codes.push(0xE5);
414 }
415 if self.0 & Self::RIGHT_ALT_U8 != 0 {
416 let _ = key_codes.push(0xE6);
417 }
418 if self.0 & Self::RIGHT_GUI_U8 != 0 {
419 let _ = key_codes.push(0xE7);
420 }
421
422 key_codes
423 }
424
425 pub fn as_byte(&self) -> u8 {
427 self.as_key_codes()
428 .iter()
429 .fold(0u8, |acc, &kc| acc | (1 << (kc - 0xE0)))
430 }
431
432 pub const fn union(&self, other: &KeyboardModifiers) -> KeyboardModifiers {
434 KeyboardModifiers(self.0 | other.0)
435 }
436
437 pub const fn has_modifiers(&self, other: &KeyboardModifiers) -> bool {
439 self.0 & other.0 != 0
440 }
441}
442
443#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
445pub enum KeyUsage {
446 Keyboard(u8),
448 Consumer(u8),
450 Custom(u8),
452 Mouse(MouseOutput),
454}
455
456impl KeyUsage {
457 pub const NO_USAGE: KeyUsage = KeyUsage::Keyboard(0x00);
459}
460
461impl Default for KeyUsage {
462 fn default() -> Self {
463 KeyUsage::NO_USAGE
464 }
465}
466
467#[derive(Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
469pub struct KeyOutput {
470 #[serde(default)]
471 key_code: KeyUsage,
472 #[serde(default)]
473 key_modifiers: KeyboardModifiers,
474}
475
476impl core::fmt::Debug for KeyOutput {
477 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
478 match (
479 self.key_code != KeyUsage::NO_USAGE,
480 self.key_modifiers != KeyboardModifiers::NONE,
481 ) {
482 (true, true) => f
483 .debug_struct("KeyOutput")
484 .field("key_code", &self.key_code)
485 .field("key_modifiers", &self.key_modifiers)
486 .finish(),
487 (false, true) => f
488 .debug_struct("KeyOutput")
489 .field("key_modifiers", &self.key_modifiers)
490 .finish(),
491 _ => f
492 .debug_struct("KeyOutput")
493 .field("key_code", &self.key_code)
494 .finish(),
495 }
496 }
497}
498
499impl KeyOutput {
500 pub const NO_OUTPUT: KeyOutput = KeyOutput {
502 key_code: KeyUsage::Keyboard(0x00),
503 key_modifiers: KeyboardModifiers::new(),
504 };
505
506 pub const fn from_usage(key_usage: KeyUsage) -> Self {
508 match key_usage {
509 KeyUsage::Keyboard(kc) => Self::from_key_code(kc),
510 KeyUsage::Consumer(cc) => Self::from_consumer_code(cc),
511 KeyUsage::Custom(cu) => Self::from_custom_code(cu),
512 KeyUsage::Mouse(mo) => Self::from_mouse_output(mo),
513 }
514 }
515
516 pub const fn from_usage_with_modifiers(
518 key_usage: KeyUsage,
519 key_modifiers: KeyboardModifiers,
520 ) -> Self {
521 match key_usage {
522 KeyUsage::Keyboard(kc) => {
523 if let Some(usage_key_modifiers) = KeyboardModifiers::from_key_code(kc) {
524 KeyOutput {
525 key_code: KeyUsage::Keyboard(0x00),
526 key_modifiers: usage_key_modifiers.union(&key_modifiers),
527 }
528 } else {
529 KeyOutput {
530 key_code: KeyUsage::Keyboard(kc),
531 key_modifiers,
532 }
533 }
534 }
535 _ => KeyOutput {
536 key_code: key_usage,
537 key_modifiers,
538 },
539 }
540 }
541
542 pub const fn from_key_code(key_code: u8) -> Self {
544 if let Some(key_modifiers) = KeyboardModifiers::from_key_code(key_code) {
545 KeyOutput {
546 key_code: KeyUsage::Keyboard(0x00),
547 key_modifiers,
548 }
549 } else {
550 KeyOutput {
551 key_code: KeyUsage::Keyboard(key_code),
552 key_modifiers: KeyboardModifiers::new(),
553 }
554 }
555 }
556
557 pub const fn from_key_code_with_modifiers(
559 key_code: u8,
560 key_modifiers: KeyboardModifiers,
561 ) -> Self {
562 let KeyOutput {
563 key_code,
564 key_modifiers: km,
565 } = Self::from_key_code(key_code);
566 KeyOutput {
567 key_code,
568 key_modifiers: km.union(&key_modifiers),
569 }
570 }
571
572 pub const fn from_key_modifiers(key_modifiers: KeyboardModifiers) -> Self {
574 KeyOutput {
575 key_code: KeyUsage::Keyboard(0x00),
576 key_modifiers,
577 }
578 }
579
580 pub const fn from_consumer_code(usage_code: u8) -> Self {
582 KeyOutput {
583 key_code: KeyUsage::Consumer(usage_code),
584 key_modifiers: KeyboardModifiers::new(),
585 }
586 }
587
588 pub const fn from_custom_code(custom_code: u8) -> Self {
590 KeyOutput {
591 key_code: KeyUsage::Custom(custom_code),
592 key_modifiers: KeyboardModifiers::new(),
593 }
594 }
595
596 pub const fn from_mouse_output(mouse_output: MouseOutput) -> Self {
598 KeyOutput {
599 key_code: KeyUsage::Mouse(mouse_output),
600 key_modifiers: KeyboardModifiers::new(),
601 }
602 }
603
604 pub const fn key_code(&self) -> KeyUsage {
606 self.key_code
607 }
608
609 pub const fn key_modifiers(&self) -> KeyboardModifiers {
611 self.key_modifiers
612 }
613}
614
615#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
617pub struct MouseOutput {
618 pub pressed_buttons: u8,
620 pub x: i8,
622 pub y: i8,
624 pub vertical_scroll: i8,
626 pub horizontal_scroll: i8,
628}
629
630impl MouseOutput {
631 pub const NO_OUTPUT: MouseOutput = MouseOutput {
633 pressed_buttons: 0,
634 x: 0,
635 y: 0,
636 vertical_scroll: 0,
637 horizontal_scroll: 0,
638 };
639
640 pub fn combine(&self, other: &Self) -> Self {
642 Self {
643 pressed_buttons: self.pressed_buttons | other.pressed_buttons,
644 x: self.x.saturating_add(other.x),
645 y: self.y.saturating_add(other.y),
646 vertical_scroll: self.vertical_scroll.saturating_add(other.vertical_scroll),
647 horizontal_scroll: self
648 .horizontal_scroll
649 .saturating_add(other.horizontal_scroll),
650 }
651 }
652}
653
654pub trait KeyState: Debug {
656 type Context;
658 type Event: Copy + Debug;
660
661 fn handle_event(
663 &mut self,
664 _context: &Self::Context,
665 _keymap_index: u16,
666 _event: Event<Self::Event>,
667 ) -> KeyEvents<Self::Event> {
668 KeyEvents::no_events()
669 }
670
671 fn key_output(&self) -> Option<KeyOutput> {
673 None
674 }
675}
676
677#[derive(Debug, Clone, Copy, PartialEq, Eq)]
679pub struct NoOpKeyState;
680
681#[allow(unused)]
683pub enum EventError {
684 UnmappableEvent,
688}
689
690type EventResult<T> = Result<T, EventError>;
692
693#[derive(Debug, Clone, Copy, PartialEq, Eq)]
698pub enum Event<T> {
699 Input(input::Event),
701 Key {
703 keymap_index: u16,
705 key_event: T,
707 },
708 Keymap(crate::keymap::KeymapEvent),
710}
711
712impl<T: Copy> Event<T> {
713 pub fn key_event(keymap_index: u16, key_event: T) -> Self {
715 Event::Key {
716 keymap_index,
717 key_event,
718 }
719 }
720
721 pub fn map_key_event<U>(self, f: fn(T) -> U) -> Event<U> {
723 match self {
724 Event::Input(event) => Event::Input(event),
725 Event::Key {
726 key_event,
727 keymap_index,
728 } => Event::Key {
729 key_event: f(key_event),
730 keymap_index,
731 },
732 Event::Keymap(cb) => Event::Keymap(cb),
733 }
734 }
735
736 pub fn into_key_event<U>(self) -> Event<U>
738 where
739 T: Into<U>,
740 {
741 self.map_key_event(|ke| ke.into())
742 }
743
744 pub fn try_into_key_event<U, E>(self) -> EventResult<Event<U>>
746 where
747 T: TryInto<U, Error = E>,
748 {
749 match self {
750 Event::Input(event) => Ok(Event::Input(event)),
751 Event::Key {
752 key_event,
753 keymap_index,
754 } => key_event
755 .try_into()
756 .map(|key_event| Event::Key {
757 key_event,
758 keymap_index,
759 })
760 .map_err(|_| EventError::UnmappableEvent),
761 Event::Keymap(cb) => Ok(Event::Keymap(cb)),
762 }
763 }
764
765 pub(crate) fn targets_keymap_index(&self, keymap_index: u16) -> bool {
770 match self {
771 Event::Input(input::Event::Press {
772 keymap_index: queued_kmi,
773 })
774 | Event::Input(input::Event::Release {
775 keymap_index: queued_kmi,
776 }) => *queued_kmi == keymap_index,
777 Event::Key {
778 keymap_index: queued_kmi,
779 ..
780 } => *queued_kmi == keymap_index,
781 _ => false,
782 }
783 }
784}
785
786pub(crate) fn pending_resolution_events<Ev: Copy, const N: usize>(
798 queued_events: &heapless::Vec<Event<Ev>, N>,
799 keymap_index: u16,
800) -> heapless::Vec<Event<Ev>, N> {
801 let (self_events, other_events): (heapless::Vec<Event<Ev>, N>, heapless::Vec<Event<Ev>, N>) =
802 queued_events
803 .iter()
804 .partition(|ev| ev.targets_keymap_index(keymap_index));
805
806 let mut result = heapless::Vec::new();
807 for ev in other_events.iter().chain(self_events.last()) {
808 let _ = result.push(*ev);
809 }
810 result
811}
812
813impl<T> From<input::Event> for Event<T> {
814 fn from(event: input::Event) -> Self {
815 Event::Input(event)
816 }
817}
818
819#[allow(unused)]
821#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
822pub enum Schedule {
823 Immediate,
825 After(u16),
827}
828
829#[derive(Debug, Clone, Copy, PartialEq, Eq)]
831pub struct ScheduledEvent<T> {
832 pub schedule: Schedule,
834 pub event: Event<T>,
836}
837
838impl<T: Copy> ScheduledEvent<T> {
839 #[allow(unused)]
841 pub fn immediate(event: Event<T>) -> Self {
842 ScheduledEvent {
843 schedule: Schedule::Immediate,
844 event,
845 }
846 }
847
848 pub fn after(delay: u16, event: Event<T>) -> Self {
850 ScheduledEvent {
851 schedule: Schedule::After(delay),
852 event,
853 }
854 }
855
856 pub fn map_scheduled_event<U>(self, f: fn(T) -> U) -> ScheduledEvent<U> {
858 ScheduledEvent {
859 event: self.event.map_key_event(f),
860 schedule: self.schedule,
861 }
862 }
863
864 pub fn into_scheduled_event<U>(self) -> ScheduledEvent<U>
866 where
867 T: Into<U>,
868 {
869 self.map_scheduled_event(|e| e.into())
870 }
871}
872
873#[cfg(test)]
874#[allow(clippy::unwrap_used, clippy::expect_used)]
875mod tests {
876 use super::*;
877
878 #[test]
879 fn pending_resolution_events_empty_returns_empty() {
880 let queued: heapless::Vec<Event<()>, 16> = heapless::Vec::new();
881 let result = pending_resolution_events(&queued, 0);
882 assert!(result.is_empty());
883 }
884
885 #[test]
886 fn pending_resolution_events_other_key_events_all_included() {
887 let mut queued: heapless::Vec<Event<()>, 16> = heapless::Vec::new();
888 queued.push(input::Event::press(1).into()).unwrap();
889 queued.push(input::Event::release(2).into()).unwrap();
890 let result = pending_resolution_events(&queued, 0);
891 assert_eq!(2, result.len());
892 }
893
894 #[test]
895 fn pending_resolution_events_resolving_key_only_last_included() {
896 let mut queued: heapless::Vec<Event<()>, 16> = heapless::Vec::new();
897 queued.push(input::Event::press(0).into()).unwrap();
898 queued.push(input::Event::release(0).into()).unwrap();
899 let result = pending_resolution_events(&queued, 0);
900 assert_eq!(1, result.len());
901 assert_eq!(Event::from(input::Event::release(0)), result[0]);
902 }
903
904 #[test]
905 fn pending_resolution_events_mix_other_and_resolving_key() {
906 let mut queued: heapless::Vec<Event<()>, 16> = heapless::Vec::new();
907 queued.push(input::Event::press(1).into()).unwrap();
908 queued.push(input::Event::press(0).into()).unwrap();
909 queued.push(input::Event::release(0).into()).unwrap();
910 let result = pending_resolution_events(&queued, 0);
911 assert_eq!(2, result.len());
912 assert_eq!(Event::from(input::Event::press(1)), result[0]);
913 assert_eq!(Event::from(input::Event::release(0)), result[1]);
914 }
915}