Skip to content

Commit fa13fb2

Browse files
authored
Improve no repeat priority (#4597)
* Improve no repeat priority * Bot review * Use KeyDownNoRepeat for tool, mode, and dialog shortcuts
1 parent 347e6ac commit fa13fb2

6 files changed

Lines changed: 93 additions & 80 deletions

File tree

‎editor/src/messages/input_mapper/input_mapper_message.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@ pub enum InputMapperMessage {
2424
PointerShake,
2525
WheelScroll,
2626
}
27+
28+
impl InputMapperMessage {
29+
pub const fn is_no_repeat(&self) -> bool {
30+
matches!(self, InputMapperMessage::KeyDownNoRepeat(_) | InputMapperMessage::KeyUpNoRepeat(_))
31+
}
32+
}

‎editor/src/messages/input_mapper/input_mapper_message_handler.rs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ impl InputMapperMessageHandler {
3737
let all_key_mapping_entries = std::iter::empty()
3838
.chain(self.mapping.key_up.iter())
3939
.chain(self.mapping.key_down.iter())
40-
.chain(self.mapping.key_up_no_repeat.iter())
41-
.chain(self.mapping.key_down_no_repeat.iter())
4240
.chain(self.mapping.double_click.iter())
4341
.chain(self.mapping.double_tap.iter())
4442
.chain(std::iter::once(&self.mapping.wheel_scroll))

‎editor/src/messages/input_mapper/input_mappings.rs‎

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
9999
entry!(KeyDown(MouseLeft); action_dispatch=TransformLayerMessage::ApplyTransformOperation { final_transform: true }),
100100
entry!(KeyDown(MouseRight); action_dispatch=TransformLayerMessage::CancelTransformOperation),
101101
entry!(KeyDown(Escape); action_dispatch=TransformLayerMessage::CancelTransformOperation),
102-
entry!(KeyDown(KeyX); action_dispatch=TransformLayerMessage::ConstrainX),
103-
entry!(KeyDown(KeyY); action_dispatch=TransformLayerMessage::ConstrainY),
102+
entry!(KeyDownNoRepeat(KeyX); action_dispatch=TransformLayerMessage::ConstrainX),
103+
entry!(KeyDownNoRepeat(KeyY); action_dispatch=TransformLayerMessage::ConstrainY),
104104
entry!(KeyDown(Backspace); action_dispatch=TransformLayerMessage::TypeBackspace),
105105
entry!(KeyDown(Minus); action_dispatch=TransformLayerMessage::TypeNegate),
106106
entry!(KeyDown(Comma); action_dispatch=TransformLayerMessage::TypeDecimalPoint),
@@ -230,9 +230,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
230230
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 }),
231231
entry!(KeyDown(MouseRight); action_dispatch=PathToolMessage::RightClick),
232232
entry!(KeyDown(Escape); action_dispatch=PathToolMessage::Escape),
233-
entry!(KeyDown(KeyG); action_dispatch=PathToolMessage::GRS { key: KeyG }),
234-
entry!(KeyDown(KeyR); action_dispatch=PathToolMessage::GRS { key: KeyR }),
235-
entry!(KeyDown(KeyS); action_dispatch=PathToolMessage::GRS { key: KeyS }),
233+
entry!(KeyDownNoRepeat(KeyG); action_dispatch=PathToolMessage::GRS { key: KeyG }),
234+
entry!(KeyDownNoRepeat(KeyR); action_dispatch=PathToolMessage::GRS { key: KeyR }),
235+
entry!(KeyDownNoRepeat(KeyS); action_dispatch=PathToolMessage::GRS { key: KeyS }),
236236
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 }),
237237
entry!(KeyDown(Delete); action_dispatch=PathToolMessage::Delete),
238238
entry!(KeyDown(KeyA); modifiers=[Accel], action_dispatch=PathToolMessage::SelectAll),
@@ -278,9 +278,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
278278
entry!(KeyDown(Enter); action_dispatch=PenToolMessage::Confirm),
279279
entry!(KeyDown(Delete); action_dispatch=PenToolMessage::RemovePreviousHandle),
280280
entry!(KeyDown(Backspace); action_dispatch=PenToolMessage::RemovePreviousHandle),
281-
entry!(KeyDown(KeyG); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
282-
entry!(KeyDown(KeyR); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
283-
entry!(KeyDown(KeyS); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
281+
entry!(KeyDownNoRepeat(KeyG); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
282+
entry!(KeyDownNoRepeat(KeyR); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
283+
entry!(KeyDownNoRepeat(KeyS); action_dispatch=PenToolMessage::GRS { grab: KeyG, rotate: KeyR, scale: KeyS }),
284284
//
285285
// FreehandToolMessage
286286
entry!(PointerMove; action_dispatch=FreehandToolMessage::PointerMove),
@@ -315,37 +315,36 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
315315
entry!(KeyDown(Escape); action_dispatch=BrushToolMessage::Abort),
316316
//
317317
// ToolMessage
318-
entry!(KeyDown(KeyV); action_dispatch=ToolMessage::ActivateToolSelect),
319-
entry!(KeyDown(KeyZ); action_dispatch=ToolMessage::ActivateToolNavigate),
320-
entry!(KeyDown(KeyI); action_dispatch=ToolMessage::ActivateToolEyedropper),
321-
entry!(KeyDown(KeyT); action_dispatch=ToolMessage::ActivateToolText),
322-
entry!(KeyDown(KeyF); action_dispatch=ToolMessage::ActivateToolFill),
323-
entry!(KeyDown(KeyH); action_dispatch=ToolMessage::ActivateToolGradient),
324-
entry!(KeyDown(KeyA); action_dispatch=ToolMessage::ActivateToolPath),
325-
entry!(KeyDown(KeyP); action_dispatch=ToolMessage::ActivateToolPen),
326-
entry!(KeyDown(KeyN); action_dispatch=ToolMessage::ActivateToolFreehand),
327-
entry!(KeyDown(KeyL); action_dispatch=ToolMessage::ActivateToolShapeLine),
328-
entry!(KeyDown(KeyM); action_dispatch=ToolMessage::ActivateToolShapeRectangle),
329-
entry!(KeyDown(KeyE); action_dispatch=ToolMessage::ActivateToolShapeEllipse),
330-
entry!(KeyDown(KeyY); action_dispatch=ToolMessage::ActivateToolShape),
331-
entry!(KeyDown(KeyB); action_dispatch=ToolMessage::ActivateToolBrush),
318+
entry!(KeyDownNoRepeat(KeyV); action_dispatch=ToolMessage::ActivateToolSelect),
319+
entry!(KeyDownNoRepeat(KeyZ); action_dispatch=ToolMessage::ActivateToolNavigate),
320+
entry!(KeyDownNoRepeat(KeyI); action_dispatch=ToolMessage::ActivateToolEyedropper),
321+
entry!(KeyDownNoRepeat(KeyT); action_dispatch=ToolMessage::ActivateToolText),
322+
entry!(KeyDownNoRepeat(KeyF); action_dispatch=ToolMessage::ActivateToolFill),
323+
entry!(KeyDownNoRepeat(KeyH); action_dispatch=ToolMessage::ActivateToolGradient),
324+
entry!(KeyDownNoRepeat(KeyA); action_dispatch=ToolMessage::ActivateToolPath),
325+
entry!(KeyDownNoRepeat(KeyP); action_dispatch=ToolMessage::ActivateToolPen),
326+
entry!(KeyDownNoRepeat(KeyN); action_dispatch=ToolMessage::ActivateToolFreehand),
327+
entry!(KeyDownNoRepeat(KeyL); action_dispatch=ToolMessage::ActivateToolShapeLine),
328+
entry!(KeyDownNoRepeat(KeyM); action_dispatch=ToolMessage::ActivateToolShapeRectangle),
329+
entry!(KeyDownNoRepeat(KeyE); action_dispatch=ToolMessage::ActivateToolShapeEllipse),
330+
entry!(KeyDownNoRepeat(KeyY); action_dispatch=ToolMessage::ActivateToolShape),
331+
entry!(KeyDownNoRepeat(KeyB); action_dispatch=ToolMessage::ActivateToolBrush),
332332
entry!(KeyDown(KeyD); action_dispatch=ToolMessage::ResetColors),
333333
entry!(KeyDown(KeyX); modifiers=[Shift], action_dispatch=ToolMessage::SwapColors),
334334
entry!(KeyDown(KeyC); modifiers=[Alt], action_dispatch=ToolMessage::SelectRandomWorkingColor { primary: true }),
335335
entry!(KeyDown(KeyC); modifiers=[Alt, Shift], action_dispatch=ToolMessage::SelectRandomWorkingColor { primary: false }),
336-
// TODO: Change to KeyDownNoRepeat when https://github.com/GraphiteEditor/Graphite/issues/2266 is resolved
337-
entry!(KeyDown(Tab); action_dispatch=ToolMessage::ToggleSelectVsPath),
336+
entry!(KeyDownNoRepeat(Tab); action_dispatch=ToolMessage::ToggleSelectVsPath),
338337
//
339338
// DocumentMessage
340339
entry!(DoubleTap(Space); action_dispatch=DocumentMessage::GraphViewOverlayToggle),
341340
entry!(KeyDownNoRepeat(Escape); action_dispatch=DocumentMessage::Escape),
342341
entry!(KeyDown(Delete); action_dispatch=DocumentMessage::DeleteSelectedLayers),
343342
entry!(KeyDown(Backspace); action_dispatch=DocumentMessage::DeleteSelectedLayers),
344-
entry!(KeyDown(KeyO); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleOverlaysVisibility),
345-
entry!(KeyDown(KeyS); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleSnapping),
343+
entry!(KeyDownNoRepeat(KeyO); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleOverlaysVisibility),
344+
entry!(KeyDownNoRepeat(KeyS); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleSnapping),
346345
entry!(KeyDown(KeyH); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedVisibility),
347-
entry!(KeyDown(KeyL); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedLocked),
348-
entry!(KeyDown(KeyG); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleGridVisibility),
346+
entry!(KeyDownNoRepeat(KeyL); modifiers=[Accel], action_dispatch=DocumentMessage::ToggleSelectedLocked),
347+
entry!(KeyDownNoRepeat(KeyG); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleGridVisibility),
349348
entry!(KeyDown(KeyZ); modifiers=[Accel, Shift], canonical, action_dispatch=DocumentMessage::Redo),
350349
entry!(KeyDown(KeyY); modifiers=[Accel], action_dispatch=DocumentMessage::Redo),
351350
entry!(KeyDown(KeyZ); modifiers=[Accel], action_dispatch=DocumentMessage::Undo),
@@ -398,9 +397,9 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
398397
entry!(KeyDown(ArrowRight); action_dispatch=DocumentMessage::NudgeSelectedLayers { delta_x: NUDGE_AMOUNT, delta_y: 0., resize: Alt, resize_opposite: Control }),
399398
//
400399
// TransformLayerMessage
401-
entry!(KeyDown(KeyG); action_dispatch=TransformLayerMessage::BeginGrab),
402-
entry!(KeyDown(KeyR); action_dispatch=TransformLayerMessage::BeginRotate),
403-
entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginScale),
400+
entry!(KeyDownNoRepeat(KeyG); action_dispatch=TransformLayerMessage::BeginGrab),
401+
entry!(KeyDownNoRepeat(KeyR); action_dispatch=TransformLayerMessage::BeginRotate),
402+
entry!(KeyDownNoRepeat(KeyS); action_dispatch=TransformLayerMessage::BeginScale),
404403
entry!(KeyDown(Digit0); action_dispatch=TransformLayerMessage::TypeDigit { digit: 0 }),
405404
entry!(KeyDown(Digit1); action_dispatch=TransformLayerMessage::TypeDigit { digit: 1 }),
406405
entry!(KeyDown(Digit2); action_dispatch=TransformLayerMessage::TypeDigit { digit: 2 }),
@@ -452,16 +451,16 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
452451
entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument),
453452
entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation),
454453
entry!(KeyDown(KeyW); modifiers=[Accel, Alt], action_dispatch=PortfolioMessage::CloseAllDocumentsWithConfirmation),
455-
entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=IngestMessage::Open),
456-
entry!(KeyDown(KeyI); modifiers=[Accel], action_dispatch=IngestMessage::Import),
457-
entry!(KeyDown(KeyR); modifiers=[Alt], action_dispatch=PortfolioMessage::ToggleRulers),
454+
entry!(KeyDownNoRepeat(KeyO); modifiers=[Accel], action_dispatch=IngestMessage::Open),
455+
entry!(KeyDownNoRepeat(KeyI); modifiers=[Accel], action_dispatch=IngestMessage::Import),
456+
entry!(KeyDownNoRepeat(KeyR); modifiers=[Alt], action_dispatch=PortfolioMessage::ToggleRulers),
458457
entry!(KeyDown(KeyD); modifiers=[Alt], action_dispatch=WorkspaceMessage::ToggleDataPanelOpen),
459458
entry!(KeyDown(Enter); modifiers=[Alt], action_dispatch=WorkspaceMessage::ToggleFocusDocument),
460459
//
461460
// DialogMessage
462-
entry!(KeyDown(KeyE); modifiers=[Accel], action_dispatch=DialogMessage::RequestExportDialog),
463-
entry!(KeyDown(KeyN); modifiers=[Accel], action_dispatch=DialogMessage::RequestNewDocumentDialog),
464-
entry!(KeyDown(Comma); modifiers=[Accel], action_dispatch=DialogMessage::RequestPreferencesDialog),
461+
entry!(KeyDownNoRepeat(KeyE); modifiers=[Accel], action_dispatch=DialogMessage::RequestExportDialog),
462+
entry!(KeyDownNoRepeat(KeyN); modifiers=[Accel], action_dispatch=DialogMessage::RequestNewDocumentDialog),
463+
entry!(KeyDownNoRepeat(Comma); modifiers=[Accel], action_dispatch=DialogMessage::RequestPreferencesDialog),
465464
//
466465
// DebugMessage
467466
entry!(KeyDown(Digit0); modifiers=[Alt], action_dispatch=DebugMessage::MessageOff),
@@ -471,35 +470,33 @@ pub fn input_mappings(zoom_with_scroll: bool) -> Mapping {
471470
entry!(KeyDown(Space); modifiers=[Shift], action_dispatch=AnimationMessage::ToggleLivePreview),
472471
entry!(KeyDown(Home); modifiers=[Shift], action_dispatch=AnimationMessage::RestartAnimation),
473472
];
474-
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;
473+
let (mut key_up, mut key_down, mut double_click, mut double_tap, mut wheel_scroll, mut pointer_move, mut pointer_shake) = mappings;
475474

476475
let sort = |list: &mut KeyMappingEntries| list.0.sort_by_key(|entry| std::cmp::Reverse(entry.modifiers.count_ones()));
477-
// Sort the sublists of `key_up`, `key_down`, `key_up_no_repeat`, and `key_down_no_repeat`
478-
for list in [&mut key_up, &mut key_down, &mut key_up_no_repeat, &mut key_down_no_repeat] {
476+
477+
for list in [&mut key_up, &mut key_down] {
479478
for sublist in list {
480479
sort(sublist);
481480
}
482481
}
483-
// Sort the sublists of `double_click`
482+
484483
for sublist in &mut double_click {
485484
sort(sublist)
486485
}
487-
// Sort the sublists of `double_tap`
486+
488487
for sublist in &mut double_tap {
489488
sort(sublist)
490489
}
491-
// Sort `wheel_scroll`
490+
492491
sort(&mut wheel_scroll);
493-
// Sort `pointer_move`
492+
494493
sort(&mut pointer_move);
495-
// Sort `pointer_shake`
494+
496495
sort(&mut pointer_shake);
497496

498497
Mapping {
499498
key_up,
500499
key_down,
501-
key_up_no_repeat,
502-
key_down_no_repeat,
503500
double_click,
504501
double_tap,
505502
wheel_scroll,

‎editor/src/messages/input_mapper/utility_types/macros.rs‎

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,6 @@ macro_rules! entry {
8888
canonical: $canonical,
8989
disabled: $disabled,
9090
},
91-
MappingEntry {
92-
action: $action_dispatch.into(),
93-
input: InputMapperMessage::KeyDownNoRepeat(Key::$refresh),
94-
modifiers: modifiers!(),
95-
canonical: $canonical,
96-
disabled: $disabled,
97-
},
98-
MappingEntry {
99-
action: $action_dispatch.into(),
100-
input: InputMapperMessage::KeyUpNoRepeat(Key::$refresh),
101-
modifiers: modifiers!(),
102-
canonical: $canonical,
103-
disabled: $disabled,
104-
},
10591
)*
10692
]]
10793
};
@@ -116,8 +102,6 @@ macro_rules! mapping {
116102
[$($entry:expr_2021),* $(,)?] => {{
117103
let mut key_up = KeyMappingEntries::key_array();
118104
let mut key_down = KeyMappingEntries::key_array();
119-
let mut key_up_no_repeat = KeyMappingEntries::key_array();
120-
let mut key_down_no_repeat = KeyMappingEntries::key_array();
121105
let mut double_click = KeyMappingEntries::mouse_buttons_arrays();
122106
let mut double_tap = KeyMappingEntries::key_array();
123107
let mut wheel_scroll = KeyMappingEntries::new();
@@ -134,10 +118,8 @@ macro_rules! mapping {
134118
}
135119

136120
let corresponding_list = match entry.input {
137-
InputMapperMessage::KeyDown(key) => &mut key_down[key as usize],
138-
InputMapperMessage::KeyUp(key) => &mut key_up[key as usize],
139-
InputMapperMessage::KeyDownNoRepeat(key) => &mut key_down_no_repeat[key as usize],
140-
InputMapperMessage::KeyUpNoRepeat(key) => &mut key_up_no_repeat[key as usize],
121+
InputMapperMessage::KeyDown(key) | InputMapperMessage::KeyDownNoRepeat(key) => &mut key_down[key as usize],
122+
InputMapperMessage::KeyUp(key) | InputMapperMessage::KeyUpNoRepeat(key) => &mut key_up[key as usize],
141123
InputMapperMessage::DoubleClick(key) => &mut double_click[key as usize],
142124
InputMapperMessage::DoubleTap(key) => &mut double_tap[key as usize],
143125
InputMapperMessage::WheelScroll => &mut wheel_scroll,
@@ -150,7 +132,7 @@ macro_rules! mapping {
150132
}
151133
)*
152134

153-
(key_up, key_down, key_up_no_repeat, key_down_no_repeat, double_click, double_tap, wheel_scroll, pointer_move, pointer_shake)
135+
(key_up, key_down, double_click, double_tap, wheel_scroll, pointer_move, pointer_shake)
154136
}};
155137
}
156138

