[Mac] Requesting PiP from two different WebViews gets PiP window "stuck"
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 22:28:19 +0000 (22:28 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 22:28:19 +0000 (22:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194099
<rdar://problem/47271323>

Reviewed by Eric Carlson.

When a different client requests the PiP window, the PiP framework will call -pipDidClose: without
first calling -pipActionStop:. This leaves the internal fullscreen state in a confused state where
the WebView will attempt to re-enter PiP once it gets focus, and can lead to a state where the two
WebViews will constantly try to steal PiP from one another, ad infinitum.

When receiving a notification that the PiP window closed when our internal state tells us that the
close was not requested, notify the client that PiP mode was exited, allowing them to set their
expected state to a correct and sane value.

* platform/mac/VideoFullscreenInterfaceMac.mm:
(-[WebVideoFullscreenInterfaceMacObjC pipDidClose:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240822 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm

index 3849c99..fa1ebfb 100644 (file)
@@ -1,3 +1,23 @@
+2019-01-31  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Requesting PiP from two different WebViews gets PiP window "stuck"
+        https://bugs.webkit.org/show_bug.cgi?id=194099
+        <rdar://problem/47271323>
+
+        Reviewed by Eric Carlson.
+
+        When a different client requests the PiP window, the PiP framework will call -pipDidClose: without
+        first calling -pipActionStop:. This leaves the internal fullscreen state in a confused state where
+        the WebView will attempt to re-enter PiP once it gets focus, and can lead to a state where the two
+        WebViews will constantly try to steal PiP from one another, ad infinitum.
+
+        When receiving a notification that the PiP window closed when our internal state tells us that the
+        close was not requested, notify the client that PiP mode was exited, allowing them to set their
+        expected state to a correct and sane value.
+
+        * platform/mac/VideoFullscreenInterfaceMac.mm:
+        (-[WebVideoFullscreenInterfaceMacObjC pipDidClose:]):
+
 2019-01-31  Keith Rollin  <krollin@apple.com>
 
         WebCore::WHLSL::AST::Expression copy constructor needs to be be default, not delete
index 1aa127e..6e981d2 100644 (file)
@@ -287,7 +287,16 @@ enum class PIPState {
 {
     ASSERT_UNUSED(pip, pip == _pipViewController);
 
-    if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->videoFullscreenModel() && _videoViewContainer && _returningWindow && !NSEqualRects(_returningRect, NSZeroRect)) {
+    if (!_videoFullscreenInterfaceMac)
+        return;
+
+    if (_pipState != PIPState::ExitingPIP) {
+        // We got told to close without going through -pipActionStop, nor by exlicitly being asked to in -exitPiP:.
+        // Call -pipActionStop: here in order to set the fullscreen state to an expected value.
+        [self pipActionStop:pip];
+    }
+
+    if (_videoFullscreenInterfaceMac->videoFullscreenModel() && _videoViewContainer && _returningWindow && !NSEqualRects(_returningRect, NSZeroRect)) {
         [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
             context.allowsImplicitAnimation = NO;
             [_videoViewContainer setFrame:_returningRect];
@@ -298,19 +307,17 @@ enum class PIPState {
         } completionHandler:nil];
     }
 
-    if (_videoFullscreenInterfaceMac) {
-        if (!self.isExitingToStandardFullscreen) {
-            if (VideoFullscreenModel* videoFullscreenModel = _videoFullscreenInterfaceMac->videoFullscreenModel()) {
-                videoFullscreenModel->didExitPictureInPicture();
-                videoFullscreenModel->setVideoLayerGravity(MediaPlayerEnums::VideoGravityResizeAspect);
-            }
+    if (!self.isExitingToStandardFullscreen) {
+        if (VideoFullscreenModel* videoFullscreenModel = _videoFullscreenInterfaceMac->videoFullscreenModel()) {
+            videoFullscreenModel->didExitPictureInPicture();
+            videoFullscreenModel->setVideoLayerGravity(MediaPlayerEnums::VideoGravityResizeAspect);
         }
+    }
 
-        _videoFullscreenInterfaceMac->clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
+    if (VideoFullscreenChangeObserver* fullscreenChangeObserver = _videoFullscreenInterfaceMac->videoFullscreenChangeObserver())
+        fullscreenChangeObserver->didExitFullscreen();
 
-        if (VideoFullscreenChangeObserver* fullscreenChangeObserver = _videoFullscreenInterfaceMac->videoFullscreenChangeObserver())
-            fullscreenChangeObserver->didExitFullscreen();
-    }
+    _videoFullscreenInterfaceMac->clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
 }
 
 - (void)pipActionPlay:(PIPViewController *)pip