Title: [227869] trunk/Source/WebKit
Revision
227869
Author
[email protected]
Date
2018-01-30 19:02:59 -0800 (Tue, 30 Jan 2018)

Log Message

WKWebView layout is sometimes wrong after rotation on iPhone X
https://bugs.webkit.org/show_bug.cgi?id=182304
<rdar://problem/34158671>

Reviewed by Simon Fraser.

* Platform/spi/ios/UIKitSPI.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _computedContentInset]):
(-[WKWebView _scrollViewSystemContentInset]):
(activeMinimumLayoutSize):
It turns out that it is not always safe to look at the safe area insets of
children from inside layoutSubviews, even after the call to super.

Instead, make use of the fact that WKScrollView and WKWebView have identical
coordinate spaces, and map WKWebView's safe area insets into the WKScrollView.
It's safe to use the scroll view's affected-edges and contentScrollInset,
because those aren't updated at the same outside-of-layout time that
safe area insets are.

We could alternatively move all calls to activeMinimumLayoutSize outside
of layoutSubviews, but that seems like a larger and riskier change.

All attempts to write a test have failed; this depends heavily on use of
autolayout and the mechanism by which the system updates system-owned
safe area insets during device rotation.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (227868 => 227869)


--- trunk/Source/WebKit/ChangeLog	2018-01-31 01:49:54 UTC (rev 227868)
+++ trunk/Source/WebKit/ChangeLog	2018-01-31 03:02:59 UTC (rev 227869)
@@ -1,3 +1,32 @@
+2018-01-30  Tim Horton  <[email protected]>
+
+        WKWebView layout is sometimes wrong after rotation on iPhone X
+        https://bugs.webkit.org/show_bug.cgi?id=182304
+        <rdar://problem/34158671>
+
+        Reviewed by Simon Fraser.
+
+        * Platform/spi/ios/UIKitSPI.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _computedContentInset]):
+        (-[WKWebView _scrollViewSystemContentInset]):
+        (activeMinimumLayoutSize):
+        It turns out that it is not always safe to look at the safe area insets of
+        children from inside layoutSubviews, even after the call to super.
+
+        Instead, make use of the fact that WKScrollView and WKWebView have identical
+        coordinate spaces, and map WKWebView's safe area insets into the WKScrollView.
+        It's safe to use the scroll view's affected-edges and contentScrollInset,
+        because those aren't updated at the same outside-of-layout time that
+        safe area insets are.
+
+        We could alternatively move all calls to activeMinimumLayoutSize outside
+        of layoutSubviews, but that seems like a larger and riskier change.
+
+        All attempts to write a test have failed; this depends heavily on use of
+        autolayout and the mechanism by which the system updates system-owned
+        safe area insets during device rotation.
+
 2018-01-30  Don Olmstead  <[email protected]>
 
         JSExports.h should be included as <_javascript_Core/JSExportMacros.h>

Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (227868 => 227869)


--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2018-01-31 01:49:54 UTC (rev 227868)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2018-01-31 03:02:59 UTC (rev 227869)
@@ -324,6 +324,7 @@
 @property (nonatomic) CGFloat horizontalScrollDecelerationFactor;
 @property (nonatomic) CGFloat verticalScrollDecelerationFactor;
 @property (nonatomic, readonly) BOOL _isInterruptingDeceleration;
+@property (nonatomic, getter=_contentScrollInset, setter=_setContentScrollInset:) UIEdgeInsets contentScrollInset;
 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
 @property (nonatomic, readonly) UIEdgeInsets _systemContentInset;
 #endif
@@ -974,6 +975,7 @@
 - (UIScrollView *)_scroller;
 - (CGPoint)accessibilityConvertPointFromSceneReferenceCoordinates:(CGPoint)point;
 - (CGRect)accessibilityConvertRectToSceneReferenceCoordinates:(CGRect)rect;
+- (UIRectEdge)_edgesApplyingSafeAreaInsetsToContentInset;
 @end
 
 @interface UIPeripheralHost (IPI)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (227868 => 227869)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-01-31 01:49:54 UTC (rev 227868)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-01-31 03:02:59 UTC (rev 227869)
@@ -1567,7 +1567,7 @@
 
 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
     if (self._safeAreaShouldAffectObscuredInsets)
-        insets = UIEdgeInsetsAdd(insets, [_scrollView _systemContentInset], self._effectiveObscuredInsetEdgesAffectedBySafeArea);
+        insets = UIEdgeInsetsAdd(insets, self._scrollViewSystemContentInset, self._effectiveObscuredInsetEdgesAffectedBySafeArea);
 #endif
 
     return insets;
@@ -2463,6 +2463,15 @@
     _enclosingScrollViewScrollTimer = nil;
 }
 
+- (UIEdgeInsets)_scrollViewSystemContentInset
+{
+    // It's not safe to access the scroll view's safeAreaInsets or _systemContentInset from
+    // inside our layoutSubviews implementation, because they aren't updated until afterwards.
+    // Instead, depend on the fact that the UIScrollView and WKWebView are in the same coordinate
+    // space, and map the WKWebView's own insets into the scroll view manually.
+    return UIEdgeInsetsAdd([_scrollView _contentScrollInset], self.safeAreaInsets, [_scrollView _edgesApplyingSafeAreaInsetsToContentInset]);
+}
+
 static WebCore::FloatSize activeMinimumLayoutSize(WKWebView *webView, const CGRect& bounds)
 {
     if (webView->_overridesMinimumLayoutSize)
@@ -2469,8 +2478,7 @@
         return WebCore::FloatSize(webView->_minimumLayoutSizeOverride);
 
 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
-    UIEdgeInsets systemContentInset = [webView->_scrollView _systemContentInset];
-    return WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), systemContentInset).size);
+    return WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), webView._scrollViewSystemContentInset).size);
 #else
     return WebCore::FloatSize(bounds.size);
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to