diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm index 392986e0d01..0f59f61bfb7 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm @@ -50,8 +50,12 @@ case NSEventTypeFlagsChanged: if (event.modifierFlags < _previouslyPressedFlags) { type = @"keyup"; - } else { + } else if (event.modifierFlags > _previouslyPressedFlags) { type = @"keydown"; + } else { + // ignore duplicate modifiers; This can happen in situations like switching + // between application windows when MacOS only sends the up event to new window. + return; } break; default: diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm index 0ee7445efec..01254d6b7c7 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm @@ -170,6 +170,16 @@ TEST(FlutterChannelKeyResponderUnittests, BasicKeyEvent) { [messages removeAllObjects]; [responses removeAllObjects]; + + // RShift up again, should be ignored and not produce a keydown event. + next_response = false; + [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, 60) + callback:^(BOOL handled) { + [responses addObject:@(handled)]; + }]; + + EXPECT_EQ([messages count], 0u); + EXPECT_EQ([responses count], 0u); } TEST(FlutterChannelKeyResponderUnittests, EmptyResponseIsTakenAsHandled) {