Title: [258821] trunk/Source/WebKit
- Revision
- 258821
- Author
- [email protected]
- Date
- 2020-03-22 12:29:40 -0700 (Sun, 22 Mar 2020)
Log Message
Adopt -[UIWindowScene interfaceOrientation] when determining device orientation
https://bugs.webkit.org/show_bug.cgi?id=209372
<rdar://problem/60491857>
Reviewed by Darin Adler.
Currently, for WebKit clients that have adopted the UIScene lifecycle (and also do not set an interface
orientation override, like MobileSafari does), device orientation APIs will always report that the device is in
portrait mode, regardless of the actual device orientation. This is because our current mechanism for tracking
device orientation asks the shared UIApplication for its -statusBarOrientation. This is hard-coded to always
return UIInterfaceOrientationPortrait for apps that adopt the UIScene lifecycle, and will additionally trigger a
simulated crash, explaining that it is invalid for any scene-based app to call -statusBarOrientation.
To fix this, we adjust the `deviceOrientation` helper in WKWebViewIOS.mm to work for scene-based apps. See below
for more details.
* Platform/spi/ios/UIKitSPI.h:
* UIProcess/API/ios/WKWebViewIOS.h:
* UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _setupScrollAndContentViews]):
Change call sites of `deviceOrientation()` to be `[self _deviceOrientation]` instead.
(-[WKWebView _deviceOrientation]):
Replace `deviceOrientation()` with a `_deviceOrientation` helper method on `WKWebView`. For non-scene-based
apps, this new helper method does not change any behavior, and continues to go through UIApplication. However,
for scene-based apps, we instead ask the web view's window's `UIWindowScene` for its interface orientation.
Importantly, this means that if a WKWebView is not parented, it doesn't have a valid device orientation (i.e.
the orientation is UIInterfaceOrientationUnknown). As such, a newly created WKWebView that is unparented will
start out with no orientation; it's only upon moving the view into a window that it is able to determine the
device orientation. To ensure this, we add logic to -didMoveToWindow to recompute device orientation and
dispatch an update if needed.
To avoid sending unnecessary updates, if a WKWebView is unparented, we wait until it's parented again to send
the new device orientation.
(-[WKWebView didMoveToWindow]):
(-[WKWebView _windowDidRotate:]):
(deviceOrientation): Deleted.
See -[WKWebView _deviceOrientation] above.
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (258820 => 258821)
--- trunk/Source/WebKit/ChangeLog 2020-03-22 17:41:12 UTC (rev 258820)
+++ trunk/Source/WebKit/ChangeLog 2020-03-22 19:29:40 UTC (rev 258821)
@@ -1,3 +1,49 @@
+2020-03-22 Wenson Hsieh <[email protected]>
+
+ Adopt -[UIWindowScene interfaceOrientation] when determining device orientation
+ https://bugs.webkit.org/show_bug.cgi?id=209372
+ <rdar://problem/60491857>
+
+ Reviewed by Darin Adler.
+
+ Currently, for WebKit clients that have adopted the UIScene lifecycle (and also do not set an interface
+ orientation override, like MobileSafari does), device orientation APIs will always report that the device is in
+ portrait mode, regardless of the actual device orientation. This is because our current mechanism for tracking
+ device orientation asks the shared UIApplication for its -statusBarOrientation. This is hard-coded to always
+ return UIInterfaceOrientationPortrait for apps that adopt the UIScene lifecycle, and will additionally trigger a
+ simulated crash, explaining that it is invalid for any scene-based app to call -statusBarOrientation.
+
+ To fix this, we adjust the `deviceOrientation` helper in WKWebViewIOS.mm to work for scene-based apps. See below
+ for more details.
+
+ * Platform/spi/ios/UIKitSPI.h:
+ * UIProcess/API/ios/WKWebViewIOS.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _setupScrollAndContentViews]):
+
+ Change call sites of `deviceOrientation()` to be `[self _deviceOrientation]` instead.
+
+ (-[WKWebView _deviceOrientation]):
+
+ Replace `deviceOrientation()` with a `_deviceOrientation` helper method on `WKWebView`. For non-scene-based
+ apps, this new helper method does not change any behavior, and continues to go through UIApplication. However,
+ for scene-based apps, we instead ask the web view's window's `UIWindowScene` for its interface orientation.
+
+ Importantly, this means that if a WKWebView is not parented, it doesn't have a valid device orientation (i.e.
+ the orientation is UIInterfaceOrientationUnknown). As such, a newly created WKWebView that is unparented will
+ start out with no orientation; it's only upon moving the view into a window that it is able to determine the
+ device orientation. To ensure this, we add logic to -didMoveToWindow to recompute device orientation and
+ dispatch an update if needed.
+
+ To avoid sending unnecessary updates, if a WKWebView is unparented, we wait until it's parented again to send
+ the new device orientation.
+
+ (-[WKWebView didMoveToWindow]):
+ (-[WKWebView _windowDidRotate:]):
+ (deviceOrientation): Deleted.
+
+ See -[WKWebView _deviceOrientation] above.
+
2020-03-21 David Kilzer <[email protected]>
decodeSharedBuffer() in WebCoreArgumentCoders.cpp should validate `bufferSize`
Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (258820 => 258821)
--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2020-03-22 17:41:12 UTC (rev 258820)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2020-03-22 19:29:40 UTC (rev 258821)
@@ -194,6 +194,7 @@
- (void)_enqueueHIDEvent:(IOHIDEventRef)event;
- (void)_handleHIDEvent:(IOHIDEventRef)event;
- (void)handleKeyUIEvent:(UIEvent *)event;
+- (BOOL)_appAdoptsUISceneLifecycle;
@end
typedef NS_ENUM(NSInteger, UIDatePickerPrivateMode) {
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h (258820 => 258821)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2020-03-22 17:41:12 UTC (rev 258820)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2020-03-22 19:29:40 UTC (rev 258821)
@@ -135,6 +135,7 @@
@property (nonatomic, readonly) UIEdgeInsets _computedObscuredInset;
@property (nonatomic, readonly) UIEdgeInsets _computedUnobscuredSafeAreaInset;
@property (nonatomic, readonly, getter=_isRetainingActiveFocusedState) BOOL _retainingActiveFocusedState;
+@property (nonatomic, readonly) int32_t _deviceOrientation;
- (BOOL)_effectiveAppearanceIsDark;
- (BOOL)_effectiveUserInterfaceLevelIsElevated;
@@ -141,6 +142,4 @@
@end
-int32_t deviceOrientation();
-
#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (258820 => 258821)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-03-22 17:41:12 UTC (rev 258820)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-03-22 19:29:40 UTC (rev 258821)
@@ -88,13 +88,6 @@
}
}
-int32_t deviceOrientation()
-{
-ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- return deviceOrientationForUIInterfaceOrientation([[UIApplication sharedApplication] statusBarOrientation]);
-ALLOW_DEPRECATED_DECLARATIONS_END
-}
-
@interface UIView (UIViewInternal)
- (UIViewController *)_viewControllerForAncestor;
@end
@@ -157,7 +150,7 @@
[self addSubview:_scrollView.get()];
- [self _dispatchSetDeviceOrientation:deviceOrientation()];
+ [self _dispatchSetDeviceOrientation:[self _deviceOrientation]];
[_contentView layer].anchorPoint = CGPointZero;
[_contentView setFrame:bounds];
@@ -230,6 +223,19 @@
return _focusPreservationCount || _activeFocusedStateRetainCount;
}
+- (int32_t)_deviceOrientation
+{
+ auto orientation = UIInterfaceOrientationUnknown;
+ auto application = UIApplication.sharedApplication;
+ALLOW_DEPRECATED_DECLARATIONS_BEGIN
+ if (!application._appAdoptsUISceneLifecycle)
+ orientation = application.statusBarOrientation;
+ALLOW_DEPRECATED_DECLARATIONS_END
+ else if (auto windowScene = self.window.windowScene)
+ orientation = windowScene.interfaceOrientation;
+ return deviceOrientationForUIInterfaceOrientation(orientation);
+}
+
- (BOOL)_effectiveAppearanceIsDark
{
return self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark;
@@ -1395,6 +1401,8 @@
- (void)didMoveToWindow
{
+ if (!_overridesInterfaceOrientation)
+ [self _dispatchSetDeviceOrientation:[self _deviceOrientation]];
_page->activityStateDidChange(WebCore::ActivityState::allFlags());
_page->webViewDidMoveToWindow();
}
@@ -2241,7 +2249,7 @@
- (void)_windowDidRotate:(NSNotification *)notification
{
if (!_overridesInterfaceOrientation)
- [self _dispatchSetDeviceOrientation:deviceOrientation()];
+ [self _dispatchSetDeviceOrientation:[self _deviceOrientation]];
}
- (void)_contentSizeCategoryDidChange:(NSNotification *)notification
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes