@@ -186,6 +186,7 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
186186
187187 const bool is_event_down = action == WM_KEYDOWN || action == WM_SYSKEYDOWN;
188188
189+ bool event_key_can_be_repeat = true ;
189190 UpdateLastSeenCritialKey (key, physical_key, sequence_logical_key);
190191 // Synchronize the toggled states of critical keys (such as whether CapsLocks
191192 // is enabled). Toggled states can only be changed upon a down event, so if
@@ -197,14 +198,14 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
197198 // updated to the true state, while the critical keys whose toggled state have
198199 // been changed will be pressed regardless of their true pressed state.
199200 // Updating the pressed state will be done by SynchronizeCritialPressedStates.
200- SynchronizeCritialToggledStates (key, is_event_down);
201+ SynchronizeCritialToggledStates (key, is_event_down, &event_key_can_be_repeat );
201202 // Synchronize the pressed states of critical keys (such as whether CapsLocks
202203 // is pressed).
203204 //
204205 // After this function, all critical keys except for the target key will have
205206 // their toggled state and pressed state matched with their true states. The
206207 // target key's pressed state will be updated immediately after this.
207- SynchronizeCritialPressedStates (key, physical_key, is_event_down);
208+ SynchronizeCritialPressedStates (key, physical_key, is_event_down, event_key_can_be_repeat );
208209
209210 // The resulting event's `type`.
210211 FlutterKeyEventType type;
@@ -340,7 +341,8 @@ void KeyboardKeyEmbedderHandler::UpdateLastSeenCritialKey(
340341
341342void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates (
342343 int event_virtual_key,
343- bool is_event_down) {
344+ bool is_event_down,
345+ bool * event_key_can_be_repeat) {
344346 // NowState ----------------> PreEventState --------------> TrueState
345347 // Synchronization Event
346348 for (auto & kv : critical_keys_) {
@@ -385,6 +387,7 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
385387 key_info.physical_key ,
386388 key_info.logical_key , empty_character),
387389 nullptr , nullptr );
390+ *event_key_can_be_repeat = false ;
388391 }
389392 key_info.toggled_on = true_toggled;
390393 }
@@ -394,7 +397,8 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
394397void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates (
395398 int event_virtual_key,
396399 int event_physical_key,
397- bool is_event_down) {
400+ bool is_event_down,
401+ bool event_key_can_be_repeat) {
398402 // During an incoming event, there might be a synthesized Flutter event for
399403 // each key of each pressing goal, followed by an eventual main Flutter
400404 // event.
@@ -424,8 +428,18 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates(
424428 if (is_event_down) {
425429 // For down events, this key is the event key if they have the same
426430 // virtual key, because virtual key represents "functionality."
431+ //
432+ // In that case, normally Flutter should synthesize nothing since the
433+ // resulting event can adapt to the current state by flexing between a
434+ // down and a repeat event. However, in certain cases (when Flutter has
435+ // just synchronized the key's toggling state) the event must not be a
436+ // repeat event.
427437 if (virtual_key == event_virtual_key) {
428- pre_event_pressed = false ;
438+ if (event_key_can_be_repeat) {
439+ continue ;
440+ } else {
441+ pre_event_pressed = false ;
442+ }
429443 }
430444 } else {
431445 // For up events, this key is the event key if they have the same
0 commit comments