Title: [180539] trunk/Source/WebKit2
Revision
180539
Author
[email protected]
Date
2015-02-23 18:07:33 -0800 (Mon, 23 Feb 2015)

Log Message

[iOS WK2] The WebProcess keep scrolling pages based on the last velocity after scrolling has been interrupted
https://bugs.webkit.org/show_bug.cgi?id=141933
rdar://problem/18746673
rdar://problem/19711490

Patch by Benjamin Poulain <[email protected]> on 2015-02-23
Reviewed by Simon Fraser.

The bug happened like this:
1) The user scroll the page. WKContentView tracks the velocity and send
   the update rect + velocity to the WebProcess.
2) The user interupts the scrolling but does not commit to either scrolling
   again or cancelling the scrolling.
   Since we were not notified of this state, the WebProcess still believed
   the velocity is stable.
3) With any paint update, the WebProcess would account for the last velocity
   and try to guess the best repaint area. This would drift endlessly out
   of the view since the view is not really moving.

This patch fixes the issue by adding special handling for interrupted scrolling.

Kudos to Kurt Revis for providing us the required APIs.

* Shared/VisibleContentRectUpdateInfo.h:
(WebKit::operator==):
We can no longer filter VisibleContentRectUpdateInfo ignoring the velocity.

Typically, UIScrollView would call -scrollViewDidScroll: before being interrupted.
If we filter based on the VisibleContentRectUpdateInfo, we have two identical
states differing only by the velocity. If we filter the second update, the WebProcess
would never know the velocity should be zero.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _scrollViewDidInterruptDecelerating:]):
We get this callback when scrolling is interrupted. We just need to clear
the velocity and re-send a new update for the current state.

(-[WKWebView _updateVisibleContentRects]):
Do not consider an interrupted scroll as a stable state. We don't know if scrolling
will resume or will stop.

* UIProcess/ios/WKContentView.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView didInterruptScrolling]):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (180538 => 180539)


--- trunk/Source/WebKit2/ChangeLog	2015-02-24 01:43:36 UTC (rev 180538)
+++ trunk/Source/WebKit2/ChangeLog	2015-02-24 02:07:33 UTC (rev 180539)
@@ -1,3 +1,49 @@
+2015-02-23  Benjamin Poulain  <[email protected]>
+
+        [iOS WK2] The WebProcess keep scrolling pages based on the last velocity after scrolling has been interrupted
+        https://bugs.webkit.org/show_bug.cgi?id=141933
+        rdar://problem/18746673
+        rdar://problem/19711490
+
+        Reviewed by Simon Fraser.
+
+        The bug happened like this:
+        1) The user scroll the page. WKContentView tracks the velocity and send
+           the update rect + velocity to the WebProcess.
+        2) The user interupts the scrolling but does not commit to either scrolling
+           again or cancelling the scrolling.
+           Since we were not notified of this state, the WebProcess still believed
+           the velocity is stable.
+        3) With any paint update, the WebProcess would account for the last velocity
+           and try to guess the best repaint area. This would drift endlessly out
+           of the view since the view is not really moving.
+
+        This patch fixes the issue by adding special handling for interrupted scrolling.
+
+        Kudos to Kurt Revis for providing us the required APIs.
+
+        * Shared/VisibleContentRectUpdateInfo.h:
+        (WebKit::operator==):
+        We can no longer filter VisibleContentRectUpdateInfo ignoring the velocity.
+
+        Typically, UIScrollView would call -scrollViewDidScroll: before being interrupted.
+        If we filter based on the VisibleContentRectUpdateInfo, we have two identical
+        states differing only by the velocity. If we filter the second update, the WebProcess
+        would never know the velocity should be zero.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _scrollViewDidInterruptDecelerating:]):
+        We get this callback when scrolling is interrupted. We just need to clear
+        the velocity and re-send a new update for the current state.
+
+        (-[WKWebView _updateVisibleContentRects]):
+        Do not consider an interrupted scroll as a stable state. We don't know if scrolling
+        will resume or will stop.
+
+        * UIProcess/ios/WKContentView.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView didInterruptScrolling]):
+
 2015-02-23  Anders Carlsson  <[email protected]>
 
         Add API for fetching website data records to _WKWebsiteDataStore

Modified: trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h (180538 => 180539)


--- trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h	2015-02-24 01:43:36 UTC (rev 180538)
+++ trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h	2015-02-24 02:07:33 UTC (rev 180539)
@@ -101,6 +101,9 @@
         && a.exposedRect() == b.exposedRect()
         && a.unobscuredRect() == b.unobscuredRect()
         && a.customFixedPositionRect() == b.customFixedPositionRect()
+        && a.horizontalVelocity() == b.horizontalVelocity()
+        && a.verticalVelocity() == b.verticalVelocity()
+        && a.scaleChangeRate() == b.scaleChangeRate()
         && a.inStableState() == b.inStableState();
 }
 

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (180538 => 180539)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2015-02-24 01:43:36 UTC (rev 180538)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2015-02-24 02:07:33 UTC (rev 180539)
@@ -103,6 +103,7 @@
 @interface UIScrollView (UIScrollViewInternal)
 - (void)_adjustForAutomaticKeyboardInfo:(NSDictionary*)info animated:(BOOL)animated lastAdjustment:(CGFloat*)lastAdjustment;
 - (BOOL)_isScrollingToTop;
+- (BOOL)_isInterruptingDeceleration;
 @end
 
 @interface UIPeripheralHost(UIKitInternal)
@@ -1411,6 +1412,15 @@
     [self _didFinishScrolling];
 }
 
+- (void)_scrollViewDidInterruptDecelerating:(UIScrollView *)scrollView
+{
+    if (![self usesStandardContentView])
+        return;
+
+    [_contentView didInterruptScrolling];
+    [self _updateVisibleContentRects];
+}
+
 - (void)_frameOrBoundsChanged
 {
     CGRect bounds = self.bounds;
@@ -1466,6 +1476,11 @@
     CGFloat scaleFactor = contentZoomScale(self);
 
     BOOL isStableState = !(_isChangingObscuredInsetsInteractively || [_scrollView isDragging] || [_scrollView isDecelerating] || [_scrollView isZooming] || [_scrollView isZoomBouncing] || [_scrollView _isAnimatingZoom] || [_scrollView _isScrollingToTop]);
+
+    // FIXME: this can be made static after we stop supporting iOS 8.x.
+    if (isStableState && [_scrollView respondsToSelector:@selector(_isInterruptingDeceleration)])
+        isStableState = ![_scrollView performSelector:@selector(_isInterruptingDeceleration)];
+
     [_contentView didUpdateVisibleRect:visibleRectInContentCoordinates
         unobscuredRect:unobscuredRectInContentCoordinates
         unobscuredRectInScrollViewCoordinates:unobscuredRect

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.h (180538 => 180539)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.h	2015-02-24 01:43:36 UTC (rev 180538)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.h	2015-02-24 02:07:33 UTC (rev 180539)
@@ -71,6 +71,7 @@
     inStableState:(BOOL)isStableState isChangingObscuredInsetsInteractively:(BOOL)isChangingObscuredInsetsInteractively;
 
 - (void)didFinishScrolling;
+- (void)didInterruptScrolling;
 - (void)didZoomToScale:(CGFloat)scale;
 - (void)willStartZoomOrScroll;
 

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (180538 => 180539)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-02-24 01:43:36 UTC (rev 180538)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-02-24 02:07:33 UTC (rev 180539)
@@ -381,6 +381,11 @@
     [self _didEndScrollingOrZooming];
 }
 
+- (void)didInterruptScrolling
+{
+    _historicalKinematicData.clear();
+}
+
 - (void)willStartZoomOrScroll
 {
     [self _willStartScrollingOrZooming];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to