‎editor/src/messages/input_mapper/utility_types/misc.rs‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ use core::time::Duration;
99
pub struct Mapping {
1010
pub key_up: [KeyMappingEntries; NUMBER_OF_KEYS],
1111
pub key_down: [KeyMappingEntries; NUMBER_OF_KEYS],
12-
pub key_up_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS],
13-
pub key_down_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS],
1412
pub double_click: [KeyMappingEntries; NUMBER_OF_MOUSE_BUTTONS],
1513
pub double_tap: [KeyMappingEntries; NUMBER_OF_KEYS],
1614
pub wheel_scroll: KeyMappingEntries,
@@ -27,15 +25,13 @@ impl Default for Mapping {
2725
impl Mapping {
2826
pub fn match_input_message(&self, message: InputMapperMessage, keyboard_state: &KeyStates, actions: ActionList) -> Option<Message> {
2927
let list = self.associated_entries(&message);
30-
list.match_mapping(keyboard_state, actions)
28+
list.match_mapping(keyboard_state, actions, &message)
3129
}
3230

3331
fn associated_entries(&self, message: &InputMapperMessage) -> &KeyMappingEntries {
3432
match message {
35-
InputMapperMessage::KeyDown(key) => &self.key_down[*key as usize],
36-
InputMapperMessage::KeyUp(key) => &self.key_up[*key as usize],
37-
InputMapperMessage::KeyDownNoRepeat(key) => &self.key_down_no_repeat[*key as usize],
38-
InputMapperMessage::KeyUpNoRepeat(key) => &self.key_up_no_repeat[*key as usize],
33+
InputMapperMessage::KeyDown(key) | InputMapperMessage::KeyDownNoRepeat(key) => &self.key_down[*key as usize],
34+
InputMapperMessage::KeyUp(key) | InputMapperMessage::KeyUpNoRepeat(key) => &self.key_up[*key as usize],
3935
InputMapperMessage::DoubleClick(key) => &self.double_click[*key as usize],
4036
InputMapperMessage::DoubleTap(key) => &self.double_tap[*key as usize],
4137
InputMapperMessage::WheelScroll => &self.wheel_scroll,
@@ -49,13 +45,18 @@ impl Mapping {
4945
pub struct KeyMappingEntries(pub Vec<MappingEntry>);
5046

5147
impl KeyMappingEntries {
52-
pub fn match_mapping(&self, keyboard_state: &KeyStates, actions: ActionList) -> Option<Message> {
48+
pub fn match_mapping(&self, keyboard_state: &KeyStates, actions: ActionList, input: &InputMapperMessage) -> Option<Message> {
5349
for mapping in self.0.iter() {
5450
// Skip this entry if any of the required modifiers are missing
5551
if all_required_modifiers_pressed(keyboard_state, &mapping.modifiers) {
5652
// Search for the action in the list of available actions to see if it's currently available to activate
5753
let matching_action_found = actions.iter().flatten().any(|action| mapping.action.to_discriminant() == *action);
5854
if matching_action_found {
55+
// If the mapping accepts only norepeat then skip.
56+
if mapping.input.is_no_repeat() && !input.is_no_repeat() {
57+
// Using `return` rather than `continue` will avoid falling back to another action
58+
return None;
59+
}
5960
return Some(mapping.action.clone());
6061
}
6162
}

‎editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,17 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
7676
};
7777

7878
responses.add(InputMapperMessage::KeyDownNoRepeat(key));
79+
} else {
80+
responses.add(InputMapperMessage::KeyDown(key));
7981
}
80-
responses.add(InputMapperMessage::KeyDown(key));
8182
}
8283
InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys } => {
8384
self.update_states_of_modifier_keys(modifier_keys, responses);
8485
self.keyboard.unset(key as usize);
8586
if !key_repeat {
8687
responses.add(InputMapperMessage::KeyUpNoRepeat(key));
88+
} else {
89+
responses.add(InputMapperMessage::KeyUp(key));
8790
}
8891
if let DoubleTapState::SecondTap { key: tapped_key, start_time } = self.double_tap_state
8992
&& tapped_key == key
@@ -97,7 +100,6 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
97100
responses.add(InputMapperMessage::DoubleTap(key));
98101
}
99102
}
100-
responses.add(InputMapperMessage::KeyUp(key));
101103
}
102104
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
103105
self.double_tap_state = DoubleTapState::Idle;
@@ -651,4 +653,31 @@ mod test {
651653
key_up(&mut input_preprocessor, Key::Space, &mut responses);
652654
assert!(!responses.contains(&InputMapperMessage::DoubleTap(Key::Space).into()));
653655
}
656+
657+
#[test]
658+
/// Only one of `InputMapperMessage::KeyDownNoRepeat` and `InputMapperMessage::KeyDown` is sent
659+
fn process_key_repeats() {
660+
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
661+
662+
let key = Key::KeyA;
663+
664+
for i in 0..5 {
665+
let key_repeat = i == 0;
666+
let modifier_keys = ModifierKeys::empty();
667+
let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys };
668+
669+
let mut responses = VecDeque::new();
670+
671+
let context = InputPreprocessorMessageContext {
672+
viewport: &ViewportMessageHandler::default(),
673+
};
674+
input_preprocessor.process_message(message, &mut responses, context);
675+
676+
assert_eq!(
677+
responses.pop_front(),
678+
Some(if key_repeat { InputMapperMessage::KeyDown(key) } else { InputMapperMessage::KeyDownNoRepeat(key) }.into())
679+
);
680+
assert!(responses.is_empty()); // No more respoonses
681+
}
682+
}
654683
}

0 commit comments

Comments
 (0)