[Fullscreen] Page sometimes ends up with an incorrect zoom level after entering fulls...
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2018 21:23:12 +0000 (21:23 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2018 21:23:12 +0000 (21:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186822

Reviewed by Simon Fraser.

Source/WebCore:

* dom/Document.cpp:
(WebCore::Document::setOverrideViewportArguments):
(WebCore::Document::updateViewportArguments):
* dom/Document.h:

Source/WebKit:

Set the minimum zoom, maximum zoom, zoom bouncing, and user scalability settings of the
WKWebView's UIScrollView upon entering fullscreen, and restore those same settings upon
exit. Override the viewport arguments upon entering fullscreen, restore them upon exit.

* Platform/IPC/ArgumentCoder.h:
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ViewportArguments>::decode):
* Shared/WebCoreArgumentCoders.h:
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::forceAlwaysUserScalable const):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setOverrideViewportArguments):
* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(WebKit::WKWebViewState::applyTo):
(WebKit::WKWebViewState::store):
(-[WKFullScreenWindowController enterFullScreen]):
(-[WKFullScreenWindowController beganExitFullScreenWithInitialFrame:finalFrame:]):
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::forceAlwaysUserScalable const):
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setOverrideViewportArguments):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233059 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebKit/ChangeLog
Source/WebKit/Platform/IPC/ArgumentCoder.h
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

index 5db57ca..73aad94 100644 (file)
@@ -1,3 +1,15 @@
+2018-06-21  Jer Noble  <jer.noble@apple.com>
+
+        [Fullscreen] Page sometimes ends up with an incorrect zoom level after entering fullscreen
+        https://bugs.webkit.org/show_bug.cgi?id=186822
+
+        Reviewed by Simon Fraser.
+
+        * dom/Document.cpp:
+        (WebCore::Document::setOverrideViewportArguments):
+        (WebCore::Document::updateViewportArguments):
+        * dom/Document.h:
+
 2018-06-20  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         RenderSVGInline has to be inline always regardless of its css display value
index 6873146..fc083cc 100644 (file)
@@ -3425,6 +3425,15 @@ void Document::dispatchDisabledAdaptationsDidChangeForMainFrame()
     page()->chrome().dispatchDisabledAdaptationsDidChange(m_disabledAdaptations);
 }
 
+void Document::setOverrideViewportArguments(const std::optional<ViewportArguments>& viewportArguments)
+{
+    if (viewportArguments == m_overrideViewportArguments)
+        return;
+
+    m_overrideViewportArguments = viewportArguments;
+    updateViewportArguments();
+}
+
 void Document::processViewport(const String& features, ViewportArguments::Type origin)
 {
     ASSERT(!features.isNull());
@@ -3451,7 +3460,7 @@ void Document::updateViewportArguments()
 #ifndef NDEBUG
         m_didDispatchViewportPropertiesChanged = true;
 #endif
-        page()->chrome().dispatchViewportPropertiesDidChange(m_viewportArguments);
+        page()->chrome().dispatchViewportPropertiesDidChange(m_overrideViewportArguments ? m_overrideViewportArguments.value() : m_viewportArguments);
         page()->chrome().didReceiveDocType(*frame());
     }
 }
index 6ed1e68..25bee77 100644 (file)
@@ -391,6 +391,9 @@ public:
 
     void setViewportArguments(const ViewportArguments& viewportArguments) { m_viewportArguments = viewportArguments; }
     ViewportArguments viewportArguments() const { return m_viewportArguments; }
+
+    WEBCORE_EXPORT void setOverrideViewportArguments(const std::optional<ViewportArguments>&);
+
     OptionSet<DisabledAdaptations> disabledAdaptations() const { return m_disabledAdaptations; }
 #ifndef NDEBUG
     bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
@@ -1715,6 +1718,7 @@ private:
     Timer m_loadEventDelayTimer;
 
     ViewportArguments m_viewportArguments;
+    std::optional<ViewportArguments> m_overrideViewportArguments;
     OptionSet<DisabledAdaptations> m_disabledAdaptations;
 
     DocumentTiming m_documentTiming;
index 900822d..532770e 100644 (file)
@@ -1,5 +1,35 @@
 2018-06-21  Jer Noble  <jer.noble@apple.com>
 
