Title: [274692] trunk/Source/WebKit
- Revision
- 274692
- Author
- [email protected]
- Date
- 2021-03-18 17:25:16 -0700 (Thu, 18 Mar 2021)
Log Message
Handle empty bound size during animated resizing
https://bugs.webkit.org/show_bug.cgi?id=223446
Patch by Sihui Liu <[email protected]> on 2021-03-18
Reviewed by Tim Horton.
We don't allow empty bounds in animated resizing: when that happens, we would cancel it. However, a set of
updates involving empty bounds can be merged to a valid update. For example, two changes of frame size
[1] (0, 0, 100, 100) => (0, 0, 0, 50) [2] (0, 0, 0, 50) => (0, 0, 50, 50) can be viewed as single change
(0, 0, 100, 100) => (0, 0, 50, 50), which is valid. We used to ask SPI clients to ensure each update is valid,
but sometimes the frame change is not under client's control. For example when client uses auto layout, empty
frame seems to be a valid mid product.
To handle this case, we can store the old bounds, and actually perform animated resizing on when new valid
bounds show up. For the example above, we would store (0, 0, 100, 100) on [1] and use it to resize from
(0, 0, 100, 100) to (0, 0, 50, 50) on [2].
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _processWillSwapOrDidExit]):
(-[WKWebView _updateVisibleContentRects]): If we still have stored old bounds in _updateVisibleContentRects, it
means they are not consumed in this cycle. In this case let's just cancel animated resizing and send out updates.
(-[WKWebView _cancelAnimatedResize]):
(-[WKWebView _didCompleteAnimatedResize]):
(-[WKWebView _beginAnimatedResizeWithUpdates:]):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (274691 => 274692)
--- trunk/Source/WebKit/ChangeLog 2021-03-19 00:08:54 UTC (rev 274691)
+++ trunk/Source/WebKit/ChangeLog 2021-03-19 00:25:16 UTC (rev 274692)
@@ -1,3 +1,30 @@
+2021-03-18 Sihui Liu <[email protected]>
+
+ Handle empty bound size during animated resizing
+ https://bugs.webkit.org/show_bug.cgi?id=223446
+
+ Reviewed by Tim Horton.
+
+ We don't allow empty bounds in animated resizing: when that happens, we would cancel it. However, a set of
+ updates involving empty bounds can be merged to a valid update. For example, two changes of frame size
+ [1] (0, 0, 100, 100) => (0, 0, 0, 50) [2] (0, 0, 0, 50) => (0, 0, 50, 50) can be viewed as single change
+ (0, 0, 100, 100) => (0, 0, 50, 50), which is valid. We used to ask SPI clients to ensure each update is valid,
+ but sometimes the frame change is not under client's control. For example when client uses auto layout, empty
+ frame seems to be a valid mid product.
+
+ To handle this case, we can store the old bounds, and actually perform animated resizing on when new valid
+ bounds show up. For the example above, we would store (0, 0, 100, 100) on [1] and use it to resize from
+ (0, 0, 100, 100) to (0, 0, 50, 50) on [2].
+
+ * UIProcess/API/Cocoa/WKWebViewInternal.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _processWillSwapOrDidExit]):
+ (-[WKWebView _updateVisibleContentRects]): If we still have stored old bounds in _updateVisibleContentRects, it
+ means they are not consumed in this cycle. In this case let's just cancel animated resizing and send out updates.
+ (-[WKWebView _cancelAnimatedResize]):
+ (-[WKWebView _didCompleteAnimatedResize]):
+ (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+
2021-03-18 Jiewen Tan <[email protected]>
Update Keychain queries according to internal needs
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (274691 => 274692)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2021-03-19 00:08:54 UTC (rev 274691)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2021-03-19 00:25:16 UTC (rev 274692)
@@ -190,6 +190,10 @@
WebKit::DynamicViewportSizeUpdateID _currentDynamicViewportSizeUpdateID;
CATransform3D _resizeAnimationTransformAdjustments;
CGFloat _animatedResizeOriginalContentWidth;
+ CGRect _animatedResizeOldBounds;
+ CGFloat _animatedResizeOldMinimumEffectiveDeviceWidth;
+ int32_t _animatedResizeOldOrientation;
+ UIEdgeInsets _animatedResizeOldObscuredInsets;
RetainPtr<UIView> _resizeAnimationView;
CGFloat _lastAdjustmentForScroller;
Optional<CGRect> _frozenVisibleContentRect;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (274691 => 274692)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-03-19 00:08:54 UTC (rev 274691)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-03-19 00:25:16 UTC (rev 274692)
@@ -655,6 +655,7 @@
_waitingForEndAnimatedResize = NO;
_waitingForCommitAfterAnimatedResize = NO;
_animatedResizeOriginalContentWidth = 0;
+ _animatedResizeOldBounds = { };
[_contentView setHidden:NO];
_scrollOffsetToRestore = WTF::nullopt;
_unobscuredCenterToRestore = WTF::nullopt;
@@ -2092,6 +2093,9 @@
return;
}
+ if (!CGRectIsEmpty(_animatedResizeOldBounds))
+ [self _cancelAnimatedResize];
+
if (_dynamicViewportUpdateMode != WebKit::DynamicViewportUpdateMode::NotResizing
|| (_needsResetViewStateAfterCommitLoadForMainFrame && ![_contentView sizeChangedSinceLastVisibleContentRectUpdate])
|| [_scrollView isZoomBouncing]
@@ -2203,6 +2207,7 @@
}
_dynamicViewportUpdateMode = WebKit::DynamicViewportUpdateMode::NotResizing;
+ _animatedResizeOldBounds = { };
[self _scheduleVisibleContentRectUpdate];
}
@@ -2255,6 +2260,7 @@
_resizeAnimationTransformAdjustments = CATransform3DIdentity;
_dynamicViewportUpdateMode = WebKit::DynamicViewportUpdateMode::NotResizing;
+ _animatedResizeOldBounds = { };
[self _scheduleVisibleContentRectUpdate];
CGRect newBounds = self.bounds;
@@ -2878,7 +2884,8 @@
CGRect oldBounds = self.bounds;
WebCore::FloatRect oldUnobscuredContentRect = _page->unobscuredContentRect();
- if (![self usesStandardContentView] || !_hasCommittedLoadForMainFrame || CGRectIsEmpty(oldBounds) || oldUnobscuredContentRect.isEmpty()) {
+ auto isOldBoundsValid = !CGRectIsEmpty(oldBounds) || !CGRectIsEmpty(_animatedResizeOldBounds);
+ if (![self usesStandardContentView] || !_hasCommittedLoadForMainFrame || !isOldBoundsValid || oldUnobscuredContentRect.isEmpty()) {
if ([_customContentView respondsToSelector:@selector(web_beginAnimatedResizeWithUpdates:)])
[_customContentView web_beginAnimatedResizeWithUpdates:updateBlock];
else
@@ -2890,11 +2897,22 @@
_dynamicViewportUpdateMode = WebKit::DynamicViewportUpdateMode::ResizingWithAnimation;
- auto oldMinimumEffectiveDeviceWidth = [self _minimumEffectiveDeviceWidth];
- auto oldViewLayoutSize = [self activeViewLayoutSize:self.bounds];
+ CGFloat oldMinimumEffectiveDeviceWidth;
+ int32_t oldOrientation;
+ UIEdgeInsets oldObscuredInsets;
+ if (!CGRectIsEmpty(_animatedResizeOldBounds)) {
+ oldBounds = _animatedResizeOldBounds;
+ oldMinimumEffectiveDeviceWidth = _animatedResizeOldMinimumEffectiveDeviceWidth;
+ oldOrientation = _animatedResizeOldOrientation;
+ oldObscuredInsets = _animatedResizeOldObscuredInsets;
+ _animatedResizeOldBounds = { };
+ } else {
+ oldMinimumEffectiveDeviceWidth = [self _minimumEffectiveDeviceWidth];
+ oldOrientation = activeOrientation(self);
+ oldObscuredInsets = _obscuredInsets;
+ }
+ auto oldViewLayoutSize = [self activeViewLayoutSize:oldBounds];
auto oldMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, oldBounds);
- int32_t oldOrientation = activeOrientation(self);
- UIEdgeInsets oldObscuredInsets = _obscuredInsets;
updateBlock();
@@ -2907,9 +2925,18 @@
CGRect futureUnobscuredRectInSelfCoordinates = UIEdgeInsetsInsetRect(newBounds, _obscuredInsets);
CGRect contentViewBounds = [_contentView bounds];
- ASSERT_WITH_MESSAGE(!(_viewLayoutSizeOverride && newViewLayoutSize.isEmpty()), "Clients controlling the layout size should maintain a valid layout size to minimize layouts.");
if (CGRectIsEmpty(newBounds) || newViewLayoutSize.isEmpty() || CGRectIsEmpty(futureUnobscuredRectInSelfCoordinates) || CGRectIsEmpty(contentViewBounds)) {
- [self _cancelAnimatedResize];
+ if (!CGRectIsEmpty(newBounds))
+ [self _cancelAnimatedResize];
+ else {
+ _animatedResizeOldBounds = oldBounds;
+ _animatedResizeOldMinimumEffectiveDeviceWidth = oldMinimumEffectiveDeviceWidth;
+ _animatedResizeOldOrientation = oldOrientation;
+ _animatedResizeOldObscuredInsets = oldObscuredInsets;
+ _waitingForCommitAfterAnimatedResize = YES;
+ _waitingForEndAnimatedResize = YES;
+ }
+
[self _frameOrBoundsChanged];
if (_viewLayoutSizeOverride)
[self _dispatchSetViewLayoutSize:newViewLayoutSize];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes