Title: [184439] trunk/Source/WebKit2
Revision
184439
Author
[email protected]
Date
2015-05-16 16:00:06 -0700 (Sat, 16 May 2015)

Log Message

[iOS] Remote scrolling tree needs to coordinate scroll snap state during resize/rotations
https://bugs.webkit.org/show_bug.cgi?id=145059
<rdar://problem/20975978>

Reviewed by Simon Fraser.

The web view needs to update its scroll snap point offsets to take into account any
adjustments to the view size caused by content insets. We also need to update the
offstes after device rotation.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Retrieve the proper
computed content inset for the view and incorporate into any scroll snap point adjustments.
(-[WKWebView _updateVisibleContentRects]): If we have active scroll snap points, 
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
* UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping): Update to account
for content inset.
(WebKit::RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling): Also validate that the
active index is valid.
(WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling): Update to track
current active snap offset index.
(WebKit::RemoteScrollingCoordinatorProxy::hasActiveSnapPoint): Added.
(WebKit::RemoteScrollingCoordinatorProxy::nearestActiveSnapPoint): Added. It calculates the proper
scroll position incorporating any snap point and content insets.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (184438 => 184439)


--- trunk/Source/WebKit2/ChangeLog	2015-05-16 21:01:42 UTC (rev 184438)
+++ trunk/Source/WebKit2/ChangeLog	2015-05-16 23:00:06 UTC (rev 184439)
@@ -1,3 +1,31 @@
+2015-05-16  Brent Fulgham  <[email protected]>
+
+        [iOS] Remote scrolling tree needs to coordinate scroll snap state during resize/rotations
+        https://bugs.webkit.org/show_bug.cgi?id=145059
+        <rdar://problem/20975978>
+
+        Reviewed by Simon Fraser.
+
+        The web view needs to update its scroll snap point offsets to take into account any
+        adjustments to the view size caused by content insets. We also need to update the
+        offstes after device rotation.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Retrieve the proper
+        computed content inset for the view and incorporate into any scroll snap point adjustments.
+        (-[WKWebView _updateVisibleContentRects]): If we have active scroll snap points, 
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping): Update to account
+        for content inset.
+        (WebKit::RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling): Also validate that the
+        active index is valid.
+        (WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling): Update to track
+        current active snap offset index.
+        (WebKit::RemoteScrollingCoordinatorProxy::hasActiveSnapPoint): Added.
+        (WebKit::RemoteScrollingCoordinatorProxy::nearestActiveSnapPoint): Added. It calculates the proper
+        scroll position incorporating any snap point and content insets.
+
 2015-05-15  Yongjun Zhang  <[email protected]>
 
         Don't reset the preview recognizer in [WKContentViewInteraction cleanupInteraction]

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


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2015-05-16 21:01:42 UTC (rev 184438)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2015-05-16 23:00:06 UTC (rev 184439)
@@ -1413,7 +1413,11 @@
     if (WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy()) {
         // FIXME: Here, I'm finding the maximum horizontal/vertical scroll offsets. There's probably a better way to do this.
         CGSize maxScrollOffsets = CGSizeMake(scrollView.contentSize.width - scrollView.bounds.size.width, scrollView.contentSize.height - scrollView.bounds.size.height);
-        coordinator->adjustTargetContentOffsetForSnapping(maxScrollOffsets, velocity, targetContentOffset);
+        
+        CGRect fullViewRect = self.bounds;
+        CGRect unobscuredRect = UIEdgeInsetsInsetRect(fullViewRect, [self _computedContentInset]);
+        
+        coordinator->adjustTargetContentOffsetForSnapping(maxScrollOffsets, velocity, unobscuredRect.origin.y, targetContentOffset);
     }
 #endif
 }
@@ -1533,6 +1537,26 @@
     if (isStableState && [_scrollView respondsToSelector:@selector(_isInterruptingDeceleration)])
         isStableState = ![_scrollView performSelector:@selector(_isInterruptingDeceleration)];
 
+#if ENABLE(CSS_SCROLL_SNAP) && ENABLE(ASYNC_SCROLLING)
+    if (isStableState) {
+        WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy();
+        if (coordinator && coordinator->hasActiveSnapPoint()) {
+            CGRect fullViewRect = self.bounds;
+            CGRect unobscuredRect = UIEdgeInsetsInsetRect(fullViewRect, [self _computedContentInset]);
+            
+            CGPoint currentPoint = [_scrollView contentOffset];
+            CGPoint activePoint = coordinator->nearestActiveContentInsetAdjustedSnapPoint(unobscuredRect.origin.y, currentPoint);
+
+            if (!CGPointEqualToPoint(activePoint, currentPoint)) {
+                RetainPtr<WKScrollView> strongScrollView = _scrollView;
+                dispatch_async(dispatch_get_main_queue(), [strongScrollView, activePoint] {
+                    [strongScrollView setContentOffset:activePoint animated:NO];
+                });
+            }
+        }
+    }
+#endif
+    
     [_contentView didUpdateVisibleRect:visibleRectInContentCoordinates
         unobscuredRect:unobscuredRectInContentCoordinates
         unobscuredRectInScrollViewCoordinates:unobscuredRect

Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h (184438 => 184439)


--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h	2015-05-16 21:01:42 UTC (rev 184438)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h	2015-05-16 23:00:06 UTC (rev 184439)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -85,7 +85,9 @@
     void scrollingTreeNodeWillStartScroll();
     void scrollingTreeNodeDidEndScroll();
 #if ENABLE(CSS_SCROLL_SNAP)
-    void adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGPoint* targetContentOffset) const;
+    void adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGFloat topInset, CGPoint* targetContentOffset);
+    bool hasActiveSnapPoint() const;
+    CGPoint nearestActiveContentInsetAdjustedSnapPoint(CGFloat topInset, const CGPoint&) const;
     bool shouldSetScrollViewDecelerationRateFast() const;
 #endif
 #endif
@@ -94,12 +96,16 @@
     void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&);
 #if ENABLE(CSS_SCROLL_SNAP)
     bool shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis) const;
-    float closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float scrollDestination, float velocity) const;
+    float closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float scrollDestination, float velocity, unsigned& closestIndex) const;
 #endif
 
     WebPageProxy& m_webPageProxy;
     RefPtr<RemoteScrollingTree> m_scrollingTree;
     RequestedScrollInfo* m_requestedScrollInfo;
+#if ENABLE(CSS_SCROLL_SNAP)
+    unsigned m_currentHorizontalSnapPointIndex { 0 };
+    unsigned m_currentVerticalSnapPointIndex { 0 };
+#endif
     bool m_propagatesMainFrameScrolls;
 };
 

Modified: trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm (184438 => 184439)


--- trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm	2015-05-16 21:01:42 UTC (rev 184438)
+++ trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm	2015-05-16 23:00:06 UTC (rev 184439)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -113,16 +113,17 @@
 }
 
 #if ENABLE(CSS_SCROLL_SNAP)
-void RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping(CGSize maxScrollOffsets, CGPoint velocity, CGPoint* targetContentOffset) const
+void RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping(CGSize maxScrollOffsets, CGPoint velocity, CGFloat topInset, CGPoint* targetContentOffset)
 {
     // The bounds checking with maxScrollOffsets is to ensure that we won't interfere with rubber-banding when scrolling to the edge of the page.
     if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal) && targetContentOffset->x > 0 && targetContentOffset->x < maxScrollOffsets.width) {
-        float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, targetContentOffset->x, velocity.x);
+        float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, targetContentOffset->x, velocity.x, m_currentHorizontalSnapPointIndex);
         targetContentOffset->x = std::min<float>(maxScrollOffsets.width, potentialSnapPosition);
     }
-    // FIXME: We need to account for how the top navigation bar changes in size.
+
     if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical) && targetContentOffset->y > 0 && targetContentOffset->y < maxScrollOffsets.height) {
-        float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, targetContentOffset->y, velocity.y);
+        float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, targetContentOffset->y, velocity.y, m_currentVerticalSnapPointIndex);
+        potentialSnapPosition -= topInset;
         targetContentOffset->y = std::min<float>(maxScrollOffsets.height, potentialSnapPosition);
     }
 }
