⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 232416 in webkit


Ignore:
Timestamp:
Jun 1, 2018, 1:58:27 PM (8 years ago)
Author:
Chris Dumez
Message:

Regression(r230876): Swipe navigation snapshot may get removed too early
https://bugs.webkit.org/show_bug.cgi?id=186168
<rdar://problem/39743617>

Reviewed by Tim Horton.

The swipe navigation snapshot would get removed too early when receiving a paint
event after requesting a history navigation but before the provisional load has
actually started. This is because of the asynchronous navigation policy decision
which occurs after requesting to navigate. To address the issue, we now start
listening for events only after the provisional load has started.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _didStartProvisionalLoadForMainFrame]):

  • UIProcess/API/Cocoa/WKWebViewInternal.h:
  • UIProcess/Cocoa/ViewGestureController.cpp:

(WebKit::ViewGestureController::didStartProvisionalLoadForMainFrame):
(WebKit::ViewGestureController::didReachMainFrameLoadTerminalState):
(WebKit::ViewGestureController::didSameDocumentNavigationForMainFrame):

  • UIProcess/Cocoa/ViewGestureController.h:
  • UIProcess/ios/PageClientImplIOS.mm:

(WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame):

  • UIProcess/ios/ViewGestureControllerIOS.mm:

(WebKit::ViewGestureController::endSwipeGesture):

  • UIProcess/mac/PageClientImplMac.h:
  • UIProcess/mac/PageClientImplMac.mm:

(WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame):

  • UIProcess/mac/ViewGestureControllerMac.mm:

(WebKit::ViewGestureController::endSwipeGesture):