+        [Fullscreen] Page sometimes ends up with an incorrect zoom level after entering fullscreen
+        https://bugs.webkit.org/show_bug.cgi?id=186822
+
+        Reviewed by Simon Fraser.
+
+        Set the minimum zoom, maximum zoom, zoom bouncing, and user scalability settings of the
+        WKWebView's UIScrollView upon entering fullscreen, and restore those same settings upon
+        exit. Override the viewport arguments upon entering fullscreen, restore them upon exit.
+
+        * Platform/IPC/ArgumentCoder.h:
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ViewportArguments>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::forceAlwaysUserScalable const):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setOverrideViewportArguments):
+        * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
+        (WebKit::WKWebViewState::applyTo):
+        (WebKit::WKWebViewState::store):
+        (-[WKFullScreenWindowController enterFullScreen]):
+        (-[WKFullScreenWindowController beganExitFullScreenWithInitialFrame:finalFrame:]):
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::forceAlwaysUserScalable const):
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setOverrideViewportArguments):
+
+2018-06-21  Jer Noble  <jer.noble@apple.com>
+
         [Fullscreen] Use secondary glyph style for fullscreen controls
         https://bugs.webkit.org/show_bug.cgi?id=186862
         <rdar://problem/41212210>
index 5ab08af..9ecfdae 100644 (file)
@@ -31,6 +31,7 @@ namespace WebCore {
 class IntConstraint;
 class DoubleConstraint;
 class ResourceResponse;
+struct ViewportArguments;
 }
 
 namespace IPC {
index c926508..71287ef 100644 (file)
@@ -659,6 +659,14 @@ bool ArgumentCoder<ViewportArguments>::decode(Decoder& decoder, ViewportArgument
 {
     return SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments);
 }
+
+std::optional<ViewportArguments> ArgumentCoder<ViewportArguments>::decode(Decoder& decoder)
+{
+    ViewportArguments viewportArguments;
+    if (!SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments))
+        return std::nullopt;
+    return WTFMove(viewportArguments);
+}
 #endif // PLATFORM(IOS)
 
 
index edabab6..6218b88 100644 (file)
@@ -267,6 +267,7 @@ template<> struct ArgumentCoder<WebCore::FloatQuad> {
 template<> struct ArgumentCoder<WebCore::ViewportArguments> {
     static void encode(Encoder&, const WebCore::ViewportArguments&);
     static bool decode(Decoder&, WebCore::ViewportArguments&);
+    static std::optional<WebCore::ViewportArguments> decode(Decoder&);
 };
 #endif // PLATFORM(IOS)
 
index b1050c9..49b21c5 100644 (file)
@@ -560,6 +560,7 @@ public:
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
     int32_t deviceOrientation() const { return m_deviceOrientation; }
+    void setOverrideViewportArguments(const std::optional<WebCore::ViewportArguments>&);
     void willCommitLayerTree(uint64_t transactionID);
 
     void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&&);
@@ -606,6 +607,7 @@ public:
     void getSelectionContext(WTF::Function<void(const String&, const String&, const String&, CallbackBase::Error)>&&);
     void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
     void setForceAlwaysUserScalable(bool);
+    bool forceAlwaysUserScalable() const { return m_forceAlwaysUserScalable; }
     void setIsScrollingOrZooming(bool);
     void requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity, uint32_t offset, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
     void requestRectsAtSelectionOffsetWithText(int32_t offset, const String&, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
index fe0c737..f31515c 100644 (file)
@@ -354,6 +354,12 @@ void WebPageProxy::setDeviceOrientation(int32_t deviceOrientation)
     }
 }
 
