[Qt][WK2] Do not apply new viewport properties until after the first visually non...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 10:56:26 +0000 (10:56 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 10:56:26 +0000 (10:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72508

Delay applying viewport properties on the viewport item until after the first visually non-empty
layout finished. It enables the viewport to be intact until the new page is ready to be rendered.

Patch by Zalan Bujtas <zbujtas@gmail.com> on 2011-11-17
Reviewed by Kenneth Rohde Christiansen.

* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::QQuickWebViewPrivate):
(QQuickWebViewPrivate::loadDidCommit):
(QQuickWebViewPrivate::didFinishFirstNonEmptyLayout):
(QQuickWebViewPrivate::didChangeContentsSize):
(QQuickWebViewPrivate::didChangeViewportProperties):
(QQuickWebViewPrivate::updateViewportSize):
(QQuickWebViewPrivate::computeViewportConstraints):
* UIProcess/API/qt/qquickwebview_p.h:
(PostTransitionState::isTransitioningToNewPage):
* UIProcess/qt/ClientImpl.cpp:
(qt_wk_didFirstVisuallyNonEmptyLayoutForFrame):
(setupPageLoaderClient):
* UIProcess/qt/QtViewInterface.cpp:
(WebKit::QtViewInterface::didFinishFirstNonEmptyLayout):
(WebKit::QtViewInterface::didChangeContentsSize):
(WebKit::QtViewInterface::didChangeViewportProperties):
(WebKit::QtViewInterface::startDrag):
* UIProcess/qt/QtViewInterface.h:
* UIProcess/qt/QtViewportInteractionEngine.cpp:
(WebKit::QtViewportInteractionEngine::reset):
(WebKit::QtViewportInteractionEngine::applyConstraints):
* UIProcess/qt/QtViewportInteractionEngine.h:
* UIProcess/qt/QtWebPageProxy.cpp:
(QtWebPageProxy::didFinishFirstNonEmptyLayout):
(QtWebPageProxy::didChangeContentsSize):
(QtWebPageProxy::didChangeViewportProperties):
(QtWebPageProxy::startDrag):
* UIProcess/qt/QtWebPageProxy.h:

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

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
Source/WebKit2/UIProcess/qt/ClientImpl.cpp
Source/WebKit2/UIProcess/qt/QtViewInterface.cpp
Source/WebKit2/UIProcess/qt/QtViewInterface.h
Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
Source/WebKit2/UIProcess/qt/QtWebPageProxy.cpp
Source/WebKit2/UIProcess/qt/QtWebPageProxy.h

index 9dc3999..ab78d61 100644 (file)
@@ -1,3 +1,43 @@
+2011-11-17  Zalan Bujtas  <zbujtas@gmail.com>
+
+        [Qt][WK2] Do not apply new viewport properties until after the first visually non-empty layout.
+        https://bugs.webkit.org/show_bug.cgi?id=72508
+
+        Delay applying viewport properties on the viewport item until after the first visually non-empty
+        layout finished. It enables the viewport to be intact until the new page is ready to be rendered.
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        * UIProcess/API/qt/qquickwebview.cpp:
+        (QQuickWebViewPrivate::QQuickWebViewPrivate):
+        (QQuickWebViewPrivate::loadDidCommit):
+        (QQuickWebViewPrivate::didFinishFirstNonEmptyLayout):
+        (QQuickWebViewPrivate::didChangeContentsSize):
+        (QQuickWebViewPrivate::didChangeViewportProperties):
+        (QQuickWebViewPrivate::updateViewportSize):
+        (QQuickWebViewPrivate::computeViewportConstraints):
+        * UIProcess/API/qt/qquickwebview_p.h:
+        (PostTransitionState::isTransitioningToNewPage):
+        * UIProcess/qt/ClientImpl.cpp:
+        (qt_wk_didFirstVisuallyNonEmptyLayoutForFrame):
+        (setupPageLoaderClient):
+        * UIProcess/qt/QtViewInterface.cpp:
+        (WebKit::QtViewInterface::didFinishFirstNonEmptyLayout):
+        (WebKit::QtViewInterface::didChangeContentsSize):
+        (WebKit::QtViewInterface::didChangeViewportProperties):
+        (WebKit::QtViewInterface::startDrag):
+        * UIProcess/qt/QtViewInterface.h:
+        * UIProcess/qt/QtViewportInteractionEngine.cpp:
+        (WebKit::QtViewportInteractionEngine::reset):
+        (WebKit::QtViewportInteractionEngine::applyConstraints):
+        * UIProcess/qt/QtViewportInteractionEngine.h:
+        * UIProcess/qt/QtWebPageProxy.cpp:
+        (QtWebPageProxy::didFinishFirstNonEmptyLayout):
+        (QtWebPageProxy::didChangeContentsSize):
+        (QtWebPageProxy::didChangeViewportProperties):
+        (QtWebPageProxy::startDrag):
+        * UIProcess/qt/QtWebPageProxy.h:
+
 2011-11-17  Eunmi Lee  <eunmi15.lee@samsung.com>
 
         Reviewed by Martin Robinson.
index 6d0a6c6..3ec405e 100644 (file)
@@ -39,6 +39,8 @@
 
 QQuickWebViewPrivate::QQuickWebViewPrivate()
     : q_ptr(0)
+    , postTransitionState(adoptPtr(new PostTransitionState(this)))
+    , transitioningToNewPage(false)
     , useTraditionalDesktopBehaviour(false)
 {
 }
@@ -103,19 +105,46 @@ void QQuickWebViewPrivate::initializeTouch(QQuickWebView* viewport)
 
 void QQuickWebViewPrivate::loadDidCommit()
 {
-    if (!useTraditionalDesktopBehaviour)
-        interactionEngine->reset();
+    transitioningToNewPage = true;
 }
 
-void QQuickWebViewPrivate::contentSizeChanged(const QSize& newSize)
+void QQuickWebViewPrivate::didFinishFirstNonEmptyLayout()
 {
+    transitioningToNewPage = false;
+
     if (useTraditionalDesktopBehaviour)
         return;
 
+    postTransitionState->apply();
+}
+
+void QQuickWebViewPrivate::didChangeContentsSize(const QSize& newSize)
+{
+    if (useTraditionalDesktopBehaviour)
+        return;
+
+    if (isTransitioningToNewPage()) {
+        postTransitionState->contentsSize = newSize;
+        return;
+    }
+
     pageView->setWidth(newSize.width());
     pageView->setHeight(newSize.height());
 }
 
+void QQuickWebViewPrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+{
+    if (useTraditionalDesktopBehaviour)
+        return;
+
+    viewportArguments = args;
+
+    if (isTransitioningToNewPage())
+        return;
+
+    interactionEngine->applyConstraints(computeViewportConstraints());
+}
+
 void QQuickWebViewPrivate::scrollPositionRequested(const QPoint& pos)
 {
     if (!useTraditionalDesktopBehaviour)
@@ -142,7 +171,6 @@ void QQuickWebViewPrivate::_q_onVisibleChanged()
     wkPage->viewStateDidChange(WebPageProxy::ViewIsVisible);
 }
 
-
 void QQuickWebViewPrivate::updateViewportSize()
 {
     Q_Q(QQuickWebView);
@@ -155,17 +183,18 @@ void QQuickWebViewPrivate::updateViewportSize()
     // Let the WebProcess know about the new viewport size, so that
     // it can resize the content accordingly.
     wkPage->setViewportSize(viewportSize);
-    updateViewportConstraints();
+
+    interactionEngine->applyConstraints(computeViewportConstraints());
     _q_viewportUpdated();
 }
 
-void QQuickWebViewPrivate::updateViewportConstraints()
+QtViewportInteractionEngine::Constraints QQuickWebViewPrivate::computeViewportConstraints()
 {
     Q_Q(QQuickWebView);
+
     QSize availableSize = q->boundingRect().size().toSize();
 
-    if (availableSize.isEmpty())
-        return;
+    Q_ASSERT(!availableSize.isEmpty());
 
     WebPageProxy* wkPage = toImpl(pageProxy->pageRef());
     WebPreferences* wkPrefs = wkPage->pageGroup()->preferences();
@@ -182,27 +211,16 @@ void QQuickWebViewPrivate::updateViewportConstraints()
     WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr);
 
     QtViewportInteractionEngine::Constraints newConstraints;
+
     newConstraints.initialScale = attr.initialScale;
     newConstraints.minimumScale = attr.minimumScale;
     newConstraints.maximumScale = attr.maximumScale;
     newConstraints.devicePixelRatio = attr.devicePixelRatio;
     newConstraints.isUserScalable = !!attr.userScalable;
-    interactionEngine->setConstraints(newConstraints);
 
-    // Overwrite minimum scale value with fit-to-view value, unless the the content author
-    // explicitly says no. NB: We can only do this when we know we have a valid size, ie.
-    // after initial layout has completed.
+    return newConstraints;
 }
 
-void QQuickWebViewPrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args)
-{
-    if (useTraditionalDesktopBehaviour)
-        return;
-    viewportArguments = args;
-    updateViewportConstraints();
-}
-
-
 void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText)
 {
 #ifndef QT_NO_MESSAGEBOX
index 1883c7b..b62ea56 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QScopedPointer>
+#include <wtf/OwnPtr.h>
 
 class QtWebPageProxy;
 
@@ -51,10 +52,14 @@ public:
     void disableMouseEvents();
 
     void loadDidCommit();
-    void contentSizeChanged(const QSize& newSize);
+
+    void didFinishFirstNonEmptyLayout();
+    void didChangeContentsSize(const QSize& newSize);
+    void didChangeViewportProperties(const WebCore::ViewportArguments& args);
+
     void scrollPositionRequested(const QPoint& pos);
     void updateViewportSize();
-    void updateViewportConstraints();
+    QtViewportInteractionEngine::Constraints computeViewportConstraints();
 
     static QQuickWebViewPrivate* get(QQuickWebView* view)
     {
@@ -74,21 +79,51 @@ public:
     void runJavaScriptAlert(const QString&);
     bool runJavaScriptConfirm(const QString&);
     QString runJavaScriptPrompt(const QString&, const QString& defaultValue, bool& ok);
-    void didChangeViewportProperties(const WebCore::ViewportArguments& args);
 
 public slots:
     void setUseTraditionalDesktopBehaviour(bool enable);
 
 private:
+
+    // This class is responsible for collecting and applying all properties
+    // on the viewport item, when transitioning from page A to page B is finished.
+    // See more at https://trac.webkit.org/wiki/QtWebKitLayoutInteraction
+    class PostTransitionState {
+    public:
+        PostTransitionState(QQuickWebViewPrivate* parent)
+            : p(parent)
+        { }
+
+        void apply()
+        {
+            p->interactionEngine->reset();
+            p->interactionEngine->applyConstraints(p->computeViewportConstraints());
+
+            if (contentsSize.isValid()) {
+                p->pageView->setWidth(contentsSize.width());
+                p->pageView->setHeight(contentsSize.height());
+            }
+
+            contentsSize = QSize();
+        }
+
+        QQuickWebViewPrivate* p;
+        QSize contentsSize;
+    };
+
+    bool isTransitioningToNewPage() const { return transitioningToNewPage; }
+
     QScopedPointer<QQuickWebPage> pageView;
     QScopedPointer<WebKit::QtViewInterface> viewInterface;
     QScopedPointer<QtViewportInteractionEngine> interactionEngine;
 
-    WebCore::ViewportArguments viewportArguments;
-
     QQuickWebView* q_ptr;
     QScopedPointer<QtWebPageProxy> pageProxy;
 
+    WebCore::ViewportArguments viewportArguments;
+    OwnPtr<PostTransitionState> postTransitionState;
+    bool transitioningToNewPage;
+
     bool useTraditionalDesktopBehaviour;
     QFileDialog* fileDialog;
     WKOpenPanelResultListenerRef openPanelResultListener;
index 802ede6..a3e8f0e 100644 (file)
@@ -151,6 +151,14 @@ static void qt_wk_didFinishProgress(WKPageRef page, const void* clientInfo)
     toQtWebPageProxy(clientInfo)->didChangeLoadProgress(100);
 }
 
+static void qt_wk_didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo)
+{
+    if (!WKFrameIsMainFrame(frame))
+        return;
+
+    toQtWebPageProxy(clientInfo)->didFinishFirstNonEmptyLayout();
+}
+
 static void qt_wk_runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo)
 {
     QString qAlertText = WKStringCopyQString(alertText);
@@ -316,6 +324,7 @@ void setupPageLoaderClient(QtWebPageProxy* qtWebPageProxy, WebPageProxy* webPage
     loadClient.didStartProgress = qt_wk_didStartProgress;
     loadClient.didChangeProgress = qt_wk_didChangeProgress;
     loadClient.didFinishProgress = qt_wk_didFinishProgress;
+    loadClient.didFirstVisuallyNonEmptyLayoutForFrame = qt_wk_didFirstVisuallyNonEmptyLayoutForFrame;
     WKPageSetPageLoaderClient(qtWebPageProxy->pageRef(), &loadClient);
 }
 
index 6d8329b..84e7594 100644 (file)
@@ -57,9 +57,19 @@ QSize QtViewInterface::drawingAreaSize()
     return QSize(m_pageView->width(), m_pageView->height());
 }
 
-void QtViewInterface::contentSizeChanged(const QSize& newSize)
+void QtViewInterface::didFinishFirstNonEmptyLayout()
 {
-    m_viewportView->d_func()->contentSizeChanged(newSize);
+    m_viewportView->d_func()->didFinishFirstNonEmptyLayout();
+}
+
+void QtViewInterface::didChangeContentsSize(const QSize& newSize)
+{
+    m_viewportView->d_func()->didChangeContentsSize(newSize);
+}
+
+void QtViewInterface::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+{
+    m_viewportView->d_func()->didChangeViewportProperties(args);
 }
 
 void QtViewInterface::scrollPositionRequested(const QPoint& pos)
@@ -97,12 +107,6 @@ void QtViewInterface::startDrag(Qt::DropActions supportedDropActions, const QIma
     *clientPosition = window->mapFromGlobal(*globalPosition);
 }
 
-
-void QtViewInterface::didChangeViewportProperties(const WebCore::ViewportArguments& args)
-{
-    m_viewportView->d_func()->didChangeViewportProperties(args);
-}
-
 void QtViewInterface::didChangeUrl(const QUrl& url)
 {
     emit m_viewportView->urlChanged(url);
index 54c8341..407afd9 100644 (file)
@@ -65,7 +65,6 @@ public:
     virtual void setViewNeedsDisplay(const QRect&);
 
     virtual QSize drawingAreaSize();
-    virtual void contentSizeChanged(const QSize&);
     virtual void scrollPositionRequested(const QPoint& pos);
 
     virtual bool isActive();
@@ -73,6 +72,9 @@ public:
     virtual bool isVisible();
 
     virtual void startDrag(Qt::DropActions supportedDropActions, const QImage& dragImage, QMimeData*, QPoint* clientPosition, QPoint* globalPosition, Qt::DropAction*);
+
+    virtual void didFinishFirstNonEmptyLayout();
+    virtual void didChangeContentsSize(const QSize&);
     virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
 
     virtual void didChangeUrl(const QUrl&);
index 1c8acee..8c26b41 100644 (file)
@@ -330,10 +330,9 @@ void QtViewportInteractionEngine::reset()
     properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.33);
 
     scroller()->setScrollerProperties(properties);
