Skip to content

Commit 5fb4a53

Browse files
authored
[macos] [NSViewController viewWillAppear] can be called multiple times (flutter#34072)
Fixes flutter#105963
1 parent e698079 commit 5fb4a53

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

shell/platform/darwin/macos/framework/Source/FlutterViewController.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,11 @@ - (BOOL)launchEngine {
429429
// ViewController as a listener for a keyUp event before it's handled by NSApplication, and should
430430
// NOT modify the event to avoid any unexpected behavior.
431431
- (void)listenForMetaModifiedKeyUpEvents {
432-
NSAssert(_keyUpMonitor == nil, @"_keyUpMonitor was already created");
432+
if (_keyUpMonitor != nil) {
433+
// It is possible for [NSViewController viewWillAppear] to be invoked multiple times
434+
// in a row. https://github.com/flutter/flutter/issues/105963
435+
return;
436+
}
433437
FlutterViewController* __weak weakSelf = self;
434438
_keyUpMonitor = [NSEvent
435439
addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp

shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ - (bool)testKeyEventsAreNotPropagatedIfHandled;
2222
- (bool)testFlagsChangedEventsArePropagatedIfNotHandled;
2323
- (bool)testKeyboardIsRestartedOnEngineRestart;
2424
- (bool)testTrackpadGesturesAreSentToFramework;
25+
- (bool)testViewWillAppearCalledMultipleTimes;
2526

2627
+ (void)respondFalseForSendEvent:(const FlutterKeyEvent&)event
2728
callback:(nullable FlutterKeyEventCallback)callback
@@ -134,6 +135,10 @@ + (void)respondFalseForSendEvent:(const FlutterKeyEvent&)event
134135
ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testTrackpadGesturesAreSentToFramework]);
135136
}
136137

138+
TEST(FlutterViewControllerTest, testViewWillAppearCalledMultipleTimes) {
139+
ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewWillAppearCalledMultipleTimes]);
140+
}
141+
137142
} // namespace flutter::testing
138143

139144
@implementation FlutterViewControllerTestObjC
@@ -518,4 +523,14 @@ - (bool)testTrackpadGesturesAreSentToFramework {
518523
return true;
519524
}
520525

526+
- (bool)testViewWillAppearCalledMultipleTimes {
527+
id engineMock = OCMClassMock([FlutterEngine class]);
528+
FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
529+
nibName:@""
530+
bundle:nil];
531+
[viewController viewWillAppear];
532+
[viewController viewWillAppear];
533+
return true;
534+
}
535+
521536
@end

0 commit comments

Comments
 (0)