diff --git a/editor/src/messages/input_mapper/input_mapper_message.rs b/editor/src/messages/input_mapper/input_mapper_message.rs index 12e611620f4..69717bb35a6 100644 --- a/editor/src/messages/input_mapper/input_mapper_message.rs +++ b/editor/src/messages/input_mapper/input_mapper_message.rs @@ -24,3 +24,9 @@ pub enum InputMapperMessage { PointerShake, WheelScroll, } + +impl InputMapperMessage { + pub const fn is_no_repeat(&self) -> bool { + matches!(self, InputMapperMessage::KeyDownNoRepeat(_) | InputMapperMessage::KeyUpNoRepeat(_)) + } +} diff --git a/editor/src/messages/input_mapper/input_mapper_message_handler.rs b/editor/src/messages/input_mapper/input_mapper_message_handler.rs index 145b75d0731..d83092b8337 100644 --- a/editor/src/messages/input_mapper/input_mapper_message_handler.rs +++ b/editor/src/messages/input_mapper/input_mapper_message_handler.rs @@ -37,8 +37,6 @@ impl InputMapperMessageHandler { let all_key_mapping_entries = std::iter::empty() .chain(self.mapping.key_up.iter()) .chain(self.mapping.key_down.iter()) - .chain(self.mapping.key_up_no_repeat.iter()) - .chain(self.mapping.key_down_no_repeat.iter()) .chain(self.mapping.double_click.iter()) .chain(self.mapping.double_tap.iter()) .chain(std::iter::once(&self.mapping.wheel_scroll)) diff --git a/editor/src/messages/input_mapper/input_mappings.rs b/editor/src/messages/input_mapper/input_mappings.rs index 3765b0ed8f8..655cf8d80f3 100644 --- a/editor/src/messages/input_mapper/input_mappings.rs +++ b/editor/src/messages/input_mapper/input_mappings.rs @@ -99,8 +99,8 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(MouseLeft); action_dispatch=TransformLayerMessage::ApplyTransformOperation { final_transform: true }), entry!(KeyDown(MouseRight); action_dispatch=TransformLayerMessage::CancelTransformOperation), entry!(KeyDown(Escape); action_dispatch=TransformLayerMessage::CancelTransformOperation), - entry!(KeyDown(KeyX); action_dispatch=TransformLayerMessage::ConstrainX), - entry!(KeyDown(KeyY); action_dispatch=TransformLayerMessage::ConstrainY), + entry!(KeyDownNoRepeat(KeyX); action_dispatch=TransformLayerMessage::ConstrainX), + entry!(KeyDownNoRepeat(KeyY); action_dispatch=TransformLayerMessage::ConstrainY), entry!(KeyDown(Backspace); action_dispatch=TransformLayerMessage::TypeBackspace), entry!(KeyDown(Minus); action_dispatch=TransformLayerMessage::TypeNegate), entry!(KeyDown(Comma); action_dispatch=TransformLayerMessage::TypeDecimalPoint), @@ -230,9 +230,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(MouseLeft); action_dispatch=PathToolMessage::MouseDown { extend_selection: Shift, lasso_select: Control, handle_drag_from_anchor: Alt, drag_restore_handle: Control, segment_editing_modifier: Control }), entry!(KeyDown(MouseRight); action_dispatch=PathToolMessage::RightClick), entry!(KeyDown(Escape); action_dispatch=PathToolMessage::Escape), - entry!(KeyDown(KeyG); action_dispatch=PathToolMessage::GRS { key: KeyG }), - entry!(KeyDown(KeyR); action_dispatch=PathToolMessage::GRS { key: KeyR }), - entry!(KeyDown(KeyS); action_dispatch=PathToolMessage::GRS { key: KeyS }), + entry!(KeyDownNoRepeat(KeyG); action_dispatch=PathToolMessage::GRS { key: KeyG }), + entry!(KeyDownNoRepeat(KeyR); action_dispatch=PathToolMessage::GRS { key: KeyR }), + entry!(KeyDownNoRepeat(KeyS); action_dispatch=PathToolMessage::GRS { key: KeyS }), entry!(PointerMove; refresh_keys=[KeyC, Space, Control, Shift, Alt, KeyQ, KeyW], action_dispatch=PathToolMessage::PointerMove { toggle_colinear: KeyC, equidistant: Alt, move_anchor_with_handles: Space, snap_angle: Shift, lock_angle: Control, delete_segment: Alt, break_colinear_molding: Alt, segment_editing_modifier: Control }), entry!(KeyDown(Delete); action_dispatch=PathToolMessage::Delete), entry!(KeyDown(KeyA); modifiers=[Accel], action_dispatch=PathToolMessage::SelectAll), @@ -278,9 +278,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(Enter); action_dispatch=PenToolMessage::Confirm), entry!(KeyDown(Delete); action_dispatch=PenToolMessage::RemovePreviousHandle), entry!(KeyDown(Backspace); action_dispatch=PenToolMessage::RemovePreviousHandle), - entry!(KeyDown(KeyG); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), - entry!(KeyDown(KeyR); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), - entry!(KeyDown(KeyS); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), + entry!(KeyDownNoRepeat(KeyG); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), + entry!(KeyDownNoRepeat(KeyR); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), + entry!(KeyDownNoRepeat(KeyS); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }), // // FreehandToolMessage entry!(PointerMove; action_dispatch=FreehandToolMessage::PointerMove), @@ -315,37 +315,36 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(Escape); action_dispatch=BrushToolMessage::Abort), // // ToolMessage - entry!(KeyDown(KeyV); action_dispatch=ToolMessage::ActivateToolSelect), - entry!(KeyDown(KeyZ); action_dispatch=ToolMessage::ActivateToolNavigate), - entry!(KeyDown(KeyI); action_dispatch=ToolMessage::ActivateToolEyedropper), - entry!(KeyDown(KeyT); action_dispatch=ToolMessage::ActivateToolText), - entry!(KeyDown(KeyF); action_dispatch=ToolMessage::ActivateToolFill), - entry!(KeyDown(KeyH); action_dispatch=ToolMessage::ActivateToolGradient), - entry!(KeyDown(KeyA); action_dispatch=ToolMessage::ActivateToolPath), - entry!(KeyDown(KeyP); action_dispatch=ToolMessage::ActivateToolPen), - entry!(KeyDown(KeyN); action_dispatch=ToolMessage::ActivateToolFreehand), - entry!(KeyDown(KeyL); action_dispatch=ToolMessage::ActivateToolShapeLine), - entry!(KeyDown(KeyM); action_dispatch=ToolMessage::ActivateToolShapeRectangle), - entry!(KeyDown(KeyE); action_dispatch=ToolMessage::ActivateToolShapeEllipse), - entry!(KeyDown(KeyY); action_dispatch=ToolMessage::ActivateToolShape), - entry!(KeyDown(KeyB); action_dispatch=ToolMessage::ActivateToolBrush), + entry!(KeyDownNoRepeat(KeyV); action_dispatch=ToolMessage::ActivateToolSelect), + entry!(KeyDownNoRepeat(KeyZ); action_dispatch=ToolMessage::ActivateToolNavigate), + entry!(KeyDownNoRepeat(KeyI); action_dispatch=ToolMessage::ActivateToolEyedropper), + entry!(KeyDownNoRepeat(KeyT); action_dispatch=ToolMessage::ActivateToolText), + entry!(KeyDownNoRepeat(KeyF); action_dispatch=ToolMessage::ActivateToolFill), + entry!(KeyDownNoRepeat(KeyH); action_dispatch=ToolMessage::ActivateToolGradient), + entry!(KeyDownNoRepeat(KeyA); action_dispatch=ToolMessage::ActivateToolPath), + entry!(KeyDownNoRepeat(KeyP); action_dispatch=ToolMessage::ActivateToolPen), + entry!(KeyDownNoRepeat(KeyN); action_dispatch=ToolMessage::ActivateToolFreehand), + entry!(KeyDownNoRepeat(KeyL); action_dispatch=ToolMessage::ActivateToolShapeLine), + entry!(KeyDownNoRepeat(KeyM); action_dispatch=ToolMessage::ActivateToolShapeRectangle), + entry!(KeyDownNoRepeat(KeyE); action_dispatch=ToolMessage::ActivateToolShapeEllipse), + entry!(KeyDownNoRepeat(KeyY); action_dispatch=ToolMessage::ActivateToolShape), + entry!(KeyDownNoRepeat(KeyB); action_dispatch=ToolMessage::ActivateToolBrush), entry!(KeyDown(KeyD); action_dispatch=ToolMessage::ResetColors), entry!(KeyDown(KeyX); modifiers=[Shift], action_dispatch=ToolMessage::SwapColors), entry!(KeyDown(KeyC); modifiers=[Alt], action_dispatch=ToolMessage::SelectRandomWorkingColor { primary: true }), entry!(KeyDown(KeyC); modifiers=[Alt, Shift], action_dispatch=ToolMessage::SelectRandomWorkingColor { primary: false }), - // TODO: Change to KeyDownNoRepeat when https://github.com/GraphiteEditor/Graphite/issues/2266 is resolved - entry!(KeyDown(Tab); action_dispatch=ToolMessage::ToggleSelectVsPath), + entry!(KeyDownNoRepeat(Tab); action_dispatch=ToolMessage::ToggleSelectVsPath), // // DocumentMessage entry!(DoubleTap(Space); action_dispatch=DocumentMessage::GraphViewOverlayToggle), entry!(KeyDownNoRepeat(Escape); action_dispatch=DocumentMessage::Escape), entry!(KeyDown(Delete); action_dispatch=DocumentMessage::DeleteSelectedLayers), entry!(KeyDown(Backspace); action_dispatch=DocumentMessage::DeleteSelectedLayers), - entry!(KeyDown(KeyO); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleOverlaysVisibility), - entry!(KeyDown(KeyS); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleSnapping), + entry!(KeyDownNoRepeat(KeyO); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleOverlaysVisibility), + entry!(KeyDownNoRepeat(KeyS); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleSnapping), entry!(KeyDown(KeyH); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedVisibility), - entry!(KeyDown(KeyL); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedLocked), - entry!(KeyDown(KeyG); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleGridVisibility), + entry!(KeyDownNoRepeat(KeyL); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedLocked), + entry!(KeyDownNoRepeat(KeyG); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleGridVisibility), entry!(KeyDown(KeyZ); modifiers=[Accel, Shift], canonical, action_dispatch=DocumentMessage::Redo), entry!(KeyDown(KeyY); modifiers=[Accel], action_dispatch=DocumentMessage::Redo), entry!(KeyDown(KeyZ); modifiers=[Accel], action_dispatch=DocumentMessage::Undo), @@ -398,9 +397,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(ArrowRight); action_dispatch=DocumentMessage::NudgeSelectedLayers { delta_x: NUDGE_AMOUNT, delta_y: 0., resize: Alt, resize_opposite: Control }), // // TransformLayerMessage - entry!(KeyDown(KeyG); action_dispatch=TransformLayerMessage::BeginGrab), - entry!(KeyDown(KeyR); action_dispatch=TransformLayerMessage::BeginRotate), - entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginScale), + entry!(KeyDownNoRepeat(KeyG); action_dispatch=TransformLayerMessage::BeginGrab), + entry!(KeyDownNoRepeat(KeyR); action_dispatch=TransformLayerMessage::BeginRotate), + entry!(KeyDownNoRepeat(KeyS); action_dispatch=TransformLayerMessage::BeginScale), entry!(KeyDown(Digit0); action_dispatch=TransformLayerMessage::TypeDigit { digit: 0 }), entry!(KeyDown(Digit1); action_dispatch=TransformLayerMessage::TypeDigit { digit: 1 }), entry!(KeyDown(Digit2); action_dispatch=TransformLayerMessage::TypeDigit { digit: 2 }), @@ -452,16 +451,16 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument), entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation), entry!(KeyDown(KeyW); modifiers=[Accel, Alt], action_dispatch=PortfolioMessage::CloseAllDocumentsWithConfirmation), - entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=IngestMessage::Open), - entry!(KeyDown(KeyI); modifiers=[Accel], action_dispatch=IngestMessage::Import), - entry!(KeyDown(KeyR); modifiers=[Alt], action_dispatch=PortfolioMessage::ToggleRulers), + entry!(KeyDownNoRepeat(KeyO); modifiers=[Accel], action_dispatch=IngestMessage::Open), + entry!(KeyDownNoRepeat(KeyI); modifiers=[Accel], action_dispatch=IngestMessage::Import), + entry!(KeyDownNoRepeat(KeyR); modifiers=[Alt], action_dispatch=PortfolioMessage::ToggleRulers), entry!(KeyDown(KeyD); modifiers=[Alt], action_dispatch=WorkspaceMessage::ToggleDataPanelOpen), entry!(KeyDown(Enter); modifiers=[Alt], action_dispatch=WorkspaceMessage::ToggleFocusDocument), // // DialogMessage - entry!(KeyDown(KeyE); modifiers=[Accel], action_dispatch=DialogMessage::RequestExportDialog), - entry!(KeyDown(KeyN); modifiers=[Accel], action_dispatch=DialogMessage::RequestNewDocumentDialog), - entry!(KeyDown(Comma); modifiers=[Accel], action_dispatch=DialogMessage::RequestPreferencesDialog), + entry!(KeyDownNoRepeat(KeyE); modifiers=[Accel], action_dispatch=DialogMessage::RequestExportDialog), + entry!(KeyDownNoRepeat(KeyN); modifiers=[Accel], action_dispatch=DialogMessage::RequestNewDocumentDialog), + entry!(KeyDownNoRepeat(Comma); modifiers=[Accel], action_dispatch=DialogMessage::RequestPreferencesDialog), // // DebugMessage entry!(KeyDown(Digit0); modifiers=[Alt], action_dispatch=DebugMessage::MessageOff), @@ -471,35 +470,33 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping { entry!(KeyDown(Space); modifiers=[Shift], action_dispatch=AnimationMessage::ToggleLivePreview), entry!(KeyDown(Home); modifiers=[Shift], action_dispatch=AnimationMessage::RestartAnimation), ]; - let (mut key_up, mut key_down, mut key_up_no_repeat, mut key_down_no_repeat, mut double_click, mut double_tap, mut wheel_scroll, mut pointer_move, mut pointer_shake) = mappings; + let (mut key_up, mut key_down, mut double_click, mut double_tap, mut wheel_scroll, mut pointer_move, mut pointer_shake) = mappings; let sort = |list: &mut KeyMappingEntries| list.0.sort_by_key(|entry| std::cmp::Reverse(entry.modifiers.count_ones())); - // Sort the sublists of `key_up`, `key_down`, `key_up_no_repeat`, and `key_down_no_repeat` - for list in [&mut key_up, &mut key_down, &mut key_up_no_repeat, &mut key_down_no_repeat] { + + for list in [&mut key_up, &mut key_down] { for sublist in list { sort(sublist); } } - // Sort the sublists of `double_click` + for sublist in &mut double_click { sort(sublist) } - // Sort the sublists of `double_tap` + for sublist in &mut double_tap { sort(sublist) } - // Sort `wheel_scroll` + sort(&mut wheel_scroll); - // Sort `pointer_move` + sort(&mut pointer_move); - // Sort `pointer_shake` + sort(&mut pointer_shake); Mapping { key_up, key_down, - key_up_no_repeat, - key_down_no_repeat, double_click, double_tap, wheel_scroll, diff --git a/editor/src/messages/input_mapper/utility_types/macros.rs b/editor/src/messages/input_mapper/utility_types/macros.rs index 2d0a5d6cf57..a61c655f7d3 100644 --- a/editor/src/messages/input_mapper/utility_types/macros.rs +++ b/editor/src/messages/input_mapper/utility_types/macros.rs @@ -88,20 +88,6 @@ macro_rules! entry { canonical: $canonical, disabled: $disabled, }, - MappingEntry { - action: $action_dispatch.into(), - input: InputMapperMessage::KeyDownNoRepeat(Key::$refresh), - modifiers: modifiers!(), - canonical: $canonical, - disabled: $disabled, - }, - MappingEntry { - action: $action_dispatch.into(), - input: InputMapperMessage::KeyUpNoRepeat(Key::$refresh), - modifiers: modifiers!(), - canonical: $canonical, - disabled: $disabled, - }, )* ]] }; @@ -116,8 +102,6 @@ macro_rules! mapping { [$($entry:expr_2021),* $(,)?] => {{ let mut key_up = KeyMappingEntries::key_array(); let mut key_down = KeyMappingEntries::key_array(); - let mut key_up_no_repeat = KeyMappingEntries::key_array(); - let mut key_down_no_repeat = KeyMappingEntries::key_array(); let mut double_click = KeyMappingEntries::mouse_buttons_arrays(); let mut double_tap = KeyMappingEntries::key_array(); let mut wheel_scroll = KeyMappingEntries::new(); @@ -134,10 +118,8 @@ macro_rules! mapping { } let corresponding_list = match entry.input { - InputMapperMessage::KeyDown(key) => &mut key_down[key as usize], - InputMapperMessage::KeyUp(key) => &mut key_up[key as usize], - InputMapperMessage::KeyDownNoRepeat(key) => &mut key_down_no_repeat[key as usize], - InputMapperMessage::KeyUpNoRepeat(key) => &mut key_up_no_repeat[key as usize], + InputMapperMessage::KeyDown(key) | InputMapperMessage::KeyDownNoRepeat(key) => &mut key_down[key as usize], + InputMapperMessage::KeyUp(key) | InputMapperMessage::KeyUpNoRepeat(key) => &mut key_up[key as usize], InputMapperMessage::DoubleClick(key) => &mut double_click[key as usize], InputMapperMessage::DoubleTap(key) => &mut double_tap[key as usize], InputMapperMessage::WheelScroll => &mut wheel_scroll, @@ -150,7 +132,7 @@ macro_rules! mapping { } )* - (key_up, key_down, key_up_no_repeat, key_down_no_repeat, double_click, double_tap, wheel_scroll, pointer_move, pointer_shake) + (key_up, key_down, double_click, double_tap, wheel_scroll, pointer_move, pointer_shake) }}; } diff --git a/editor/src/messages/input_mapper/utility_types/misc.rs b/editor/src/messages/input_mapper/utility_types/misc.rs index 8dcf77369fe..51d38382014 100644 --- a/editor/src/messages/input_mapper/utility_types/misc.rs +++ b/editor/src/messages/input_mapper/utility_types/misc.rs @@ -9,8 +9,6 @@ use core::time::Duration; pub struct Mapping { pub key_up: [KeyMappingEntries; NUMBER_OF_KEYS], pub key_down: [KeyMappingEntries; NUMBER_OF_KEYS], - pub key_up_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS], - pub key_down_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS], pub double_click: [KeyMappingEntries; NUMBER_OF_MOUSE_BUTTONS], pub double_tap: [KeyMappingEntries; NUMBER_OF_KEYS], pub wheel_scroll: KeyMappingEntries, @@ -27,15 +25,13 @@ impl Default for Mapping { impl Mapping { pub fn match_input_message(&self, message: InputMapperMessage, keyboard_state: &KeyStates, actions: ActionList) -> Option { let list = self.associated_entries(&message); - list.match_mapping(keyboard_state, actions) + list.match_mapping(keyboard_state, actions, &message) } fn associated_entries(&self, message: &InputMapperMessage) -> &KeyMappingEntries { match message { - InputMapperMessage::KeyDown(key) => &self.key_down[*key as usize], - InputMapperMessage::KeyUp(key) => &self.key_up[*key as usize], - InputMapperMessage::KeyDownNoRepeat(key) => &self.key_down_no_repeat[*key as usize], - InputMapperMessage::KeyUpNoRepeat(key) => &self.key_up_no_repeat[*key as usize], + InputMapperMessage::KeyDown(key) | InputMapperMessage::KeyDownNoRepeat(key) => &self.key_down[*key as usize], + InputMapperMessage::KeyUp(key) | InputMapperMessage::KeyUpNoRepeat(key) => &self.key_up[*key as usize], InputMapperMessage::DoubleClick(key) => &self.double_click[*key as usize], InputMapperMessage::DoubleTap(key) => &self.double_tap[*key as usize], InputMapperMessage::WheelScroll => &self.wheel_scroll, @@ -49,13 +45,18 @@ impl Mapping { pub struct KeyMappingEntries(pub Vec); impl KeyMappingEntries { - pub fn match_mapping(&self, keyboard_state: &KeyStates, actions: ActionList) -> Option { + pub fn match_mapping(&self, keyboard_state: &KeyStates, actions: ActionList, input: &InputMapperMessage) -> Option { for mapping in self.0.iter() { // Skip this entry if any of the required modifiers are missing if all_required_modifiers_pressed(keyboard_state, &mapping.modifiers) { // Search for the action in the list of available actions to see if it's currently available to activate let matching_action_found = actions.iter().flatten().any(|action| mapping.action.to_discriminant() == *action); if matching_action_found { + // If the mapping accepts only norepeat then skip. + if mapping.input.is_no_repeat() && !input.is_no_repeat() { + // Using `return` rather than `continue` will avoid falling back to another action + return None; + } return Some(mapping.action.clone()); } } diff --git a/editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs b/editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs index 14a5526a941..2225ef19c51 100644 --- a/editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs +++ b/editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs @@ -76,14 +76,17 @@ impl<'a> MessageHandler { self.update_states_of_modifier_keys(modifier_keys, responses); self.keyboard.unset(key as usize); if !key_repeat { responses.add(InputMapperMessage::KeyUpNoRepeat(key)); + } else { + responses.add(InputMapperMessage::KeyUp(key)); } if let DoubleTapState::SecondTap { key: tapped_key, start_time } = self.double_tap_state && tapped_key == key @@ -97,7 +100,6 @@ impl<'a> MessageHandler { self.double_tap_state = DoubleTapState::Idle; @@ -651,4 +653,31 @@ mod test { key_up(&mut input_preprocessor, Key::Space, &mut responses); assert!(!responses.contains(&InputMapperMessage::DoubleTap(Key::Space).into())); } + + #[test] + /// Only one of `InputMapperMessage::KeyDownNoRepeat` and `InputMapperMessage::KeyDown` is sent + fn process_key_repeats() { + let mut input_preprocessor = InputPreprocessorMessageHandler::default(); + + let key = Key::KeyA; + + for i in 0..5 { + let key_repeat = i == 0; + let modifier_keys = ModifierKeys::empty(); + let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys }; + + let mut responses = VecDeque::new(); + + let context = InputPreprocessorMessageContext { + viewport: &ViewportMessageHandler::default(), + }; + input_preprocessor.process_message(message, &mut responses, context); + + assert_eq!( + responses.pop_front(), + Some(if key_repeat { InputMapperMessage::KeyDown(key) } else { InputMapperMessage::KeyDownNoRepeat(key) }.into()) + ); + assert!(responses.is_empty()); // No more respoonses + } + } }