From 831744b7e0456f0c5eaa5805a35b33aed072e395 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Thu, 13 Oct 2022 11:49:01 -0400 Subject: [PATCH 01/10] EXPERIMENT --- shell/platform/darwin/ios/framework/Source/FlutterView.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 7c188be87109d..06f02966895bb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -47,6 +47,7 @@ - (instancetype)initWithDelegate:(id)delegate opaque: if (self) { _delegate = delegate; self.layer.opaque = opaque; + self.layer.backgroundColor = NSColor.black; } return self; From 18f13a0de188ec095348e713c3eaf52b4cea4899 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Thu, 20 Oct 2022 11:56:47 -1000 Subject: [PATCH 02/10] Create failing unit test for black background on macos --- .../framework/Source/FlutterEngineTest.mm | 30 +++++++++++++++++++ .../Source/fixtures/flutter_desktop_test.dart | 6 ++++ 2 files changed, 36 insertions(+) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 439519575e578..606bea5663ccc 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -101,6 +101,36 @@ @interface FlutterEngine (Test) EXPECT_TRUE(logs.find("Hello logging") != std::string::npos); } +TEST_F(FlutterEngineTest, BackgroundIsBlack) { + // Launch the test entrypoint. + FlutterEngine* engine = GetFlutterEngine(); + EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]); + EXPECT_TRUE(engine.running); + + NSString* fixtures = @(flutter::testing::GetFixturesPath()); + FlutterDartProject* project = [[FlutterDartProject alloc] + initWithAssetsPath:fixtures + ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]]; + FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project]; + [viewController loadView]; + viewController.flutterView.frame = CGRectMake(0, 0, 800, 600); + [engine setViewController:viewController]; + + // Latch to ensure the entire layer tree has been generated and presented. + fml::AutoResetWaitableEvent latch; + AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { + CALayer* rootLayer = engine.viewController.flutterView.layer; + EXPECT_TRUE(rootLayer.backgroundColor != nil); + if (rootLayer.backgroundColor != nil) { + NSColor* actualBackgroundColor = + [NSColor colorWithCGColor:rootLayer.backgroundColor]; + EXPECT_EQ(actualBackgroundColor, [NSColor blackColor]); + } + latch.Signal(); + })); + latch.Wait(); +} + TEST_F(FlutterEngineTest, CanToggleAccessibility) { FlutterEngine* engine = GetFlutterEngine(); // Capture the update callbacks before the embedder API initializes. diff --git a/shell/platform/darwin/macos/framework/Source/fixtures/flutter_desktop_test.dart b/shell/platform/darwin/macos/framework/Source/fixtures/flutter_desktop_test.dart index 50c31f3adcee7..afdc3275e9618 100644 --- a/shell/platform/darwin/macos/framework/Source/fixtures/flutter_desktop_test.dart +++ b/shell/platform/darwin/macos/framework/Source/fixtures/flutter_desktop_test.dart @@ -57,3 +57,9 @@ Picture _createSimplePicture() { void nativeCallback() { signalNativeTest(); } + +@pragma('vm:entry-point') +void backgroundTest() { + PlatformDispatcher.instance.views.first.render(SceneBuilder().build()); + signalNativeTest(); // should look black +} From d8f3f65730c3c52a9a897da63d2381bb316c388d Mon Sep 17 00:00:00 2001 From: a-wallen Date: Thu, 20 Oct 2022 12:00:20 -1000 Subject: [PATCH 03/10] Add black background default to FlutterView root layer --- .../platform/darwin/macos/framework/Source/FlutterView.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index 30c0a4495ac1a..2d9eb221a1b68 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -28,6 +28,7 @@ - (instancetype)initWithMTLDevice:(id)device self = [super initWithFrame:NSZeroRect]; if (self) { [self setWantsLayer:YES]; + [self setBackgroundColor:[NSColor blackColor]]; [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; _reshapeListener = reshapeListener; _resizableBackingStoreProvider = @@ -51,6 +52,7 @@ - (instancetype)initWithFrame:(NSRect)frame self = [super initWithFrame:frame]; if (self) { [self setWantsLayer:YES]; + [self setBackgroundColor:[NSColor blackColor]]; _reshapeListener = reshapeListener; _resizableBackingStoreProvider = [[FlutterOpenGLResizableBackingStoreProvider alloc] initWithMainContext:mainContext @@ -84,6 +86,11 @@ - (void)reshaped { }]; } +- (void)setBackgroundColor:(NSColor*)color { + [self setWantsLayer:YES]; + self.layer.backgroundColor = color.CGColor; +} + #pragma mark - NSView overrides - (void)setFrameSize:(NSSize)newSize { From 4aaad356a9fca7595526ac3dea45e8ad40195814 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Wed, 26 Oct 2022 12:33:24 -1000 Subject: [PATCH 04/10] Expose in FlutterView --- .../platform/darwin/macos/framework/Source/FlutterView.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index 8aed110e70adb..6dd21830b2c8d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -68,4 +68,13 @@ */ - (void)shutdown; +/** + * By default, the `FlutterSurfaceManager` creates two layers to manage Flutter + * content, the content layer and containing layer. To set the native background + * color, onto which the Flutter content is drawn, call this method with the + * NSColor which you would like to override the default, black background color + * with. + */ +- (void)setBackgroundColor:(nonnull NSColor*)color; + @end From 0e94bfe8837d3fbce10734e1fcc91592ee6cfad4 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Wed, 26 Oct 2022 12:34:04 -1000 Subject: [PATCH 05/10] Route setting background of FlutterView through FlutterViewController --- .../framework/Headers/FlutterViewController.h | 44 +++++++++++++++++++ .../framework/Source/FlutterViewController.mm | 10 +++++ 2 files changed, 54 insertions(+) diff --git a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h index 038db1f322eed..04d7214141a87 100644 --- a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h @@ -73,4 +73,48 @@ FLUTTER_DARWIN_EXPORT */ - (void)onPreEngineRestart; +/** + * The contentView (FlutterView)'s background color is set to black during + * its instantiation. + * + * The containing layer's color can be set to the NSColor provided to this method. + * + * For example, the background may be set after the FlutterViewController + * is instantiated in MainFlutterWindow.swift in the Flutter project. + * ```swift + * import Cocoa + * import FlutterMacOS + * + * class MainFlutterWindow: NSWindow { + * override func awakeFromNib() { + * let flutterViewController = FlutterViewController.init() + * + * // The background color of the window and `FlutterViewController` + * // are retained separately. + * // + * // In this example, both the MainFlutterWindow and FlutterViewController's + * // FlutterView's backgroundColor are set to clear to achieve a fully + * // transparent effect. + * // + * // If the window's background color is not set, it will use the system + * // default. + * // + * // If the `FlutterView`'s color is not set via `FlutterViewController.setBackgroundColor` + * // it's default will be black. + * self.backgroundColor = NSColor.clear + * flutterViewController.setBackgroundColor(NSColor.white) + * + * let windowFrame = self.frame + * self.contentViewController = flutterViewController + * self.setFrame(windowFrame, display: true) + * + * RegisterGeneratedPlugins(registry: flutterViewController) + * + * super.awakeFromNib() + * } + * } + * ``` + */ +- (void)setBackgroundColor:(nonnull NSColor*)color; + @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index cb472018404c7..037cb416da0a2 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -159,6 +159,8 @@ void Reset() { */ @interface FlutterViewWrapper : NSView +- (void)setBackgroundColor:(NSColor*)color; + @end /** @@ -266,6 +268,10 @@ - (instancetype)initWithFlutterView:(FlutterView*)view { return self; } +- (void)setBackgroundColor:(NSColor*)color { + [_flutterView setBackgroundColor:color]; +} + - (NSArray*)accessibilityChildren { return @[ _flutterView ]; } @@ -418,6 +424,10 @@ - (void)setMouseTrackingMode:(FlutterMouseTrackingMode)mode { [self configureTrackingArea]; } +- (void)setBackgroundColor:(NSColor*)color { + [(FlutterViewWrapper*)[self view] setBackgroundColor:color]; +} + - (void)onPreEngineRestart { [self initializeKeyboard]; } From 25ddb128dca6b5092718557d83559d5df954311c Mon Sep 17 00:00:00 2001 From: a-wallen Date: Wed, 26 Oct 2022 13:15:30 -1000 Subject: [PATCH 06/10] Add test to ensure background is overridable --- .../framework/Source/FlutterEngineTest.mm | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 606bea5663ccc..d783683b99f41 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -131,6 +131,37 @@ @interface FlutterEngine (Test) latch.Wait(); } +TEST_F(FlutterEngineTest, CanOverrideBackgroundColor) { + // Launch the test entrypoint. + FlutterEngine* engine = GetFlutterEngine(); + EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]); + EXPECT_TRUE(engine.running); + + NSString* fixtures = @(flutter::testing::GetFixturesPath()); + FlutterDartProject* project = [[FlutterDartProject alloc] + initWithAssetsPath:fixtures + ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]]; + FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project]; + [viewController loadView]; + viewController.flutterView.frame = CGRectMake(0, 0, 800, 600); + [engine setViewController:viewController]; + [viewController setBackgroundColor:[NSColor whiteColor]]; + + // Latch to ensure the entire layer tree has been generated and presented. + fml::AutoResetWaitableEvent latch; + AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { + CALayer* rootLayer = engine.viewController.flutterView.layer; + EXPECT_TRUE(rootLayer.backgroundColor != nil); + if (rootLayer.backgroundColor != nil) { + NSColor* actualBackgroundColor = + [NSColor colorWithCGColor:rootLayer.backgroundColor]; + EXPECT_EQ(actualBackgroundColor, [NSColor whiteColor]); + } + latch.Signal(); + })); + latch.Wait(); +} + TEST_F(FlutterEngineTest, CanToggleAccessibility) { FlutterEngine* engine = GetFlutterEngine(); // Capture the update callbacks before the embedder API initializes. From c2f7828ec2ec1359a035dfdb85dc651772b82d89 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Thu, 27 Oct 2022 10:45:20 -1000 Subject: [PATCH 07/10] Remove SetWantsLayer from setBackgroundColor --- shell/platform/darwin/macos/framework/Source/FlutterView.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index 2d9eb221a1b68..b2c85efba3cd4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -87,7 +87,6 @@ - (void)reshaped { } - (void)setBackgroundColor:(NSColor*)color { - [self setWantsLayer:YES]; self.layer.backgroundColor = color.CGColor; } From 4b143f2241e166043c3df98f6ed70d679f9d1fb3 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Thu, 27 Oct 2022 11:05:56 -1000 Subject: [PATCH 08/10] Make backgroundColor a property on FVC --- .../darwin/macos/framework/Headers/FlutterViewController.h | 4 ++-- .../darwin/macos/framework/Source/FlutterEngineTest.mm | 2 +- .../darwin/macos/framework/Source/FlutterViewController.mm | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h index 04d7214141a87..53e26fbad4da6 100644 --- a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h @@ -102,7 +102,7 @@ FLUTTER_DARWIN_EXPORT * // If the `FlutterView`'s color is not set via `FlutterViewController.setBackgroundColor` * // it's default will be black. * self.backgroundColor = NSColor.clear - * flutterViewController.setBackgroundColor(NSColor.white) + * flutterViewController.backgroundColor = NSColor.clear * * let windowFrame = self.frame * self.contentViewController = flutterViewController @@ -115,6 +115,6 @@ FLUTTER_DARWIN_EXPORT * } * ``` */ -- (void)setBackgroundColor:(nonnull NSColor*)color; +@property(readwrite, nonatomic, nullable) NSColor* backgroundColor; @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index d783683b99f41..f6ac4a37a181a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -145,7 +145,7 @@ @interface FlutterEngine (Test) [viewController loadView]; viewController.flutterView.frame = CGRectMake(0, 0, 800, 600); [engine setViewController:viewController]; - [viewController setBackgroundColor:[NSColor whiteColor]]; + viewController.flutterView.backgroundColor = [NSColor whiteColor]; // Latch to ensure the entire layer tree has been generated and presented. fml::AutoResetWaitableEvent latch; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 037cb416da0a2..33bb05407edda 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -425,7 +425,8 @@ - (void)setMouseTrackingMode:(FlutterMouseTrackingMode)mode { } - (void)setBackgroundColor:(NSColor*)color { - [(FlutterViewWrapper*)[self view] setBackgroundColor:color]; + _backgroundColor = color; + [(FlutterViewWrapper*)[self view] setBackgroundColor:_backgroundColor]; } - (void)onPreEngineRestart { From 18ecb7fc4bbb9f830b56e297bdab2b0fcc62e318 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Fri, 28 Oct 2022 05:47:48 -1000 Subject: [PATCH 09/10] Set background when viewDidLoad --- .../darwin/macos/framework/Source/FlutterViewController.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 33bb05407edda..d78c3941aa275 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -382,6 +382,9 @@ - (void)loadView { } flutterView = [[FlutterView alloc] initWithMainContext:mainContext reshapeListener:self]; } + if (_backgroundColor != nil) { + [flutterView setBackgroundColor:_backgroundColor]; + } FlutterViewWrapper* wrapperView = [[FlutterViewWrapper alloc] initWithFlutterView:flutterView]; self.view = wrapperView; _flutterView = flutterView; @@ -426,7 +429,7 @@ - (void)setMouseTrackingMode:(FlutterMouseTrackingMode)mode { - (void)setBackgroundColor:(NSColor*)color { _backgroundColor = color; - [(FlutterViewWrapper*)[self view] setBackgroundColor:_backgroundColor]; + [_flutterView setBackgroundColor:_backgroundColor]; } - (void)onPreEngineRestart { From 4b459f6c947abc6ff8851c14a7692a9b6869a916 Mon Sep 17 00:00:00 2001 From: a-wallen Date: Fri, 28 Oct 2022 06:43:04 -1000 Subject: [PATCH 10/10] Fix ios accident --- shell/platform/darwin/ios/framework/Source/FlutterView.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 06f02966895bb..7c188be87109d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -47,7 +47,6 @@ - (instancetype)initWithDelegate:(id)delegate opaque: if (self) { _delegate = delegate; self.layer.opaque = opaque; - self.layer.backgroundColor = NSColor.black; } return self;