Title: [239475] trunk/Source/WebKit
Revision
239475
Author
[email protected]
Date
2018-12-20 16:27:50 -0800 (Thu, 20 Dec 2018)

Log Message

Flicker when exiting element fullscreen.
https://bugs.webkit.org/show_bug.cgi?id=192774
rdar://problem/33088878

Patch by Jeremy Jones <[email protected]> on 2018-12-20
Reviewed by Jer Noble.

Fixes an issue where the web page would flicker upon exiting element fullscreen.

Replace WebView with a snapshot while the WebView is restyled and resized for inline.

* UIProcess/mac/WKFullScreenWindowController.h:
* UIProcess/mac/WKFullScreenWindowController.mm:
(-[WKFullScreenWindowController initWithWindow:webView:page:]):
(-[WKFullScreenWindowController finishedExitFullScreenAnimation:]):
(-[WKFullScreenWindowController completeFinishExitFullScreenAnimationAfterRepaint]):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (239474 => 239475)


--- trunk/Source/WebKit/ChangeLog	2018-12-21 00:20:21 UTC (rev 239474)
+++ trunk/Source/WebKit/ChangeLog	2018-12-21 00:27:50 UTC (rev 239475)
@@ -1,3 +1,21 @@
+2018-12-20  Jeremy Jones  <[email protected]>
+
+        Flicker when exiting element fullscreen.
+        https://bugs.webkit.org/show_bug.cgi?id=192774
+        rdar://problem/33088878
+
+        Reviewed by Jer Noble.
+
+        Fixes an issue where the web page would flicker upon exiting element fullscreen.
+
+        Replace WebView with a snapshot while the WebView is restyled and resized for inline.
+
+        * UIProcess/mac/WKFullScreenWindowController.h:
+        * UIProcess/mac/WKFullScreenWindowController.mm:
+        (-[WKFullScreenWindowController initWithWindow:webView:page:]):
+        (-[WKFullScreenWindowController finishedExitFullScreenAnimation:]):
+        (-[WKFullScreenWindowController completeFinishExitFullScreenAnimationAfterRepaint]):
+
 2018-12-20  Chris Dumez  <[email protected]>
 
         Move HTTPS_UPGRADE code behind a runtime flag, off by default

Modified: trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h (239474 => 239475)


--- trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h	2018-12-21 00:20:21 UTC (rev 239474)
+++ trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h	2018-12-21 00:27:50 UTC (rev 239475)
@@ -48,6 +48,7 @@
     NSView *_webView; // Cannot be retained, see <rdar://problem/14884666>.
     WebKit::WebPageProxy* _page;
     RetainPtr<WebCoreFullScreenPlaceholderView> _webViewPlaceholder;
+    RetainPtr<NSView> _exitPlaceholder;
     RetainPtr<NSView> _clipView;
     RetainPtr<NSView> _backgroundView;
     NSRect _initialFrame;

Modified: trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm (239474 => 239475)


--- trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm	2018-12-21 00:20:21 UTC (rev 239474)
+++ trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm	2018-12-21 00:27:50 UTC (rev 239475)
@@ -440,6 +440,26 @@
     [[self window] exitFullScreenMode:self];
 }
 