@@ -138,23 +139,71 @@
     if (root && root->isFrameScrollingNode()) {
         ScrollingTreeFrameScrollingNode* rootFrame = static_cast<ScrollingTreeFrameScrollingNode*>(root);
         const Vector<float>& snapOffsets = axis == ScrollEventAxis::Horizontal ? rootFrame->horizontalSnapOffsets() : rootFrame->verticalSnapOffsets();
-        return snapOffsets.size() > 0;
+        unsigned currentIndex = axis == ScrollEventAxis::Horizontal ? m_currentHorizontalSnapPointIndex : m_currentVerticalSnapPointIndex;
+        return (snapOffsets.size() > 0) && (currentIndex < snapOffsets.size());
     }
     return false;
 }
 
-float RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling(ScrollEventAxis axis, float scrollDestination, float velocity) const
+float RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling(ScrollEventAxis axis, float scrollDestination, float velocity, unsigned& currentIndex) const
 {
     ScrollingTreeNode* root = m_scrollingTree->rootNode();
     ASSERT(root && root->isFrameScrollingNode());
     ScrollingTreeFrameScrollingNode* rootFrame = static_cast<ScrollingTreeFrameScrollingNode*>(root);
     const Vector<float>& snapOffsets = axis == ScrollEventAxis::Horizontal ? rootFrame->horizontalSnapOffsets() : rootFrame->verticalSnapOffsets();
 
-    unsigned ignore = 0;
     float scaledScrollDestination = scrollDestination / m_webPageProxy.displayedContentScale();
-    float rawClosestSnapOffset = closestSnapOffset<float, float>(snapOffsets, scaledScrollDestination, velocity, ignore);
+    float rawClosestSnapOffset = closestSnapOffset<float, float>(snapOffsets, scaledScrollDestination, velocity, currentIndex);
     return rawClosestSnapOffset * m_webPageProxy.displayedContentScale();
 }
+
+bool RemoteScrollingCoordinatorProxy::hasActiveSnapPoint() const
+{
+    ScrollingTreeNode* root = m_scrollingTree->rootNode();
+    if (!root)
+        return false;
+
+    if (!is<ScrollingTreeFrameScrollingNode>(root))
+        return false;
+
+    ScrollingTreeFrameScrollingNode& rootFrame = downcast<ScrollingTreeFrameScrollingNode>(*root);
+    const Vector<float>& horizontal = rootFrame.horizontalSnapOffsets();
+    const Vector<float>& vertical = rootFrame.verticalSnapOffsets();
+
+    if (horizontal.isEmpty() && vertical.isEmpty())
+        return false;
+
+    if ((!horizontal.isEmpty() && m_currentHorizontalSnapPointIndex >= horizontal.size())
+        || (!vertical.isEmpty() && m_currentVerticalSnapPointIndex >= vertical.size())) {
+        return false;
+    }
+    
+    return true;
+}
+    
+CGPoint RemoteScrollingCoordinatorProxy::nearestActiveContentInsetAdjustedSnapPoint(CGFloat topInset, const CGPoint& currentPoint) const
+{
+    CGPoint activePoint = currentPoint;
+
+    ScrollingTreeNode* root = m_scrollingTree->rootNode();
+    ASSERT(root && is<ScrollingTreeFrameScrollingNode>(root));
+    ScrollingTreeFrameScrollingNode& rootFrame = downcast<ScrollingTreeFrameScrollingNode>(*root);
+    const Vector<float>& horizontal = rootFrame.horizontalSnapOffsets();
+    const Vector<float>& vertical = rootFrame.verticalSnapOffsets();
+
+    // The bounds checking with maxScrollOffsets is to ensure that we won't interfere with rubber-banding when scrolling to the edge of the page.
+    if (!horizontal.isEmpty() && m_currentHorizontalSnapPointIndex < horizontal.size())
+        activePoint.x = horizontal[m_currentHorizontalSnapPointIndex] * m_webPageProxy.displayedContentScale();
+
+    if (!vertical.isEmpty() && m_currentVerticalSnapPointIndex < vertical.size()) {
+        float potentialSnapPosition = vertical[m_currentVerticalSnapPointIndex] * m_webPageProxy.displayedContentScale();
+        potentialSnapPosition -= topInset;
+        activePoint.y = potentialSnapPosition;
+    }
+
+    return activePoint;
+}
+
 #endif
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to