Changeset 169411 in webkit


Ignore:
Timestamp:
May 27, 2014 9:44:56 PM (10 years ago)
Author:
Simon Fraser
Message:

[iOS WK2] Fix behavior of position:sticky inside accelerated overflow-scroll
https://bugs.webkit.org/show_bug.cgi?id=133334
<rdar://problem/16462535>

Reviewed by Tim Horton.

When the scroll position changes in an accelerated overflow-scroll element, we have
to update child nodes in the scrolling tree for position:sticky. That requires a
more generic ability to update the scrolling tree after some arbitrary zoom or
scroll. To do this, we need to know the current fixed position rect, rather than
having it passed in.

So make the fixed position rect available from ScrollingTree, and make it possible
to get the current scrollPosition() from any ScrollingTreeScrollingNode.

Also, implement updateLayersAfterDelegatedScroll() in ScrollingTreeOverflowScrollingNodeIOS,
and have it update descendant layers.

Finally, fix ScrollingTreeOverflowScrollingNode to use the correct rectangle for its
constraints math, using the scroll position of the parent node if appropriate.

Source/WebCore:

  • page/scrolling/ScrollingTree.h:
  • page/scrolling/ScrollingTreeScrollingNode.h:
  • page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:

(WebCore::ScrollingTreeFrameScrollingNodeIOS::updateChildNodesAfterScroll):

  • page/scrolling/ios/ScrollingTreeIOS.cpp:

(WebCore::ScrollingTreeIOS::fixedPositionRect):

  • page/scrolling/ios/ScrollingTreeIOS.h:
  • page/scrolling/mac/ScrollingTreeStickyNode.mm:

(WebCore::ScrollingTreeStickyNode::updateLayersAfterAncestorChange):

Source/WebKit2:

  • UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
  • UIProcess/Scrolling/RemoteScrollingTree.cpp:

(WebKit::RemoteScrollingTree::fixedPositionRect):

  • UIProcess/Scrolling/RemoteScrollingTree.h:
  • UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
  • UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:

(WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterDelegatedScroll):
(WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateChildNodesAfterScroll):

  • UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:

(WebKit::RemoteScrollingCoordinatorProxy::customFixedPositionRect):

