From ab4d9a9f73843486f39e8874afb303d3d5b9f0d9 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Sat, 31 Jul 2021 03:00:54 +0200 Subject: [PATCH] Do not generate keydown event for empty modifier flags (#27817) * Do not generate keydown event for empty modifier flags * Mask 0x100 bit instead of comparison * Comment * Update comment * comment * Add comment --- .../framework/Source/FlutterChannelKeyResponder.mm | 8 +++++--- .../Source/FlutterChannelKeyResponderUnittests.mm | 13 ++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm b/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm index b6aaae1376247..29436dec17ea1 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm @@ -39,6 +39,8 @@ - (nonnull instancetype)initWithChannel:(nonnull FlutterBasicMessageChannel*)cha } - (void)handleEvent:(NSEvent*)event callback:(FlutterAsyncKeyCallback)callback { + // Remove the modifier bits that Flutter is not interested in. + NSEventModifierFlags modifierFlags = event.modifierFlags & ~0x100; NSString* type; switch (event.type) { case NSEventTypeKeyDown: @@ -48,9 +50,9 @@ - (void)handleEvent:(NSEvent*)event callback:(FlutterAsyncKeyCallback)callback { type = @"keyup"; break; case NSEventTypeFlagsChanged: - if (event.modifierFlags < _previouslyPressedFlags) { + if (modifierFlags < _previouslyPressedFlags) { type = @"keyup"; - } else if (event.modifierFlags > _previouslyPressedFlags) { + } else if (modifierFlags > _previouslyPressedFlags) { type = @"keydown"; } else { // ignore duplicate modifiers; This can happen in situations like switching @@ -61,7 +63,7 @@ - (void)handleEvent:(NSEvent*)event callback:(FlutterAsyncKeyCallback)callback { default: NSAssert(false, @"Unexpected key event type (got %lu).", event.type); } - _previouslyPressedFlags = event.modifierFlags; + _previouslyPressedFlags = modifierFlags; NSMutableDictionary* keyMessage = [@{ @"keymap" : @"macos", @"type" : type, diff --git a/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm b/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm index 01254d6b7c780..d5629e900bea8 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponderUnittests.mm @@ -52,9 +52,20 @@ callback(keyMessage); })); - // Key down FlutterChannelKeyResponder* responder = [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel]; + + // Initial empty modifiers. This can happen when user opens window while modifier key is pressed + // and then releases the modifier. Shouldn't result in an event being sent. + // Regression test for https://github.com/flutter/flutter/issues/87339. + [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, 60) + callback:^(BOOL handled) { + [responses addObject:@(handled)]; + }]; + + EXPECT_EQ([messages count], 0u); + + // Key down [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", FALSE, 0) callback:^(BOOL handled) { [responses addObject:@(handled)];