@@ -49,6 +49,7 @@ pub use keyberon_macros::*;
4949use crate :: action:: { Action , HoldTapAction , HoldTapConfig , SequenceEvent } ;
5050use crate :: key_code:: KeyCode ;
5151use arraydeque:: ArrayDeque ;
52+ use core:: convert:: TryFrom ;
5253use heapless:: Vec ;
5354
5455use State :: * ;
@@ -326,7 +327,38 @@ impl<'a> Iterator for StackedIter<'a> {
326327}
327328
328329#[ 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 > {
330362 /// Current event being processed
331363 cur_event : Option < SequenceEvent < K > > ,
332364 /// Remaining events to process
@@ -335,6 +367,8 @@ struct SequenceState<K: 'static> {
335367 delay : u32 ,
336368 /// Keycode of a key that should be released at the next tick
337369 tapped : Option < K > ,
370+ /// Keys filtered that can be restored later
371+ to_restore : [ Option < SavedKeyCodeState < K > > ; 64 ] ,
338372}
339373
340374impl < K : Copy > Default for SequenceState < K > {
@@ -344,6 +378,23 @@ impl<K: Copy> Default for SequenceState<K> {
344378 remaining_events : & [ ] ,
345379 delay : 0 ,
346380 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+ }
347398 }
348399 }
349400}
@@ -517,7 +568,36 @@ impl<const C: usize, const R: usize, const L: usize, T: 'static, K: 'static + Co
517568 seq. delay = duration - 1 ;
518569 }
519570 }
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+ }
521601 }
522602 }
523603 if !seq. remaining_events . is_empty ( ) || seq. tapped . is_some ( ) {
@@ -1645,4 +1725,189 @@ mod test {
16451725 // finished
16461726 assert_keys ( & [ ] , layout. keycodes ( ) ) ;
16471727 }
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+ }
16481913}
0 commit comments