Modified: trunk/Source/WebKit2/ChangeLog (171200 => 171201)
--- trunk/Source/WebKit2/ChangeLog 2014-07-17 22:02:26 UTC (rev 171200)
+++ trunk/Source/WebKit2/ChangeLog 2014-07-17 22:08:41 UTC (rev 171201)
@@ -1,3 +1,56 @@
+2014-07-17 Benjamin Poulain <[email protected]>
+
+ [iOS][WK2] Add SPI to do a dynamic viewport update without showing any content
+ https://bugs.webkit.org/show_bug.cgi?id=135010
+
+ Reviewed by Darin Adler.
+
+ This patch add a new SPI, [WKWebView _resizeWhileHidingContentWithUpdates:] to perform all the work
+ of a dynamic viewport size update, but instead of animating the old content, it is hidden.
+
+ The patch is built on top of the animated resize mechanism. Instead of having an animation driving
+ the beginning and end, we let the content do that. The dynamic resize begins, it runs for as long as
+ the WebProcess needs, and it ends when first layer tree commit with the new content is processed.
+
+ The attribute "_isAnimatingResize" is generalized to support two modes of resizing: animated and
+ hiding content.
+
+ The attribute "_hasCommittedLoadForMainFrame" is rather silly. It is only needed because
+ [WKWebView _resizeWhileHidingContentWithUpdates:] is intended to be called a lot before the page
+ is initialized, and doing an animated resize would trash the WebProcess state.
+ I wish I had a better solution, this is not great.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _processDidExit]):
+ (-[WKWebView _didCommitLoadForMainFrame]):
+ (-[WKWebView _didCommitLayerTree:]):
+ This is the key to make this work properly. We want _resizeWhileHidingContentWithUpdates: to behave
+ exactly like an animated resize to avoid bugs. So we went to the whole update mechanism using
+ _resizeAnimationTransformAdjustments to accumulate the adjustments, now we need to restore a correct
+ view state.
+
+ Calling [WKWebView _endAnimatedResize] will do exactly that, but we need to make sure we do not hit
+ the synchronization path or we would be blocked there for a while, which is what we are trying to avoid.
+
+ After r171154, WebPageProxy keeps track of what stage of dynamic viewport update we are in. Since we are
+ executing the layer tree update stage, with the right transaction ID, WebPageProxy already knows we have
+ everything we need and does not use any synchronous messages.
+
+ (-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:nextValidLayerTreeTransactionID:]):
+ (-[WKWebView _restorePageStateToExposedRect:scale:]):
+ (-[WKWebView _restorePageStateToUnobscuredCenter:scale:]):
+ (-[WKWebView _scrollToContentOffset:]):
+ (-[WKWebView _frameOrBoundsChanged]):
+ (-[WKWebView _updateVisibleContentRects]):
+ (-[WKWebView _setMinimumLayoutSizeOverride:]):
+ (-[WKWebView _setMinimumLayoutSizeOverrideForMinimalUI:]):
+ (-[WKWebView _setInterfaceOrientationOverride:]):
+ (-[WKWebView _setMaximumUnobscuredSizeOverride:]):
+ (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+ (-[WKWebView _endAnimatedResize]):
+ (-[WKWebView _resizeWhileHidingContentWithUpdates:]):
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
2014-07-17 Brent Fulgham <[email protected]>
[Mac] Full screen video not always animating in the correct Space
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (171200 => 171201)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm 2014-07-17 22:02:26 UTC (rev 171200)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm 2014-07-17 22:08:41 UTC (rev 171201)
@@ -118,6 +118,13 @@
- (UIViewController *)_rootAncestorViewController;
- (UIViewController *)_viewControllerForSupportedInterfaceOrientations;
@end
+
+enum class DynamicViewportUpdateMode {
+ NotResizing,
+ ResizingWithAnimation,
+ ResizingWithDocumentHidden,
+};
+
#endif
#if PLATFORM(MAC)
@@ -166,9 +173,10 @@
UIInterfaceOrientation _interfaceOrientationOverride;
BOOL _overridesInterfaceOrientation;
+ BOOL _hasCommittedLoadForMainFrame;
BOOL _needsResetViewStateAfterCommitLoadForMainFrame;
uint64_t _firstPaintAfterCommitLoadTransactionID;
- BOOL _isAnimatingResize;
+ DynamicViewportUpdateMode _dynamicViewportUpdateMode;
CATransform3D _resizeAnimationTransformAdjustments;
uint64_t _resizeAnimationTransformTransactionID;
RetainPtr<UIView> _resizeAnimationView;
@@ -740,14 +748,13 @@
- (void)_processDidExit
{
- if (!_customContentView && _isAnimatingResize) {
+ if (!_customContentView && _dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
NSUInteger indexOfResizeAnimationView = [[_scrollView subviews] indexOfObject:_resizeAnimationView.get()];
[_scrollView insertSubview:_contentView.get() atIndex:indexOfResizeAnimationView];
[_scrollView insertSubview:[_contentView unscaledView] atIndex:indexOfResizeAnimationView + 1];
[_resizeAnimationView removeFromSuperview];
_resizeAnimationView = nil;
- _isAnimatingResize = NO;
_resizeAnimationTransformAdjustments = CATransform3DIdentity;
}
[_contentView setFrame:self.bounds];
@@ -756,7 +763,10 @@
[_scrollView setZoomScale:1];
_viewportMetaTagWidth = -1;
+ _hasCommittedLoadForMainFrame = NO;
_needsResetViewStateAfterCommitLoadForMainFrame = NO;
+ _dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
+ [_contentView setHidden:NO];
_needsToRestoreExposedRect = NO;
_needsToRestoreUnobscuredCenter = NO;
_scrollViewBackgroundColor = WebCore::Color();
@@ -768,6 +778,7 @@
{
_firstPaintAfterCommitLoadTransactionID = toRemoteLayerTreeDrawingAreaProxy(_page->drawingArea())->nextLayerTreeTransactionID();
+ _hasCommittedLoadForMainFrame = YES;
_needsResetViewStateAfterCommitLoadForMainFrame = YES;
_usesMinimalUI = NO;
}
@@ -804,9 +815,14 @@
if (_customContentView)
return;
- if (_isAnimatingResize) {
- if (layerTreeTransaction.transactionID() >= _resizeAnimationTransformTransactionID)
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
+ if (layerTreeTransaction.transactionID() >= _resizeAnimationTransformTransactionID) {
[_resizeAnimationView layer].sublayerTransform = _resizeAnimationTransformAdjustments;
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::ResizingWithDocumentHidden) {
+ [_contentView setHidden:NO];
+ [self _endAnimatedResize];
+ }
+ }
return;
}
@@ -869,7 +885,7 @@
- (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition nextValidLayerTreeTransactionID:(uint64_t)nextValidLayerTreeTransactionID
{
- if (_isAnimatingResize) {
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
CGFloat animatingScaleTarget = [[_resizeAnimationView layer] transform].m11;
double currentTargetScale = animatingScaleTarget * [[_contentView layer] transform].m11;
double scale = newScale / currentTargetScale;
@@ -886,7 +902,7 @@
- (void)_restorePageStateToExposedRect:(WebCore::FloatRect)exposedRect scale:(double)scale
{
- if (_isAnimatingResize)
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
return;
if (_customContentView)
@@ -901,7 +917,7 @@
- (void)_restorePageStateToUnobscuredCenter:(WebCore::FloatPoint)center scale:(double)scale
{
- if (_isAnimatingResize)
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
return;
if (_customContentView)
@@ -987,7 +1003,7 @@
- (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset
{
- if (_isAnimatingResize)
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
return;
WebCore::FloatPoint scaledOffset = contentOffset;
@@ -1332,7 +1348,7 @@
CGRect bounds = self.bounds;
[_scrollView setFrame:bounds];
- if (!_isAnimatingResize) {
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing) {
if (!_overridesMinimumLayoutSize)
_page->setViewportConfigurationMinimumLayoutSize(WebCore::FloatSize(bounds.size));
if (!_overridesMinimumLayoutSizeForMinimalUI)
@@ -1368,7 +1384,7 @@
return;
}
- if (_isAnimatingResize)
+ if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
return;
if (_needsResetViewStateAfterCommitLoadForMainFrame)
@@ -2027,7 +2043,7 @@
return;
_minimumLayoutSizeOverride = minimumLayoutSizeOverride;
- if (!_isAnimatingResize)
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
_page->setViewportConfigurationMinimumLayoutSize(WebCore::FloatSize(minimumLayoutSizeOverride));
}
@@ -2044,7 +2060,7 @@
return;
_minimumLayoutSizeOverrideForMinimalUI = size;
- if (!_isAnimatingResize)
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
_page->setViewportConfigurationMinimumLayoutSizeForMinimalUI(WebCore::FloatSize(size));
}
@@ -2080,7 +2096,7 @@
_interfaceOrientationOverride = interfaceOrientation;
- if (!_isAnimatingResize)
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
_page->setDeviceOrientation(deviceOrientationForUIInterfaceOrientation(_interfaceOrientationOverride));
}
@@ -2104,7 +2120,7 @@
return;
_maximumUnobscuredSizeOverride = size;
- if (!_isAnimatingResize)
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
_page->setMaximumUnobscuredSize(WebCore::FloatSize(size));
}
@@ -2133,12 +2149,12 @@
- (void)_beginAnimatedResizeWithUpdates:(void (^)(void))updateBlock
{
- if (_customContentView) {
+ if (_customContentView || !_hasCommittedLoadForMainFrame) {
updateBlock();
return;
}
- _isAnimatingResize = YES;
+ _dynamicViewportUpdateMode = DynamicViewportUpdateMode::ResizingWithAnimation;
CGRect oldBounds = self.bounds;
WebCore::FloatSize oldMinimumLayoutSize = activeMinimumLayoutSize(self, oldBounds);
@@ -2163,7 +2179,7 @@
&& oldMaximumUnobscuredSize == newMaximumUnobscuredSize
&& oldOrientation == newOrientation
&& UIEdgeInsetsEqualToEdgeInsets(oldObscuredInsets, newObscuredInsets)) {
- _isAnimatingResize = NO;
+ _dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
[self _updateVisibleContentRects];
return;
}
@@ -2227,7 +2243,7 @@
- (void)_endAnimatedResize
{
- if (!_isAnimatingResize)
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
return;
_page->synchronizeDynamicViewportUpdate();
@@ -2265,10 +2281,20 @@
_resizeAnimationView = nil;
_resizeAnimationTransformAdjustments = CATransform3DIdentity;
- _isAnimatingResize = NO;
+ _dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
+ [_contentView setHidden:NO];
[self _updateVisibleContentRects];
}
+- (void)_resizeWhileHidingContentWithUpdates:(void (^)(void))updateBlock
+{
+ [self _beginAnimatedResizeWithUpdates:updateBlock];
+ if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::ResizingWithAnimation) {
+ [_contentView setHidden:YES];
+ _dynamicViewportUpdateMode = DynamicViewportUpdateMode::ResizingWithDocumentHidden;
+ }
+}
+
- (void)_setOverlaidAccessoryViewsInset:(CGSize)inset
{
[_customContentView web_setOverlaidAccessoryViewsInset:inset];
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (171200 => 171201)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h 2014-07-17 22:02:26 UTC (rev 171200)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h 2014-07-17 22:08:41 UTC (rev 171201)
@@ -137,6 +137,7 @@
- (void)_beginAnimatedResizeWithUpdates:(void (^)(void))updateBlock;
- (void)_endAnimatedResize;
+- (void)_resizeWhileHidingContentWithUpdates:(void (^)(void))updateBlock;
- (void)_snapshotRect:(CGRect)rectInViewCoordinates intoImageOfWidth:(CGFloat)imageWidth completionHandler:(void(^)(CGImageRef))completionHandler;