@@ -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 core:: fmt:: Debug ;
5354use heapless:: Vec ;
5455
@@ -331,7 +332,38 @@ impl<'a> Iterator for StackedIter<'a> {
331332}
332333
333334#[ 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 > {
335367 /// Current event being processed
336368 cur_event : Option < SequenceEvent < K > > ,
337369 /// Remaining events to process
@@ -340,6 +372,8 @@ struct SequenceState<K: 'static> {
340372 delay : u32 ,
341373 /// Keycode of a key that should be released at the next tick
342374 tapped : Option < K > ,
375+ /// Keys filtered that can be restored later
376+ to_restore : [ Option < SavedKeyCodeState < K > > ; 64 ] ,
343377}
344378
345379impl < K : Copy > Default for SequenceState < K > {
@@ -349,6 +383,23 @@ impl<K: Copy> Default for SequenceState<K> {
349383 remaining_events : & [ ] ,
350384 delay : 0 ,
351385 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+ }
352403 }
353404 }
354405}
@@ -527,7 +578,36 @@ impl<
527578 seq. delay = duration - 1 ;
528579 }
529580 }
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+ }
531611 }
532612 }
533613 if !seq. remaining_events . is_empty ( ) || seq. tapped . is_some ( ) {
@@ -1655,4 +1735,189 @@ mod test {
16551735 // finished
16561736 assert_keys ( & [ ] , layout. keycodes ( ) ) ;
16571737 }
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+ }
16581923}
0 commit comments