mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix macOS crash when modifier keys pressed. (flutter/engine#23154)
This fixes a problem with the macOS key handling where a flagsChanged event is being sent to a keyDown selector.
This commit is contained in:
parent
78b1abc9c4
commit
3384cb61ba
@ -504,7 +504,8 @@ static void CommonInit(FlutterViewController* controller) {
|
||||
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"]) {
|
||||
@ -513,13 +514,20 @@ static void CommonInit(FlutterViewController* controller) {
|
||||
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;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
- (bool)testKeyEventsAreSentToFramework;
|
||||
- (bool)testKeyEventsArePropagatedIfNotHandled;
|
||||
- (bool)testKeyEventsAreNotPropagatedIfHandled;
|
||||
- (bool)testFlagsChangedEventsArePropagatedIfNotHandled;
|
||||
@end
|
||||
|
||||
namespace flutter::testing {
|
||||
@ -98,6 +99,11 @@ TEST(FlutterViewControllerTest, TestKeyEventsAreNotPropagatedIfHandled) {
|
||||
ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled]);
|
||||
}
|
||||
|
||||
TEST(FlutterViewControllerTest, TestFlagsChangedEventsArePropagatedIfNotHandled) {
|
||||
ASSERT_TRUE(
|
||||
[[FlutterViewControllerTestObjC alloc] testFlagsChangedEventsArePropagatedIfNotHandled]);
|
||||
}
|
||||
|
||||
} // namespace flutter::testing
|
||||
|
||||
@implementation FlutterViewControllerTestObjC
|
||||
@ -185,6 +191,53 @@ TEST(FlutterViewControllerTest, TestKeyEventsAreNotPropagatedIfHandled) {
|
||||
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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user