Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Fix macOS crash when modifier keys pressed. #23154

Merged
merged 1 commit into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,8 @@ - (void)propagateKeyEvent:(NSEvent*)event ofType:(NSString*)type {
return;
}
}
if ([self.nextResponder respondsToSelector:@selector(keyDown:)]) {
if ([self.nextResponder respondsToSelector:@selector(keyDown:)] &&
event.type == NSEventTypeKeyDown) {
[self.nextResponder keyDown:event];
}
} else if ([type isEqual:@"keyup"]) {
Expand All @@ -513,13 +514,20 @@ - (void)propagateKeyEvent:(NSEvent*)event ofType:(NSString*)type {
return;
}
}
if ([self.nextResponder respondsToSelector:@selector(keyUp:)]) {
if ([self.nextResponder respondsToSelector:@selector(keyUp:)] &&
event.type == NSEventTypeKeyUp) {
[self.nextResponder keyUp:event];
}
}
if ([self.nextResponder respondsToSelector:@selector(flagsChanged:)] &&
event.type == NSEventTypeFlagsChanged) {
[self.nextResponder flagsChanged:event];
}
}

- (void)dispatchKeyEvent:(NSEvent*)event ofType:(NSString*)type {
// Be sure to add a handler in propagateKeyEvent if you allow more event
// types here.
if (event.type != NSEventTypeKeyDown && event.type != NSEventTypeKeyUp &&
event.type != NSEventTypeFlagsChanged) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ @interface FlutterViewControllerTestObjC : NSObject
- (bool)testKeyEventsAreSentToFramework;
- (bool)testKeyEventsArePropagatedIfNotHandled;
- (bool)testKeyEventsAreNotPropagatedIfHandled;
- (bool)testFlagsChangedEventsArePropagatedIfNotHandled;
@end

namespace flutter::testing {
Expand Down Expand Up @@ -98,6 +99,11 @@ id mockViewController(NSString* pasteboardString) {
ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled]);
}

TEST(FlutterViewControllerTest, TestFlagsChangedEventsArePropagatedIfNotHandled) {
ASSERT_TRUE(
[[FlutterViewControllerTestObjC alloc] testFlagsChangedEventsArePropagatedIfNotHandled]);
}

} // namespace flutter::testing

@implementation FlutterViewControllerTestObjC
Expand Down Expand Up @@ -185,6 +191,53 @@ - (bool)testKeyEventsArePropagatedIfNotHandled {
return true;
}

- (bool)testFlagsChangedEventsArePropagatedIfNotHandled {
id engineMock = OCMClassMock([FlutterEngine class]);
id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
[engineMock binaryMessenger])
.andReturn(binaryMessengerMock);
FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
nibName:@""
bundle:nil];
id responderMock = OCMClassMock([FlutterIntermediateKeyResponder class]);
[viewController addKeyResponder:responderMock];
NSDictionary* expectedEvent = @{
@"keymap" : @"macos",
@"type" : @"keydown",
@"keyCode" : @(56), // SHIFT key
@"modifiers" : @(537001986),
};
NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:expectedEvent];
CGEventRef cgEvent = CGEventCreateKeyboardEvent(NULL, 56, TRUE); // SHIFT key
CGEventSetType(cgEvent, kCGEventFlagsChanged);
NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
OCMExpect( // NOLINT(google-objc-avoid-throwing-exception)
[binaryMessengerMock sendOnChannel:@"flutter/keyevent"
message:encodedKeyEvent
binaryReply:[OCMArg any]])
.andDo((^(NSInvocation* invocation) {
FlutterBinaryReply handler;
[invocation getArgument:&handler atIndex:4];
NSDictionary* reply = @{
@"handled" : @(false),
};
NSData* encodedReply = [[FlutterJSONMessageCodec sharedInstance] encode:reply];
handler(encodedReply);
}));
[viewController viewWillAppear]; // Initializes the event channel.
[viewController flagsChanged:event];
@try {
OCMVerify( // NOLINT(google-objc-avoid-throwing-exception)
[binaryMessengerMock sendOnChannel:@"flutter/keyevent"
message:encodedKeyEvent
binaryReply:[OCMArg any]]);
} @catch (...) {
return false;
}
return true;
}

- (bool)testKeyEventsAreNotPropagatedIfHandled {
id engineMock = OCMClassMock([FlutterEngine class]);
id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
Expand Down