-    setConstraints(Constraints());
 }
 
-void QtViewportInteractionEngine::setConstraints(const Constraints& constraints)
+void QtViewportInteractionEngine::applyConstraints(const Constraints& constraints)
 {
     if (m_constraints == constraints)
         return;
index 9f528d8..a865004 100644 (file)
@@ -65,7 +65,7 @@ public:
     bool event(QEvent*);
 
     void reset();
-    void setConstraints(const Constraints&);
+    void applyConstraints(const Constraints&);
 
     void setItemRectVisible(const QRectF&);
     void animateItemRectVisible(const QRectF&);
index 3564dd6..a58a7af 100644 (file)
@@ -446,9 +446,19 @@ void QtWebPageProxy::pageDidRequestScroll(const IntPoint& pos)
     m_viewInterface->scrollPositionRequested(pos);
 }
 
+void QtWebPageProxy::didFinishFirstNonEmptyLayout()
+{
+    m_viewInterface->didFinishFirstNonEmptyLayout();
+}
+
 void QtWebPageProxy::didChangeContentsSize(const IntSize& newSize)
 {
-    m_viewInterface->contentSizeChanged(QSize(newSize));
+    m_viewInterface->didChangeContentsSize(QSize(newSize));
+}
+
+void QtWebPageProxy::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+{
+    m_viewInterface->didChangeViewportProperties(args);
 }
 
 void QtWebPageProxy::toolTipChanged(const String&, const String& newTooltip)
@@ -792,11 +802,6 @@ void QtWebPageProxy::startDrag(const WebCore::DragData& dragData, PassRefPtr<Sha
     m_webPageProxy->dragEnded(clientPosition, globalPosition, dropActionToDragOperation(actualDropAction));
 }
 
-void QtWebPageProxy::didChangeViewportProperties(const WebCore::ViewportArguments& args)
-{
-    m_viewInterface->didChangeViewportProperties(args);
-}
-
 void QtWebPageProxy::handleDownloadRequest(DownloadProxy* download)
 {
     // This function is responsible for hooking up a DownloadProxy to our API layer
index 66dc47d..4c7750e 100644 (file)
@@ -99,10 +99,12 @@ public:
     virtual void processDidCrash();
     virtual void pageClosed() { }
     virtual void didRelaunchProcess();
+
+    virtual void didFinishFirstNonEmptyLayout();
     virtual void didChangeContentsSize(const WebCore::IntSize&);
+    virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
 
     virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
-    virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
     virtual void setCursor(const WebCore::Cursor&);
     virtual void setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves);
     virtual void toolTipChanged(const WTF::String&, const WTF::String&);