@@ -366,6 +366,56 @@ def legal_transitions_with_primary_button() -> Dict[str, Tuple["PenState", ...]]
366366 ),
367367 }
368368
369+ @staticmethod
370+ def legal_transitions_with_secondary_button () -> Dict [str , Tuple ["PenState" , ...]]:
371+ """We revisit the Windows Pen Implementation state machine:
372+ we now have a secondary button.
373+ Note: we don't looks for 2 buttons interactions.
374+ """
375+ return {
376+ "hover-button" : (PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,),
377+ "hover-button -> out-of-range" : (
378+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
379+ PenState .PEN_IS_OUT_OF_RANGE ,
380+ ),
381+ "in-range -> button-press" : (
382+ PenState .PEN_IS_IN_RANGE ,
383+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
384+ ),
385+ "in-range -> button-press -> button-release" : (
386+ PenState .PEN_IS_IN_RANGE ,
387+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
388+ PenState .PEN_IS_IN_RANGE ,
389+ ),
390+ "in-range -> touch -> button-press -> button-release" : (
391+ PenState .PEN_IS_IN_RANGE ,
392+ PenState .PEN_IS_IN_CONTACT ,
393+ PenState .PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON ,
394+ PenState .PEN_IS_IN_CONTACT ,
395+ ),
396+ "in-range -> touch -> button-press -> release -> button-release" : (
397+ PenState .PEN_IS_IN_RANGE ,
398+ PenState .PEN_IS_IN_CONTACT ,
399+ PenState .PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON ,
400+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
401+ PenState .PEN_IS_IN_RANGE ,
402+ ),
403+ "in-range -> button-press -> touch -> release -> button-release" : (
404+ PenState .PEN_IS_IN_RANGE ,
405+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
406+ PenState .PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON ,
407+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
408+ PenState .PEN_IS_IN_RANGE ,
409+ ),
410+ "in-range -> button-press -> touch -> button-release -> release" : (
411+ PenState .PEN_IS_IN_RANGE ,
412+ PenState .PEN_IS_IN_RANGE_WITH_SECOND_BUTTON ,
413+ PenState .PEN_IS_IN_CONTACT_WITH_SECOND_BUTTON ,
414+ PenState .PEN_IS_IN_CONTACT ,
415+ PenState .PEN_IS_IN_RANGE ,
416+ ),
417+ }
418+
369419 @staticmethod
370420 def tolerated_transitions () -> Dict [str , Tuple ["PenState" , ...]]:
371421 """This is not adhering to the Windows Pen Implementation state machine
@@ -444,6 +494,7 @@ def __init__(self, x, y):
444494 self .width = 10
445495 self .height = 10
446496 self .barrelswitch = False
497+ self .secondarybarrelswitch = False
447498 self .invert = False
448499 self .eraser = False
449500 self .xtilt = 1
@@ -736,6 +787,22 @@ def test_valid_primary_button_pen_states(self, state_list, scribble):
736787 """Rework the transition state machine by adding the primary button."""
737788 self ._test_states (state_list , scribble )
738789
790+ @pytest .mark .skip_if_uhdev (
791+ lambda uhdev : "Secondary Barrel Switch" not in uhdev .fields ,
792+ "Device not compatible, missing Secondary Barrel Switch usage" ,
793+ )
794+ @pytest .mark .parametrize ("scribble" , [True , False ], ids = ["scribble" , "static" ])
795+ @pytest .mark .parametrize (
796+ "state_list" ,
797+ [
798+ pytest .param (v , id = k )
799+ for k , v in PenState .legal_transitions_with_secondary_button ().items ()
800+ ],
801+ )
802+ def test_valid_secondary_button_pen_states (self , state_list , scribble ):
803+ """Rework the transition state machine by adding the secondary button."""
804+ self ._test_states (state_list , scribble )
805+
739806 @pytest .mark .skip_if_uhdev (
740807 lambda uhdev : "Invert" not in uhdev .fields ,
741808 "Device not compatible, missing Invert usage" ,
0 commit comments