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