@@ -18,7 +18,7 @@ pub struct InputPreprocessorMessageHandler {
1818 pub keyboard : KeyStates ,
1919 pub mouse : MouseState ,
2020 pub last_key_down : Option < ( Key , u64 ) > , // (Key, timestamp)
21- pub double_tap_key : Option < Key > ,
21+ pub double_tap_key : Option < ( Key , u64 ) > ,
2222}
2323
2424#[ message_handler_data]
@@ -28,6 +28,7 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
2828
2929 match message {
3030 InputPreprocessorMessage :: DoubleClick { editor_mouse_state, modifier_keys } => {
31+ self . clear_double_tap_state ( ) ;
3132 self . update_states_of_modifier_keys ( modifier_keys, responses) ;
3233
3334 let mouse_state = editor_mouse_state. to_mouse_state ( viewport) ;
@@ -54,10 +55,11 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
5455 . is_some_and ( |( last_key, last_time) | last_key == key && self . time . saturating_sub ( last_time) < DOUBLE_CLICK_MILLISECONDS ) ;
5556
5657 if is_double_tap {
57- self . double_tap_key = Some ( key) ;
58+ self . double_tap_key = Some ( ( key, self . time ) ) ;
5859 self . last_key_down = None ;
5960 } else {
6061 self . last_key_down = Some ( ( key, self . time ) ) ;
62+ self . double_tap_key = None ;
6163 }
6264
6365 responses. add ( InputMapperMessage :: KeyDownNoRepeat ( key) ) ;
@@ -70,13 +72,16 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
7072 if !key_repeat {
7173 responses. add ( InputMapperMessage :: KeyUpNoRepeat ( key) ) ;
7274 }
73- if self . double_tap_key == Some ( key) {
74- responses. add ( InputMapperMessage :: DoubleTap ( key) ) ;
75+ if let Some ( ( dt_key, dt_time) ) = self . double_tap_key {
76+ if dt_key == key && self . time . saturating_sub ( dt_time) < DOUBLE_CLICK_MILLISECONDS {
77+ responses. add ( InputMapperMessage :: DoubleTap ( key) ) ;
78+ }
7579 self . double_tap_key = None ;
7680 }
7781 responses. add ( InputMapperMessage :: KeyUp ( key) ) ;
7882 }
7983 InputPreprocessorMessage :: PointerDown { editor_mouse_state, modifier_keys } => {
84+ self . clear_double_tap_state ( ) ;
8085 self . update_states_of_modifier_keys ( modifier_keys, responses) ;
8186
8287 let mouse_state = editor_mouse_state. to_mouse_state ( viewport) ;
@@ -96,6 +101,7 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
96101 self . translate_mouse_event ( mouse_state, false , responses) ;
97102 }
98103 InputPreprocessorMessage :: PointerUp { editor_mouse_state, modifier_keys } => {
104+ self . clear_double_tap_state ( ) ;
99105 self . update_states_of_modifier_keys ( modifier_keys, responses) ;
100106
101107 let mouse_state = editor_mouse_state. to_mouse_state ( viewport) ;
@@ -117,6 +123,7 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
117123 self . frame_time . advance_timestamp ( Duration :: from_millis ( timestamp) ) ;
118124 }
119125 InputPreprocessorMessage :: WheelScroll { editor_mouse_state, modifier_keys } => {
126+ self . clear_double_tap_state ( ) ;
120127 self . update_states_of_modifier_keys ( modifier_keys, responses) ;
121128
122129 let mouse_state = editor_mouse_state. to_mouse_state ( viewport) ;
@@ -135,6 +142,11 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
135142}
136143
137144impl InputPreprocessorMessageHandler {
145+ fn clear_double_tap_state ( & mut self ) {
146+ self . last_key_down = None ;
147+ self . double_tap_key = None ;
148+ }
149+
138150 fn translate_mouse_event ( & mut self , mut new_state : MouseState , allow_first_button_down : bool , responses : & mut VecDeque < Message > ) {
139151 let click_mappings = [
140152 ( MouseKeys :: LEFT , Key :: MouseLeft ) ,
@@ -359,7 +371,7 @@ mod test {
359371 assert ! ( responses. contains( & InputMapperMessage :: KeyDown ( Key :: Space ) . into( ) ) ) ;
360372 assert ! ( responses. contains( & InputMapperMessage :: KeyDownNoRepeat ( Key :: Space ) . into( ) ) ) ;
361373 assert ! ( input_preprocessor. last_key_down. is_none( ) ) ;
362- assert_eq ! ( input_preprocessor. double_tap_key, Some ( Key :: Space ) ) ;
374+ assert_eq ! ( input_preprocessor. double_tap_key, Some ( ( Key :: Space , 50 ) ) ) ;
363375
364376 responses. clear ( ) ;
365377 key_up ( & mut input_preprocessor, Key :: Space , & mut responses) ;
@@ -394,4 +406,55 @@ mod test {
394406
395407 assert ! ( !responses. contains( & InputMapperMessage :: DoubleTap ( Key :: Space ) . into( ) ) ) ;
396408 }
409+
410+ #[ test]
411+ fn process_double_tap_held_too_long ( ) {
412+ let mut input_preprocessor = InputPreprocessorMessageHandler :: default ( ) ;
413+ let mut responses = VecDeque :: new ( ) ;
414+
415+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
416+ key_up ( & mut input_preprocessor, Key :: Space , & mut responses) ;
417+ responses. clear ( ) ;
418+
419+ input_preprocessor. time = 50 ;
420+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
421+ responses. clear ( ) ;
422+
423+ // Release after the threshold
424+ input_preprocessor. time = 50 + DOUBLE_CLICK_MILLISECONDS + 1 ;
425+ key_up ( & mut input_preprocessor, Key :: Space , & mut responses) ;
426+
427+ assert ! ( !responses. contains( & InputMapperMessage :: DoubleTap ( Key :: Space ) . into( ) ) ) ;
428+ }
429+
430+ #[ test]
431+ fn process_double_tap_interrupted_by_pointer ( ) {
432+ let mut input_preprocessor = InputPreprocessorMessageHandler :: default ( ) ;
433+ let mut responses = VecDeque :: new ( ) ;
434+
435+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
436+ key_up ( & mut input_preprocessor, Key :: Space , & mut responses) ;
437+ responses. clear ( ) ;
438+
439+ input_preprocessor. time = 50 ;
440+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
441+ responses. clear ( ) ;
442+
443+ // PointerDown happens!
444+ input_preprocessor. process_message (
445+ InputPreprocessorMessage :: PointerDown {
446+ editor_mouse_state : EditorMouseState :: default ( ) ,
447+ modifier_keys : ModifierKeys :: empty ( ) ,
448+ } ,
449+ & mut responses,
450+ InputPreprocessorMessageContext {
451+ viewport : & ViewportMessageHandler :: default ( ) ,
452+ } ,
453+ ) ;
454+ responses. clear ( ) ;
455+
456+ key_up ( & mut input_preprocessor, Key :: Space , & mut responses) ;
457+
458+ assert ! ( !responses. contains( & InputMapperMessage :: DoubleTap ( Key :: Space ) . into( ) ) ) ;
459+ }
397460}
0 commit comments