+void WebPageProxy::setOverrideViewportArguments(const std::optional<ViewportArguments>& viewportArguments)
+{
+    if (isValid())
+        m_process->send(Messages::WebPage::SetOverrideViewportArguments(viewportArguments), m_pageID);
+}
+
 static bool exceedsRenderTreeSizeSizeThreshold(uint64_t thresholdSize, uint64_t committedSize)
 {
     const double thesholdSizeFraction = 0.5; // Empirically-derived.
index aa4f5cf..d5c4d4c 100644 (file)
@@ -44,6 +44,7 @@
 #import <WebCore/GeometryUtilities.h>
 #import <WebCore/IntRect.h>
 #import <WebCore/LocalizedStrings.h>
+#import <WebCore/ViewportArguments.h>
 #import <WebCore/WebCoreNSURLExtras.h>
 #import <pal/spi/cf/CFNetworkSPI.h>
 #import <pal/spi/cocoa/NSStringSPI.h>
@@ -95,6 +96,10 @@ struct WKWebViewState {
     UIEdgeInsets _savedObscuredInsets = UIEdgeInsetsZero;
     UIEdgeInsets _savedScrollIndicatorInsets = UIEdgeInsetsZero;
     CGPoint _savedContentOffset = CGPointZero;
+    CGFloat _savedMinimumZoomScale = 1;
+    CGFloat _savedMaximumZoomScale = 1;
+    BOOL _savedBouncesZoom = NO;
+    BOOL _savedForceAlwaysUserScalable = NO;
 
     void applyTo(WKWebView* webView)
     {
@@ -104,8 +109,12 @@ struct WKWebViewState {
         [[webView scrollView] setContentOffset:_savedContentOffset];
         [[webView scrollView] setScrollIndicatorInsets:_savedScrollIndicatorInsets];
         [webView _page]->setTopContentInset(_savedTopContentInset);
+        [webView _page]->setForceAlwaysUserScalable(_savedForceAlwaysUserScalable);
         [webView _setViewScale:_savedViewScale];
         [[webView scrollView] setZoomScale:_savedZoomScale];
+        webView.scrollView.minimumZoomScale = _savedMinimumZoomScale;
+        webView.scrollView.maximumZoomScale = _savedMaximumZoomScale;
+        webView.scrollView.bouncesZoom = _savedBouncesZoom;
     }
     
     void store(WKWebView* webView)
@@ -116,8 +125,12 @@ struct WKWebViewState {
         _savedContentOffset = [[webView scrollView] contentOffset];
         _savedScrollIndicatorInsets = [[webView scrollView] scrollIndicatorInsets];
         _savedTopContentInset = [webView _page]->topContentInset();
+        _savedForceAlwaysUserScalable = [webView _page]->forceAlwaysUserScalable();
         _savedViewScale = [webView _viewScale];
         _savedZoomScale = [[webView scrollView] zoomScale];
+        _savedMinimumZoomScale = webView.scrollView.minimumZoomScale;
+        _savedMaximumZoomScale = webView.scrollView.maximumZoomScale;
+        _savedBouncesZoom = webView.scrollView.bouncesZoom;
     }
 };
 
@@ -494,6 +507,13 @@ static const NSTimeInterval kAnimationDuration = 0.2;
         
         [self _manager]->setAnimatingFullScreen(true);
 
+        ViewportArguments arguments { ViewportArguments::CSSDeviceAdaptation };
+        arguments.zoom = 1;
+        arguments.minZoom = 1;
+        arguments.maxZoom = 1;
+        arguments.userZoom = 1;
+        [webView _page]->setOverrideViewportArguments(arguments);
+
         _repaintCallback = VoidCallback::create([protectedSelf = retainPtr(self), self](WebKit::CallbackBase::Error) {
             _repaintCallback = nullptr;
             if (auto* manager = [protectedSelf _manager]) {
@@ -628,6 +648,7 @@ static const NSTimeInterval kAnimationDuration = 0.2;
     [webView becomeFirstResponder];
 
     _viewState.applyTo(webView.get());
+    [webView _page]->setOverrideViewportArguments(std::nullopt);
 
     [webView setNeedsLayout];
     [webView layoutIfNeeded];
index 40d3af8..32555c6 100644 (file)
@@ -657,7 +657,8 @@ public:
 
     void enableInspectorNodeSearch();
     void disableInspectorNodeSearch();
-    
+
+    bool forceAlwaysUserScalable() const { return m_forceAlwaysUserScalable; }
     void setForceAlwaysUserScalable(bool);
 #endif
 
@@ -890,6 +891,7 @@ public:
     void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&);
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
+    void setOverrideViewportArguments(const std::optional<WebCore::ViewportArguments>&);
     void dynamicViewportSizeUpdate(const WebCore::FloatSize& viewLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, DynamicViewportSizeUpdateID);
     std::optional<float> scaleFromUIProcess(const VisibleContentRectUpdateInfo&) const;
     void updateVisibleContentRects(const VisibleContentRectUpdateInfo&, MonotonicTime oldestTimestamp);
index 5e96a7b..686dafa 100644 (file)
@@ -48,6 +48,7 @@ messages -> WebPage LegacyReceiver {
     SetViewportConfigurationViewLayoutSize(WebCore::FloatSize size)
     SetMaximumUnobscuredSize(WebCore::FloatSize size)
     SetDeviceOrientation(int32_t deviceOrientation)
+    SetOverrideViewportArguments(std::optional<WebCore::ViewportArguments> arguments)
     DynamicViewportSizeUpdate(WebCore::FloatSize viewLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
 
     HandleTap(WebCore::IntPoint point, uint64_t lastLayerTreeTransactionId)
index 310fa3f..69d80aa 100644 (file)
@@ -2484,6 +2484,12 @@ void WebPage::setDeviceOrientation(int32_t deviceOrientation)
     m_page->mainFrame().orientationChanged();
 }
 
+void WebPage::setOverrideViewportArguments(const std::optional<WebCore::ViewportArguments>& arguments)
+{
+    if (auto* document = m_page->mainFrame().document())
+        document->setOverrideViewportArguments(arguments);
+}
+
 // WebCore stores the page scale factor as float instead of double. When we get a scale from WebCore,
 // we need to ignore differences that are within a small rounding error on floats.
 static inline bool areEssentiallyEqualAsFloat(float a, float b)