|
19 | 19 | #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"
|
20 | 20 | #include "flutter/shell/platform/embedder/embedder.h"
|
21 | 21 |
|
| 22 | +const uint64_t kFlutterDefaultViewId = 0; |
| 23 | + |
22 | 24 | /**
|
23 | 25 | * Constructs and returns a FlutterLocale struct corresponding to |locale|, which must outlive
|
24 | 26 | * the returned struct.
|
@@ -80,6 +82,8 @@ @interface FlutterEngine () <FlutterBinaryMessenger>
|
80 | 82 | */
|
81 | 83 | @property(nonatomic, strong) NSMutableArray<NSNumber*>* isResponseValid;
|
82 | 84 |
|
| 85 | +- (nullable FlutterViewController*)viewControllerForId:(uint64_t)viewId; |
| 86 | + |
83 | 87 | /**
|
84 | 88 | * Sends the list of user-preferred locales to the Flutter engine.
|
85 | 89 | */
|
@@ -213,8 +217,6 @@ @implementation FlutterEngine {
|
213 | 217 | // when the engine is destroyed.
|
214 | 218 | std::unique_ptr<flutter::FlutterCompositor> _macOSCompositor;
|
215 | 219 |
|
216 |
| - FlutterViewEngineProvider* _viewProvider; |
217 |
| - |
218 | 220 | // FlutterCompositor is copied and used in embedder.cc.
|
219 | 221 | FlutterCompositor _compositor;
|
220 | 222 |
|
@@ -248,7 +250,6 @@ - (instancetype)initWithName:(NSString*)labelPrefix
|
248 | 250 | _currentMessengerConnection = 1;
|
249 | 251 | _allowHeadlessExecution = allowHeadlessExecution;
|
250 | 252 | _semanticsEnabled = NO;
|
251 |
| - _viewProvider = [[FlutterViewEngineProvider alloc] initWithEngine:self]; |
252 | 253 | _isResponseValid = [[NSMutableArray alloc] initWithCapacity:1];
|
253 | 254 | [_isResponseValid addObject:@YES];
|
254 | 255 |
|
@@ -411,29 +412,41 @@ - (void)loadAOTData:(NSString*)assetsDir {
|
411 | 412 | }
|
412 | 413 |
|
413 | 414 | - (void)setViewController:(FlutterViewController*)controller {
|
414 |
| - if (_viewController != controller) { |
| 415 | + if (_viewController == controller) { |
| 416 | + // From nil to nil, or from non-nil to the same controller. |
| 417 | + return; |
| 418 | + } |
| 419 | + if (_viewController == nil && controller != nil) { |
| 420 | + // From nil to non-nil. |
| 421 | + NSAssert(controller.engine == nil, |
| 422 | + @"Failed to set view controller to the engine: " |
| 423 | + @"The given FlutterViewController is already attached to an engine %@. " |
| 424 | + @"If you wanted to create an FlutterViewController and set it to an existing engine, " |
| 425 | + @"you should create it with init(engine:, nibName, bundle:) instead.", |
| 426 | + controller.engine); |
415 | 427 | _viewController = controller;
|
416 |
| - |
417 |
| - if (_semanticsEnabled && _bridge) { |
418 |
| - _bridge->UpdateDefaultViewController(_viewController); |
419 |
| - } |
420 |
| - |
421 |
| - if (!controller && !_allowHeadlessExecution) { |
| 428 | + [_viewController attachToEngine:self withId:kFlutterDefaultViewId]; |
| 429 | + } else if (_viewController != nil && controller == nil) { |
| 430 | + // From non-nil to nil. |
| 431 | + [_viewController detachFromEngine]; |
| 432 | + _viewController = nil; |
| 433 | + if (!_allowHeadlessExecution) { |
422 | 434 | [self shutDownEngine];
|
423 | 435 | }
|
| 436 | + } else { |
| 437 | + // From non-nil to a different non-nil view controller. |
| 438 | + NSAssert(NO, |
| 439 | + @"Failed to set view controller to the engine: " |
| 440 | + @"The engine already has a default view controller %@. " |
| 441 | + @"If you wanted to make the default view render in a different window, " |
| 442 | + @"you should attach the current view controller to the window instead.", |
| 443 | + _viewController); |
424 | 444 | }
|
425 | 445 | }
|
426 | 446 |
|
427 | 447 | - (FlutterCompositor*)createFlutterCompositor {
|
428 |
| - // TODO(richardjcai): Add support for creating a FlutterCompositor |
429 |
| - // with a nil _viewController for headless engines. |
430 |
| - // https://github.com/flutter/flutter/issues/71606 |
431 |
| - if (!_viewController) { |
432 |
| - return nil; |
433 |
| - } |
434 |
| - |
435 |
| - _macOSCompositor = |
436 |
| - std::make_unique<flutter::FlutterCompositor>(_viewProvider, _platformViewController); |
| 448 | + _macOSCompositor = std::make_unique<flutter::FlutterCompositor>( |
| 449 | + [[FlutterViewEngineProvider alloc] initWithEngine:self], _platformViewController); |
437 | 450 |
|
438 | 451 | _compositor = {};
|
439 | 452 | _compositor.struct_size = sizeof(FlutterCompositor);
|
@@ -539,10 +552,10 @@ - (nonnull NSString*)executableName {
|
539 | 552 | }
|
540 | 553 |
|
541 | 554 | - (void)updateWindowMetrics {
|
542 |
| - if (!_engine || !_viewController.viewLoaded) { |
| 555 | + if (!_engine || !self.viewController.viewLoaded) { |
543 | 556 | return;
|
544 | 557 | }
|
545 |
| - NSView* view = _viewController.flutterView; |
| 558 | + NSView* view = self.viewController.flutterView; |
546 | 559 | CGRect scaledBounds = [view convertRectToBacking:view.bounds];
|
547 | 560 | CGSize scaledSize = scaledBounds.size;
|
548 | 561 | double pixelRatio = view.bounds.size.width == 0 ? 1 : scaledSize.width / view.bounds.size.width;
|
@@ -603,6 +616,17 @@ - (FlutterPlatformViewController*)platformViewController {
|
603 | 616 |
|
604 | 617 | #pragma mark - Private methods
|
605 | 618 |
|
| 619 | +- (FlutterViewController*)viewControllerForId:(uint64_t)viewId { |
| 620 | + // TODO(dkwingsmt): The engine only supports single-view, therefore it |
| 621 | + // only processes the default ID. After the engine supports multiple views, |
| 622 | + // this method should be able to return the view for any IDs. |
| 623 | + NSAssert(viewId == kFlutterDefaultViewId, @"Unexpected view ID %llu", viewId); |
| 624 | + if (viewId == kFlutterDefaultViewId) { |
| 625 | + return _viewController; |
| 626 | + } |
| 627 | + return nil; |
| 628 | +} |
| 629 | + |
606 | 630 | - (void)sendUserLocales {
|
607 | 631 | if (!self.running) {
|
608 | 632 | return;
|
@@ -679,9 +703,7 @@ - (void)shutDownEngine {
|
679 | 703 | return;
|
680 | 704 | }
|
681 | 705 |
|
682 |
| - if (_viewController && _viewController.flutterView) { |
683 |
| - [_viewController.flutterView shutdown]; |
684 |
| - } |
| 706 | + [self.viewController.flutterView shutdown]; |
685 | 707 |
|
686 | 708 | FlutterEngineResult result = _embedderAPI.Deinitialize(_engine);
|
687 | 709 | if (result != kSuccess) {
|
|
0 commit comments