Location:
trunk/Source
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r169410 r169411  
     12014-05-27  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] Fix behavior of position:sticky inside accelerated overflow-scroll
     4        https://bugs.webkit.org/show_bug.cgi?id=133334
     5        <rdar://problem/16462535>
     6
     7        Reviewed by Tim Horton.
     8
     9        When the scroll position changes in an accelerated overflow-scroll element, we have
     10        to update child nodes in the scrolling tree for position:sticky. That requires a
     11        more generic ability to update the scrolling tree after some arbitrary zoom or
     12        scroll. To do this, we need to know the current fixed position rect, rather than
     13        having it passed in.
     14       
     15        So make the fixed position rect available from ScrollingTree, and make it possible
     16        to get the current scrollPosition() from any ScrollingTreeScrollingNode.
     17       
     18        Also, implement updateLayersAfterDelegatedScroll() in ScrollingTreeOverflowScrollingNodeIOS,
     19        and have it update descendant layers.
     20       
     21        Finally, fix ScrollingTreeOverflowScrollingNode to use the correct rectangle for its
     22        constraints math, using the scroll position of the parent node if appropriate.
     23
     24        * page/scrolling/ScrollingTree.h:
     25        * page/scrolling/ScrollingTreeScrollingNode.h:
     26        * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
     27        (WebCore::ScrollingTreeFrameScrollingNodeIOS::updateChildNodesAfterScroll):
     28        * page/scrolling/ios/ScrollingTreeIOS.cpp:
     29        (WebCore::ScrollingTreeIOS::fixedPositionRect):
     30        * page/scrolling/ios/ScrollingTreeIOS.h:
     31        * page/scrolling/mac/ScrollingTreeStickyNode.mm:
     32        (WebCore::ScrollingTreeStickyNode::updateLayersAfterAncestorChange):
     33
    1342014-05-27  Simon Fraser  <simon.fraser@apple.com>
    235
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r169410 r169411  
    8888
    8989    FloatPoint mainFrameScrollPosition();
     90   
     91#if PLATFORM(IOS)
     92    virtual FloatRect fixedPositionRect() = 0;
     93#endif
    9094
    9195    bool isPointInNonFastScrollableRegion(IntPoint);
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h

    r169410 r169411  
    5757    virtual void updateLayersAfterDelegatedScroll(const FloatPoint&) { }
    5858
     59    virtual FloatPoint scrollPosition() const = 0;
     60
    5961protected:
    6062    ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     
    6466
    6567    virtual void setScrollLayerPosition(const FloatPoint&) = 0;
    66 
    67     virtual FloatPoint scrollPosition() const = 0;
    6868
    6969    FloatPoint lastCommittedScrollPosition() const { return m_lastCommittedScrollPosition; }
  • trunk/Source/WebCore/page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm

    r169410 r169411  
    135135        return;
    136136
    137     size_t size = m_children->size();
    138     for (size_t i = 0; i < size; ++i)
    139         m_children->at(i)->updateLayersAfterAncestorChange(*this, fixedPositionRect, FloatSize());
     137    for (auto& child : *m_children)
     138        child->updateLayersAfterAncestorChange(*this, fixedPositionRect, FloatSize());
    140139}
    141140
     
    172171        return;
    173172
    174     viewportRect.setLocation(scrollOffset);
    175 
    176     FloatRect viewportConstrainedObjectsRect = FrameView::rectForViewportConstrainedObjects(enclosingLayoutRect(viewportRect), roundedLayoutSize(totalContentsSize()), frameScaleFactor(), false, behaviorForFixed);
    177 
    178     size_t size = m_children->size();
    179     for (size_t i = 0; i < size; ++i)
    180         m_children->at(i)->updateLayersAfterAncestorChange(*this, fixedPositionRect, FloatSize());
     173    FloatRect fixedPositionRect = scrollingTree().fixedPositionRect();
     174   
     175    for (auto& child : *m_children)
     176        child->updateLayersAfterAncestorChange(*this, fixedPositionRect, FloatSize());
    181177}
    182178
  • trunk/Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.cpp

    r163231 r169411  
    9898}
    9999
     100FloatRect ScrollingTreeIOS::fixedPositionRect()
     101{
     102    // When ScrollingTreeIOS starts being used for WK1 on iOS, this needs to get the customFixedPositionRect from
     103    // the ScrollingCoordinator.
     104    ASSERT_NOT_REACHED();
     105    return FloatRect();
     106}
     107
    100108} // namespace WebCore
    101109
  • trunk/Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.h

    r163231 r169411  
    5959    virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
    6060
     61    virtual FloatRect fixedPositionRect() override;
     62
    6163    RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
    6264};
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFixedNode.mm

    r169410 r169411  
    8080    FloatSize newDelta = layerPosition - m_constraints.layerPositionAtLastLayout() + cumulativeDelta;
    8181
    82     size_t size = m_children->size();
    83     for (size_t i = 0; i < size; ++i)
    84         m_children->at(i)->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, newDelta);
     82    for (auto& child : *m_children)
     83        child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, newDelta);
    8584}
    8685
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeStickyNode.mm

    r169410 r169411  
    3131#include "ScrollingStateStickyNode.h"
    3232#include "ScrollingTree.h"
     33#include "ScrollingTreeOverflowScrollingNode.h"
    3334#include <QuartzCore/CALayer.h>
    3435
     
    6768void ScrollingTreeStickyNode::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
    6869{
    69     FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(fixedPositionRect);
     70    FloatRect constrainingRect = fixedPositionRect;
     71    if (parent()->isOverflowScrollingNode())
     72        constrainingRect = FloatRect(toScrollingTreeOverflowScrollingNode(parent())->scrollPosition(), m_constraints.constrainingRectAtLastLayout().size());
     73
     74    FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect);
    7075
    7176    // FIXME: Subtracting the cumulativeDelta is not totally sufficient to get the new position right for nested
     
    8489    FloatSize newDelta = layerPosition - m_constraints.layerPositionAtLastLayout() + cumulativeDelta;
    8590
    86     size_t size = m_children->size();
    87     for (size_t i = 0; i < size; ++i)
    88         m_children->at(i)->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, newDelta);
     91    for (auto& child : *m_children)
     92        child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, newDelta);
    8993}
    9094
  • trunk/Source/WebKit2/ChangeLog

    r169410 r169411  
     12014-05-27  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] Fix behavior of position:sticky inside accelerated overflow-scroll
     4        https://bugs.webkit.org/show_bug.cgi?id=133334
     5        <rdar://problem/16462535>
     6
     7        Reviewed by Tim Horton.
     8
     9        When the scroll position changes in an accelerated overflow-scroll element, we have
     10        to update child nodes in the scrolling tree for position:sticky. That requires a
     11        more generic ability to update the scrolling tree after some arbitrary zoom or
     12        scroll. To do this, we need to know the current fixed position rect, rather than
     13        having it passed in.
     14       
     15        So make the fixed position rect available from ScrollingTree, and make it possible
     16        to get the current scrollPosition() from any ScrollingTreeScrollingNode.
     17       
     18        Also, implement updateLayersAfterDelegatedScroll() in ScrollingTreeOverflowScrollingNodeIOS,
     19        and have it update descendant layers.
     20       
     21        Finally, fix ScrollingTreeOverflowScrollingNode to use the correct rectangle for its
     22        constraints math, using the scroll position of the parent node if appropriate.
     23
     24        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
     25        * UIProcess/Scrolling/RemoteScrollingTree.cpp:
     26        (WebKit::RemoteScrollingTree::fixedPositionRect):
     27        * UIProcess/Scrolling/RemoteScrollingTree.h:
     28        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
     29        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
     30        (WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterDelegatedScroll):
     31        (WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateChildNodesAfterScroll):
     32        * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
     33        (WebKit::RemoteScrollingCoordinatorProxy::customFixedPositionRect):
     34
    1352014-05-27  Simon Fraser  <simon.fraser@apple.com>
    236
  • trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h

    r169410 r169411  
    7373    bool propagatesMainFrameScrolls() const { return m_propagatesMainFrameScrolls; }
    7474
     75#if PLATFORM(IOS)
     76    WebCore::FloatRect customFixedPositionRect() const;
     77#endif
     78
    7579private:
    7680    void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&, bool& fixedOrStickyLayerChanged);
  • trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp

    r169063 r169411  
    7878#endif
    7979
     80#if PLATFORM(IOS)
     81WebCore::FloatRect RemoteScrollingTree::fixedPositionRect()
     82{
     83    return m_scrollingCoordinatorProxy.customFixedPositionRect();
     84}
     85#endif
     86
    8087void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
    8188{
  • trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h

    r167262 r169411  
    5757#endif
    5858
     59#if PLATFORM(IOS)
     60    virtual WebCore::FloatRect fixedPositionRect() override;
     61#endif
     62
    5963    virtual PassOwnPtr<WebCore::ScrollingTreeNode> createNode(WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
    6064   
  • trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h

    r169410 r169411  
    5656
    5757    virtual void updateLayersAfterViewportChange(const WebCore::FloatRect& fixedPositionRect, double scale) { }
     58    virtual void updateLayersAfterDelegatedScroll(const WebCore::FloatPoint& scrollPosition) override;
     59
    5860    virtual void handleWheelEvent(const WebCore::PlatformWheelEvent&) override { }
    5961
  • trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm

    r169313 r169411  
    175175}
    176176
    177 void ScrollingTreeOverflowScrollingNodeIOS::updateChildNodesAfterScroll(const FloatPoint&)
     177void ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterDelegatedScroll(const FloatPoint& scrollPosition)
     178{
     179    updateChildNodesAfterScroll(scrollPosition);
     180}
     181
     182void ScrollingTreeOverflowScrollingNodeIOS::updateChildNodesAfterScroll(const FloatPoint& scrollPosition)
    178183{
    179184    if (!m_children)
    180185        return;
    181186
    182     // FIXME: this needs to adjust child fixed/sticky nodes.
     187    FloatRect fixedPositionRect = scrollingTree().fixedPositionRect();
     188
     189    size_t size = m_children->size();
     190    for (size_t i = 0; i < size; ++i)
     191        m_children->at(i)->updateLayersAfterAncestorChange(*this, fixedPositionRect, FloatSize());
    183192}
    184193
  • trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm

    r169063 r169411  
    3232#include "LayerRepresentation.h"
    3333#include "RemoteLayerTreeHost.h"
     34#include "WebPageProxy.h"
    3435#include <WebCore/ScrollingStateFrameScrollingNode.h>
    3536#include <WebCore/ScrollingStateOverflowScrollingNode.h>
     
    9394}
    9495
     96FloatRect RemoteScrollingCoordinatorProxy::customFixedPositionRect() const
     97{
     98    return m_webPageProxy.computeCustomFixedPositionRect(m_webPageProxy.unobscuredContentRect(), m_webPageProxy.displayedContentScale());
     99}
     100
    95101} // namespace WebKit
    96102
Note: See TracChangeset for help on using the changeset viewer.