Location:
trunk/Source/WebKit
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r232414 r232416  
     12018-06-01  Chris Dumez  <cdumez@apple.com>
     2
     3        Regression(r230876): Swipe navigation snapshot may get removed too early
     4        https://bugs.webkit.org/show_bug.cgi?id=186168
     5        <rdar://problem/39743617>
     6
     7        Reviewed by Tim Horton.
     8
     9        The swipe navigation snapshot would get removed too early when receiving a paint
     10        event after requesting a history navigation but before the provisional load has
     11        actually started. This is because of the asynchronous navigation policy decision
     12        which occurs after requesting to navigate. To address the issue, we now start
     13        listening for events only after the provisional load has started.
     14
     15        * UIProcess/API/Cocoa/WKWebView.mm:
     16        (-[WKWebView _didStartProvisionalLoadForMainFrame]):
     17        * UIProcess/API/Cocoa/WKWebViewInternal.h:
     18        * UIProcess/Cocoa/ViewGestureController.cpp:
     19        (WebKit::ViewGestureController::didStartProvisionalLoadForMainFrame):
     20        (WebKit::ViewGestureController::didReachMainFrameLoadTerminalState):
     21        (WebKit::ViewGestureController::didSameDocumentNavigationForMainFrame):
     22        * UIProcess/Cocoa/ViewGestureController.h:
     23        * UIProcess/ios/PageClientImplIOS.mm:
     24        (WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame):
     25        * UIProcess/ios/ViewGestureControllerIOS.mm:
     26        (WebKit::ViewGestureController::endSwipeGesture):
     27        * UIProcess/mac/PageClientImplMac.h:
     28        * UIProcess/mac/PageClientImplMac.mm:
     29        (WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame):
     30        * UIProcess/mac/ViewGestureControllerMac.mm:
     31        (WebKit::ViewGestureController::endSwipeGesture):
     32
    1332018-06-01  Jiewen Tan  <jiewen_tan@apple.com>
    234
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r232284 r232416  
    28282828        callback();
    28292829    }
     2830}
     2831
     2832- (void)_didStartProvisionalLoadForMainFrame
     2833{
     2834    if (_gestureController)
     2835        _gestureController->didStartProvisionalLoadForMainFrame();
    28302836}
    28312837
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h

    r231664 r232416  
    106106- (void)_scheduleVisibleContentRectUpdate;
    107107
     108- (void)_didStartProvisionalLoadForMainFrame;
    108109- (void)_didFinishLoadForMainFrame;
    109110- (void)_didFailLoadForMainFrame;
  • trunk/Source/WebKit/UIProcess/Cocoa/ViewGestureController.cpp

    r230896 r232416  
    128128}
    129129
     130void ViewGestureController::didStartProvisionalLoadForMainFrame()
     131{
     132    if (auto provisionalLoadCallback = WTFMove(m_provisionalLoadCallback))
     133        provisionalLoadCallback();
     134}
     135
    130136
    131137void ViewGestureController::didFirstVisuallyNonEmptyLayoutForMainFrame()
     
    156162void ViewGestureController::didReachMainFrameLoadTerminalState()
    157163{
     164    if (m_provisionalLoadCallback) {
     165        m_provisionalLoadCallback = nullptr;
     166        removeSwipeSnapshot();
     167        return;
     168    }
     169
    158170    if (!m_snapshotRemovalTracker.eventOccurred(SnapshotRemovalTracker::MainFrameLoad))
    159171        return;
     
    180192void ViewGestureController::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType type)
    181193{
     194    if (m_provisionalLoadCallback) {
     195        m_provisionalLoadCallback = nullptr;
     196        removeSwipeSnapshot();
     197        return;
     198    }
     199
    182200    bool cancelledOutstandingEvent = false;
    183201
  • trunk/Source/WebKit/UIProcess/Cocoa/ViewGestureController.h

    r230506 r232416  
    123123    WebCore::Color backgroundColorForCurrentSnapshot() const { return m_backgroundColorForCurrentSnapshot; }
    124124
     125    void didStartProvisionalLoadForMainFrame();
    125126    void didFinishLoadForMainFrame() { didReachMainFrameLoadTerminalState(); }
    126127    void didFailLoadForMainFrame() { didReachMainFrameLoadTerminalState(); }
     
    296297#endif
    297298
     299    WTF::Function<void()> m_provisionalLoadCallback;
    298300    SnapshotRemovalTracker m_snapshotRemovalTracker;
    299301};
  • trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm

    r231242 r232416  
    246246void PageClientImpl::didStartProvisionalLoadForMainFrame()
    247247{
     248    [m_webView _didStartProvisionalLoadForMainFrame];
    248249    [m_webView _hidePasswordView];
    249250}
  • trunk/Source/WebKit/UIProcess/ios/ViewGestureControllerIOS.mm

    r232082 r232416  
    297297    m_webPageProxyForBackForwardListForCurrentSwipe->goToBackForwardItem(*targetItem);
    298298
    299     if (auto drawingArea = m_webPageProxy.drawingArea()) {
    300         uint64_t pageID = m_webPageProxy.pageID();
    301         GestureID gestureID = m_currentGestureID;
    302         drawingArea->dispatchAfterEnsuringDrawing([pageID, gestureID] (CallbackBase::Error error) {
    303             if (auto gestureController = controllerForGesture(pageID, gestureID))
    304                 gestureController->willCommitPostSwipeTransitionLayerTree(error == CallbackBase::Error::None);
     299    if (!m_webPageProxy.drawingArea()) {
     300        removeSwipeSnapshot();
     301        return;
     302    }
     303
     304    m_provisionalLoadCallback = [this] {
     305        if (auto drawingArea = m_webPageProxy.drawingArea()) {
     306            uint64_t pageID = m_webPageProxy.pageID();
     307            GestureID gestureID = m_currentGestureID;
     308            drawingArea->dispatchAfterEnsuringDrawing([pageID, gestureID] (CallbackBase::Error error) {
     309                if (auto gestureController = controllerForGesture(pageID, gestureID))
     310                    gestureController->willCommitPostSwipeTransitionLayerTree(error == CallbackBase::Error::None);
     311            });
     312            drawingArea->hideContentUntilPendingUpdate();
     313        } else {
     314            removeSwipeSnapshot();
     315            return;
     316        }
     317
     318        // FIXME: Should we wait for VisuallyNonEmptyLayout like we do on Mac?
     319        m_snapshotRemovalTracker.start(SnapshotRemovalTracker::RenderTreeSizeThreshold
     320            | SnapshotRemovalTracker::RepaintAfterNavigation
     321            | SnapshotRemovalTracker::MainFrameLoad
     322            | SnapshotRemovalTracker::SubresourceLoads
     323            | SnapshotRemovalTracker::ScrollPositionRestoration, [this] {
     324                this->removeSwipeSnapshot();
    305325        });
    306         drawingArea->hideContentUntilPendingUpdate();
    307     } else {
    308         removeSwipeSnapshot();
    309         return;
    310     }
    311 
    312     // FIXME: Should we wait for VisuallyNonEmptyLayout like we do on Mac?
    313     m_snapshotRemovalTracker.start(SnapshotRemovalTracker::RenderTreeSizeThreshold
    314         | SnapshotRemovalTracker::RepaintAfterNavigation
    315         | SnapshotRemovalTracker::MainFrameLoad
    316         | SnapshotRemovalTracker::SubresourceLoads
    317         | SnapshotRemovalTracker::ScrollPositionRestoration, [this] {
    318             this->removeSwipeSnapshot();
    319     });
     326    };
    320327
    321328    if (ViewSnapshot* snapshot = targetItem->snapshot()) {
  • trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h

    r228857 r232416  
    206206    NSWindow *activeWindow() const;
    207207
     208    void didStartProvisionalLoadForMainFrame() override;
    208209    void didFirstVisuallyNonEmptyLayoutForMainFrame() override;
    209210    void didFinishLoadForMainFrame() override;
  • trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm

    r230512 r232416  
    756756}
    757757
     758void PageClientImpl::didStartProvisionalLoadForMainFrame()
     759{
     760    if (auto gestureController = m_impl->gestureController())
     761        gestureController->didStartProvisionalLoadForMainFrame();
     762}
     763
    758764void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
    759765{
  • trunk/Source/WebKit/UIProcess/mac/ViewGestureControllerMac.mm

    r230506 r232416  
    744744    m_webPageProxy.goToBackForwardItem(*targetItem);
    745745
    746     SnapshotRemovalTracker::Events desiredEvents = SnapshotRemovalTracker::VisuallyNonEmptyLayout
    747         | SnapshotRemovalTracker::MainFrameLoad
    748         | SnapshotRemovalTracker::SubresourceLoads
    749         | SnapshotRemovalTracker::ScrollPositionRestoration;
    750     if (renderTreeSize)
    751         desiredEvents |= SnapshotRemovalTracker::RenderTreeSizeThreshold;
    752     m_snapshotRemovalTracker.start(desiredEvents, [this] { this->forceRepaintIfNeeded(); });
     746    m_provisionalLoadCallback = [this, renderTreeSize] {
     747        SnapshotRemovalTracker::Events desiredEvents = SnapshotRemovalTracker::VisuallyNonEmptyLayout
     748            | SnapshotRemovalTracker::MainFrameLoad
     749            | SnapshotRemovalTracker::SubresourceLoads
     750            | SnapshotRemovalTracker::ScrollPositionRestoration;
     751        if (renderTreeSize)
     752            desiredEvents |= SnapshotRemovalTracker::RenderTreeSizeThreshold;
     753        m_snapshotRemovalTracker.start(desiredEvents, [this] { this->forceRepaintIfNeeded(); });
     754    };
    753755
    754756    // FIXME: Like on iOS, we should ensure that even if one of the timeouts fires,
Note: See TracChangeset for help on using the changeset viewer.