@@ -49,6 +49,7 @@ pub use keyberon_macros::*;
49
49
use crate :: action:: { Action , HoldTapAction , HoldTapConfig , SequenceEvent } ;
50
50
use crate :: key_code:: KeyCode ;
51
51
use arraydeque:: ArrayDeque ;
52
+ use core:: convert:: TryFrom ;
52
53
use heapless:: Vec ;
53
54
54
55
use State :: * ;
@@ -326,7 +327,38 @@ impl<'a> Iterator for StackedIter<'a> {
326
327
}
327
328
328
329
#[ derive( Debug , Copy , Clone ) ]
329
- struct SequenceState < K : ' static > {
330
+ /// Enum to save a state that represents a key pressed
331
+ enum SavedKeyCodeState < K : ' static + Copy > {
332
+ /// Key pressed
333
+ NormalKey { keycode : K , coord : ( u8 , u8 ) } ,
334
+ /// Fake key event for sequences
335
+ FakeKey { keycode : K } ,
336
+ }
337
+
338
+ impl < T : ' static , K : ' static + Copy + Eq > From < SavedKeyCodeState < K > > for State < T , K > {
339
+ /// Convert a [`SavedKeyCodeState`] into a [`State`]
340
+ fn from ( saved : SavedKeyCodeState < K > ) -> Self {
341
+ match saved {
342
+ SavedKeyCodeState :: NormalKey { keycode, coord } => Self :: NormalKey { keycode, coord } ,
343
+ SavedKeyCodeState :: FakeKey { keycode } => Self :: FakeKey { keycode } ,
344
+ }
345
+ }
346
+ }
347
+
348
+ impl < T : ' static , K : ' static + Copy > TryFrom < State < T , K > > for SavedKeyCodeState < K > {
349
+ type Error = & ' static str ;
350
+ /// Try to convert a [`State`] into a [`SavedKeyCodeState`]
351
+ fn try_from ( state : State < T , K > ) -> Result < Self , Self :: Error > {
352
+ match state {
353
+ NormalKey { keycode, coord } => Ok ( Self :: NormalKey { keycode, coord } ) ,
354
+ FakeKey { keycode } => Ok ( Self :: FakeKey { keycode } ) ,
355
+ _ => Err ( "Unsupported State conversion to SavedKeyCodeState" ) ,
356
+ }
357
+ }
358
+ }
359
+
360
+ #[ derive( Debug , Copy , Clone ) ]
361
+ struct SequenceState < K : ' static + Copy > {
330
362
/// Current event being processed
331
363
cur_event : Option < SequenceEvent < K > > ,
332
364
/// Remaining events to process
@@ -335,6 +367,8 @@ struct SequenceState<K: 'static> {
335
367
delay : u32 ,
336
368
/// Keycode of a key that should be released at the next tick
337
369
tapped : Option < K > ,
370
+ /// Keys filtered that can be restored later
371
+ to_restore : [ Option < SavedKeyCodeState < K > > ; 64 ] ,
338
372
}
339
373
340
374
impl < K : Copy > Default for SequenceState < K > {
@@ -344,6 +378,23 @@ impl<K: Copy> Default for SequenceState<K> {
344
378
remaining_events : & [ ] ,
345
379
delay : 0 ,
346
380
tapped : None ,
381
+ to_restore : [ None ; 64 ] ,
382
+ }
383
+ }
384
+ }
385
+ impl < K : Copy > SequenceState < K > {
386
+ fn add_to_restore < T > ( & mut self , s : State < T , K > ) {
387
+ for e in self . to_restore . iter_mut ( ) {
388
+ if e. is_none ( ) {
389
+ match s {
390
+ NormalKey { .. } | FakeKey { .. } => {
391
+ let saved = SavedKeyCodeState :: < K > :: try_from ( s) ;
392
+ * e = Some ( saved. unwrap ( ) ) ;
393
+ }
394
+ _ => { }
395
+ }
396
+ return ;
397
+ }
347
398
}
348
399
}
349
400
}
@@ -517,7 +568,36 @@ impl<const C: usize, const R: usize, const L: usize, T: 'static, K: 'static + Co
517
568
seq. delay = duration - 1 ;
518
569
}
519
570
}
520
- _ => { } // We'll never get here
571
+ Some ( SequenceEvent :: Filter ( keys) ) => {
572
+ self . states = self
573
+ . states
574
+ . iter ( )
575
+ . filter_map ( |s| match s. keycode ( ) {
576
+ Some ( k) => {
577
+ if keys. contains ( & k) {
578
+ seq. add_to_restore ( * s) ;
579
+ None
580
+ } else {
581
+ Some ( * s)
582
+ }
583
+ }
584
+ _ => Some ( * s) ,
585
+ } )
586
+ . collect ( )
587
+ }
588
+ Some ( SequenceEvent :: Restore ) => seq
589
+ . to_restore
590
+ . iter ( )
591
+ . filter_map ( |s| {
592
+ if let Some ( saved) = s {
593
+ let _ = self . states . push ( ( * saved) . into ( ) ) ;
594
+ }
595
+ None
596
+ } )
597
+ . collect ( ) ,
598
+ _ => {
599
+ panic ! ( "invalid sequence" ) ;
600
+ }
521
601
}
522
602
}
523
603
if !seq. remaining_events . is_empty ( ) || seq. tapped . is_some ( ) {
@@ -1645,4 +1725,189 @@ mod test {
1645
1725
// finished
1646
1726
assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1647
1727
}
1728
+
1729
+ #[ test]
1730
+ fn sequences_unshift ( ) {
1731
+ static LAYERS : Layers < 8 , 1 , 1 > = [ [ [
1732
+ k ( LShift ) ,
1733
+ k ( RShift ) ,
1734
+ k ( A ) ,
1735
+ k ( B ) ,
1736
+ k ( C ) ,
1737
+ Sequence (
1738
+ & [
1739
+ SequenceEvent :: Press ( A ) ,
1740
+ SequenceEvent :: Release ( A ) ,
1741
+ SequenceEvent :: Press ( RShift ) ,
1742
+ SequenceEvent :: Press ( B ) ,
1743
+ SequenceEvent :: Release ( B ) ,
1744
+ SequenceEvent :: Release ( RShift ) ,
1745
+ SequenceEvent :: Press ( C ) ,
1746
+ SequenceEvent :: Release ( C ) ,
1747
+ ]
1748
+ . as_slice ( ) ,
1749
+ ) ,
1750
+ Sequence (
1751
+ & [
1752
+ SequenceEvent :: Tap ( A ) ,
1753
+ SequenceEvent :: Press ( RShift ) ,
1754
+ SequenceEvent :: Tap ( B ) ,
1755
+ SequenceEvent :: Release ( RShift ) ,
1756
+ SequenceEvent :: Tap ( C ) ,
1757
+ ]
1758
+ . as_slice ( ) ,
1759
+ ) ,
1760
+ Sequence (
1761
+ & [
1762
+ SequenceEvent :: Tap ( A ) ,
1763
+ SequenceEvent :: Filter ( & [ LShift , RShift ] . as_slice ( ) ) ,
1764
+ SequenceEvent :: Tap ( B ) ,
1765
+ SequenceEvent :: Restore ,
1766
+ SequenceEvent :: Tap ( C ) ,
1767
+ ]
1768
+ . as_slice ( ) ,
1769
+ ) ,
1770
+ /* TODO: sequence with explicit Shift */
1771
+ ] ] ] ;
1772
+ let mut layout = Layout :: new ( & LAYERS ) ;
1773
+
1774
+ // Test a sequence that contains Shift
1775
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1776
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1777
+ layout. event ( Press ( 0 , 2 ) ) ; // A
1778
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1779
+ assert_keys ( & [ A ] , layout. keycodes ( ) ) ;
1780
+ layout. event ( Release ( 0 , 2 ) ) ; // A
1781
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1782
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1783
+ layout. event ( Press ( 0 , 1 ) ) ; // RShift
1784
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1785
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1786
+ layout. event ( Press ( 0 , 3 ) ) ; // B
1787
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1788
+ assert_keys ( & [ B , RShift ] , layout. keycodes ( ) ) ;
1789
+ layout. event ( Release ( 0 , 3 ) ) ; // B
1790
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1791
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1792
+ layout. event ( Release ( 0 , 1 ) ) ; // RShift
1793
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1794
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1795
+ layout. event ( Press ( 0 , 4 ) ) ; // C
1796
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1797
+ assert_keys ( & [ C ] , layout. keycodes ( ) ) ;
1798
+ layout. event ( Release ( 0 , 4 ) ) ; // C
1799
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1800
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1801
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1802
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1803
+
1804
+ // Test a sequence that contains Shift
1805
+ layout. event ( Press ( 0 , 5 ) ) ;
1806
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence detected & added
1807
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1808
+ layout. event ( Release ( 0 , 5 ) ) ;
1809
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // To Process Press(A)
1810
+ assert_keys ( & [ A ] , layout. keycodes ( ) ) ;
1811
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(A)
1812
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1813
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Press(RShift)
1814
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1815
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Press(B)
1816
+ assert_keys ( & [ RShift , B ] , layout. keycodes ( ) ) ;
1817
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(B)
1818
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1819
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(RShift)
1820
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1821
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(C)
1822
+ assert_keys ( & [ C ] , layout. keycodes ( ) ) ;
1823
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(C)
1824
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1825
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence is
1826
+ // finished
1827
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1828
+
1829
+ // Test a sequence that contains Shift with Tap
1830
+ layout. event ( Press ( 0 , 6 ) ) ;
1831
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence detected & added
1832
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1833
+ layout. event ( Release ( 0 , 6 ) ) ;
1834
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // To Process Tap(A)
1835
+ assert_keys ( & [ A ] , layout. keycodes ( ) ) ;
1836
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(A)
1837
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1838
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Press(RShift)
1839
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1840
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(B)
1841
+ assert_keys ( & [ RShift , B ] , layout. keycodes ( ) ) ;
1842
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(B)
1843
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1844
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(RShift)
1845
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1846
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(C)
1847
+ assert_keys ( & [ C ] , layout. keycodes ( ) ) ;
1848
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(C)
1849
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1850
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence is
1851
+ // finished
1852
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1853
+
1854
+ // Test a sequence with Unshift/Restore while Shift has not been
1855
+ // pressed
1856
+ layout. event ( Press ( 0 , 7 ) ) ;
1857
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence detected & added
1858
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1859
+ layout. event ( Release ( 0 , 7 ) ) ;
1860
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // To Process Tap(A)
1861
+ assert_keys ( & [ A ] , layout. keycodes ( ) ) ;
1862
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(A)
1863
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1864
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Unshift
1865
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1866
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(B)
1867
+ assert_keys ( & [ B ] , layout. keycodes ( ) ) ;
1868
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(B)
1869
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1870
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // RestoreShift
1871
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1872
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(C)
1873
+ assert_keys ( & [ C ] , layout. keycodes ( ) ) ;
1874
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(C)
1875
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1876
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence is
1877
+ // finished
1878
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1879
+
1880
+ // Test a sequence with Unshift/Restore while RShift has been pressed
1881
+
1882
+ layout. event ( Press ( 0 , 1 ) ) ; // RShift
1883
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1884
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1885
+
1886
+ layout. event ( Press ( 0 , 7 ) ) ;
1887
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence detected & added
1888
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1889
+ layout. event ( Release ( 0 , 7 ) ) ;
1890
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // To Process Tap(A)
1891
+ assert_keys ( & [ RShift , A ] , layout. keycodes ( ) ) ;
1892
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(A)
1893
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1894
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Unshift
1895
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1896
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(B)
1897
+ assert_keys ( & [ B ] , layout. keycodes ( ) ) ;
1898
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(B)
1899
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1900
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // RestoreShift
1901
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1902
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Tap(C)
1903
+ assert_keys ( & [ RShift , C ] , layout. keycodes ( ) ) ;
1904
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Release(C)
1905
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1906
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ; // Sequence is
1907
+ // finished
1908
+ assert_keys ( & [ RShift ] , layout. keycodes ( ) ) ;
1909
+ layout. event ( Release ( 0 , 1 ) ) ; // RShift
1910
+ assert_eq ! ( CustomEvent :: NoEvent , layout. tick( ) ) ;
1911
+ assert_keys ( & [ ] , layout. keycodes ( ) ) ;
1912
+ }
1648
1913
}
0 commit comments