@@ -373,46 +373,29 @@ impl KeyInputState {
373373 is_composing : false ,
374374 } )
375375 }
376+ }
376377
377- fn clear ( & mut self , undo_actions : & mut HashSet < char > , result : & mut Vec < Event > ) {
378- let mut actions: Vec < _ > = undo_actions. drain ( ) . collect ( ) ;
379- actions. sort_unstable ( ) ;
380- for action in actions {
381- result. push ( self . dispatch_keyup ( action) . unwrap ( ) . into ( ) ) ;
382- }
383- assert ! ( undo_actions. is_empty( ) ) ;
384- }
385-
386- fn dispatch_typeable ( & mut self , text : & mut String , result : & mut Vec < Event > ) {
387- for character in text. chars ( ) {
388- let shifted = self . modifiers . contains ( Modifiers :: SHIFT ) ;
389- if is_shifted_character ( character) && !shifted {
390- // dispatch left shift down
391- result. push ( self . dispatch_keydown ( '\u{E008}' ) . into ( ) ) ;
392- }
393- if !is_shifted_character ( character) && shifted {
394- // dispatch left shift up
395- result. push ( self . dispatch_keyup ( '\u{E008}' ) . unwrap ( ) . into ( ) ) ;
396- }
397- result. push ( self . dispatch_keydown ( character) . into ( ) ) ;
398- result. push ( self . dispatch_keyup ( character) . unwrap ( ) . into ( ) ) ;
399- }
400- text. clear ( ) ;
401- }
378+ /// Give user the key state and char of the key event.
379+ /// User must then send the key event through `dispatch_actions`
380+ #[ derive( Clone , Eq , PartialEq , Hash , Debug , PartialOrd , Ord ) ]
381+ #[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
382+ pub struct KeyItem {
383+ state : KeyState ,
384+ raw_char : char ,
402385}
403386
404- /// Either a [`KeyboardEvent `] or a [`CompositionEvent`].
387+ /// Either a [`KeyItem `] or a [`CompositionEvent`].
405388///
406389/// Returned by the [`send_keys`] function.
407390#[ derive( Clone , Eq , PartialEq , Hash , Debug , PartialOrd , Ord ) ]
408391#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
409392pub enum Event {
410- Keyboard ( KeyboardEvent ) ,
393+ Keyboard ( KeyItem ) ,
411394 Composition ( CompositionEvent ) ,
412395}
413396
414- impl From < KeyboardEvent > for Event {
415- fn from ( v : KeyboardEvent ) -> Event {
397+ impl From < KeyItem > for Event {
398+ fn from ( v : KeyItem ) -> Event {
416399 Event :: Keyboard ( v)
417400 }
418401}
@@ -459,25 +442,89 @@ pub fn send_keys(text: &str) -> Vec<Event> {
459442 text. chars ( ) . count ( ) == 1
460443 }
461444
445+ fn clear ( undo_actions : & mut HashSet < char > , result : & mut Vec < Event > , shifted : & mut bool ) {
446+ let mut actions: Vec < _ > = undo_actions. drain ( ) . collect ( ) ;
447+ actions. sort_unstable ( ) ;
448+ for action in actions {
449+ result. push (
450+ KeyItem {
451+ state : KeyState :: Up ,
452+ raw_char : action,
453+ }
454+ . into ( ) ,
455+ ) ;
456+ }
457+ * shifted = false ;
458+ assert ! ( undo_actions. is_empty( ) ) ;
459+ }
460+
461+ fn dispatch_typeable ( text : & mut String , result : & mut Vec < Event > , shifted : & mut bool ) {
462+ for character in text. chars ( ) {
463+ if is_shifted_character ( character) && !( * shifted) {
464+ // dispatch left shift down
465+ result. push (
466+ KeyItem {
467+ state : KeyState :: Down ,
468+ raw_char : '\u{E008}' ,
469+ }
470+ . into ( ) ,
471+ ) ;
472+ * shifted = true ;
473+ }
474+ if !is_shifted_character ( character) && * shifted {
475+ // dispatch left shift up
476+ result. push (
477+ KeyItem {
478+ state : KeyState :: Up ,
479+ raw_char : '\u{E008}' ,
480+ }
481+ . into ( ) ,
482+ ) ;
483+ * shifted = false ;
484+ }
485+ result. push (
486+ KeyItem {
487+ state : KeyState :: Down ,
488+ raw_char : character,
489+ }
490+ . into ( ) ,
491+ ) ;
492+ result. push (
493+ KeyItem {
494+ state : KeyState :: Up ,
495+ raw_char : character,
496+ }
497+ . into ( ) ,
498+ ) ;
499+ }
500+ text. clear ( ) ;
501+ }
502+
462503 let mut result = Vec :: new ( ) ;
463504 let mut typeable_text = String :: new ( ) ;
464- let mut state = KeyInputState :: new ( ) ;
465505 let mut undo_actions = HashSet :: new ( ) ;
506+ let mut shifted = false ;
466507 for cluster in UnicodeSegmentation :: graphemes ( text, true ) {
467508 match cluster {
468509 "\u{E000} " => {
469- state . dispatch_typeable ( & mut typeable_text, & mut result) ;
470- state . clear ( & mut undo_actions, & mut result) ;
510+ dispatch_typeable ( & mut typeable_text, & mut result, & mut shifted ) ;
511+ clear ( & mut undo_actions, & mut result, & mut shifted ) ;
471512 }
472513 s if is_modifier ( s) => {
473- state . dispatch_typeable ( & mut typeable_text, & mut result) ;
514+ dispatch_typeable ( & mut typeable_text, & mut result, & mut shifted ) ;
474515 let raw_modifier = first_char ( s) ;
475- result. push ( state. dispatch_keydown ( raw_modifier) . into ( ) ) ;
516+ result. push (
517+ KeyItem {
518+ state : KeyState :: Down ,
519+ raw_char : raw_modifier,
520+ }
521+ . into ( ) ,
522+ ) ;
476523 undo_actions. insert ( raw_modifier) ;
477524 }
478525 s if is_typeable ( s) => typeable_text. push_str ( s) ,
479526 s => {
480- state . dispatch_typeable ( & mut typeable_text, & mut result) ;
527+ dispatch_typeable ( & mut typeable_text, & mut result, & mut shifted ) ;
481528 // FIXME: Spec says undefined instead of empty string
482529 result. push (
483530 CompositionEvent {
@@ -503,7 +550,7 @@ pub fn send_keys(text: &str) -> Vec<Event> {
503550 }
504551 }
505552 }
506- state . dispatch_typeable ( & mut typeable_text, & mut result) ;
507- state . clear ( & mut undo_actions, & mut result) ;
553+ dispatch_typeable ( & mut typeable_text, & mut result, & mut shifted ) ;
554+ clear ( & mut undo_actions, & mut result, & mut shifted ) ;
508555 result
509556}
0 commit comments