+WTF_DECLARE_CF_TYPE_TRAIT(CGImage);
+
+static RetainPtr<CGImageRef> takeWindowSnapshot(CGSWindowID windowID, bool captureAtNominalResolution)
+{
+    CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
+    if (captureAtNominalResolution)
+        options |= kCGSWindowCaptureNominalResolution;
+    RetainPtr<CFArrayRef> windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
+
+    if (windowSnapshotImages && CFArrayGetCount(windowSnapshotImages.get()))
+        return checked_cf_cast<CGImageRef>(CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0));
+
+    // Fall back to the non-hardware capture path if we didn't get a snapshot
+    // (which usually happens if the window is fully off-screen).
+    CGWindowImageOption imageOptions = kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque;
+    if (captureAtNominalResolution)
+        imageOptions |= kCGWindowImageNominalResolution;
+    return adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, imageOptions));
+}
+
 - (void)finishedExitFullScreenAnimation:(bool)completed
 {
     if (_fullScreenState == InFullScreen) {
@@ -457,20 +477,36 @@
 
     NSResponder *firstResponder = [[self window] firstResponder];
 
-    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    // Screen updates to be re-enabled in completeFinishExitFullScreenAnimationAfterRepaint.
-    NSDisableScreenUpdates();
-    ALLOW_DEPRECATED_DECLARATIONS_END
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    NSRect exitPlaceholderScreenRect = _initialFrame;
+    exitPlaceholderScreenRect.origin.y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - NSMaxY(exitPlaceholderScreenRect);
+
+    RetainPtr<CGImageRef> webViewContents = takeWindowSnapshot([[_webView window] windowNumber], true);
+    webViewContents = adoptCF(CGImageCreateWithImageInRect(webViewContents.get(), NSRectToCGRect(exitPlaceholderScreenRect)));
+    
+    _exitPlaceholder = adoptNS([[NSView alloc] initWithFrame:[_webView frame]]);
+    [_exitPlaceholder setWantsLayer: YES];
+    [_exitPlaceholder setAutoresizesSubviews: YES];
+    [_exitPlaceholder setLayerContentsPlacement: NSViewLayerContentsPlacementScaleProportionallyToFit];
+    [_exitPlaceholder setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawNever];
+    [_exitPlaceholder setFrame:[_webView frame]];
+    [[_exitPlaceholder layer] setContents:(__bridge id)webViewContents.get()];
+    [[_webView superview] addSubview:_exitPlaceholder.get() positioned:NSWindowAbove relativeTo:_webView];
+
+    [CATransaction commit];
+    [CATransaction flush];
+
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    
+    [_backgroundView.get().layer removeAllAnimations];
     _page->setSuppressVisibilityUpdates(true);
-    [[self window] orderOut:self];
-    NSView *contentView = [[self window] contentView];
-    contentView.hidden = YES;
-    [_backgroundView.get().layer removeAllAnimations];
-    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    [[_webViewPlaceholder window] setAutodisplay:NO];
-    ALLOW_DEPRECATED_DECLARATIONS_END
+    [_webView removeFromSuperview];
+    [_webView setFrame:[_webViewPlaceholder frame]];
+    [_webView setAutoresizingMask:[_webViewPlaceholder autoresizingMask]];
+    [[_webViewPlaceholder superview] addSubview:_webView positioned:NSWindowBelow relativeTo:_webViewPlaceholder.get()];
 
-    [self _replaceView:_webViewPlaceholder.get() with:_webView];
     BEGIN_BLOCK_OBJC_EXCEPTIONS
     [NSLayoutConstraint activateConstraints:self.savedConstraints];
     END_BLOCK_OBJC_EXCEPTIONS
@@ -477,8 +513,6 @@
     self.savedConstraints = nil;
     makeResponderFirstResponderIfDescendantOfView(_webView.window, firstResponder, _webView);
 
-    [[_webView window] makeKeyAndOrderFront:self];
-
     // These messages must be sent after the swap or flashing will occur during forceRepaint:
     [self _manager]->didExitFullScreen();
     [self _manager]->setAnimatingFullScreen(false);
@@ -496,19 +530,32 @@
         [self completeFinishExitFullScreenAnimationAfterRepaint];
     });
     _page->forceRepaint(_repaintCallback.copyRef());
+
+    [CATransaction commit];
+    [CATransaction flush];
 }
 
 - (void)completeFinishExitFullScreenAnimationAfterRepaint
 {
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+
+    [_webViewPlaceholder removeFromSuperview];
+    [[self window] orderOut:self];
+    NSView *contentView = [[self window] contentView];
+    contentView.hidden = YES;
+    [_exitPlaceholder removeFromSuperview];
+    [[_exitPlaceholder layer] setContents:nil];
+    _exitPlaceholder = nil;
+    
+    [[_webView window] makeKeyAndOrderFront:self];
+    _webViewPlaceholder = nil;
+    
     _repaintCallback = nullptr;
-    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    [[_webView window] setAutodisplay:YES];
-    ALLOW_DEPRECATED_DECLARATIONS_END
-    [[_webView window] displayIfNeeded];
     _page->setSuppressVisibilityUpdates(false);
-    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    NSEnableScreenUpdates();
-    ALLOW_DEPRECATED_DECLARATIONS_END
+
+    [CATransaction commit];
+    [CATransaction flush];
 }
 
 - (void)performClose:(id)sender
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to