diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorView.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorView.mm index e5bfd3ad707..c9036ecb8ff 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorView.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorView.mm @@ -602,9 +602,18 @@ NSMutableArray* ClipPathFromMutations(CGRect master_clip, const MutationVector& [containerSuperview addSubview:_platformViewContainer]; _platformViewContainer.frame = self.bounds; - // Nest the platform view in the PlatformViewContainer. - [_platformViewContainer addSubview:_platformView]; - _platformView.frame = untransformedBounds; + // Nest the platform view in the PlatformViewContainer, but only if the view doesn't have a + // superview yet. Sometimes the platform view reparents itself (WKWebView entering FullScreen) + // in which case do not forcefully move it back. + if (_platformView.superview == nil) { + [_platformViewContainer addSubview:_platformView]; + } + + // Originally first subview would be the _platformView. However during WKWebView full screen + // the platform view gets replaced with a placeholder. Given that _platformViewContainer does + // not contain any other views it is safe to assume that any subview found can be treated + // as the platform view. + _platformViewContainer.subviews.firstObject.frame = untransformedBounds; // Transform for the platform view is finalTransform adjusted for bounding rect origin. CATransform3D translation = diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorViewTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorViewTest.mm index 576ab9b3d4d..d352eefe3ba 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorViewTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorViewTest.mm @@ -562,6 +562,28 @@ TEST(FlutterMutatorViewTest, HitTestIgnoreRegion) { EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 50)], platformView); } +TEST(FlutterMutatorViewTest, ReparentingPlatformView) { + NSView* platformView = [[NSView alloc] init]; + FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView]; + ApplyFlutterLayer(mutatorView, FlutterSize{100, 100}, {}); + EXPECT_TRUE(platformView.superview == mutatorView.platformViewContainer); + EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 100, 100))); + + // Reparent platform view and replace it with placeholder (mimicking WKWebKit going full screen) + NSView* newParent = [[NSView alloc] init]; + [newParent addSubview:platformView]; + platformView.frame = CGRectMake(10, 10, 200, 200); + + NSView* placeholderView = [[NSView alloc] init]; + [mutatorView.platformViewContainer addSubview:placeholderView]; + ApplyFlutterLayer(mutatorView, FlutterSize{100, 100}, {}); + + // Platform view should not be touched but the replacement view should be properly positioned. + EXPECT_TRUE(platformView.superview == newParent); + EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(10, 10, 200, 200))); + EXPECT_TRUE(CGRectEqualToRect(placeholderView.frame, CGRectMake(0, 0, 100, 100))); +} + @interface FlutterCursorCoordinatorTest : NSObject @end