Changeset 183597 in webkit


Ignore:
Timestamp:
Apr 29, 2015, 5:46:40 PM (10 years ago)
Author:
Simon Fraser
Message:

Compute the non-fast-scrollable region in main-document coordinates
https://bugs.webkit.org/show_bug.cgi?id=144420

Reviewed by Tim Horton.

Source/WebCore:

Compute the non-fast-scrollable region in document coordinates, to make it easier
to reason about. Previously, it was document coordinates offset by top content inset.

  • page/DebugPageOverlays.cpp:

(WebCore::MouseWheelRegionOverlay::updateRegion): Traverse all frames to compute the wheel
event handler region, mapping each to root view coords, and then mapping back into document
coords at the end.
(WebCore::NonFastScrollableRegionOverlay::updateRegion): No offset needed here; the
overlay and region are both document coordinates.

  • page/FrameView.h: Make some mapping function overrides public, and expose widgetsInRenderTree().
  • page/Page.cpp:

(WebCore::Page::nonFastScrollableRects): Remove frame argument.

  • page/Page.h:
  • page/PageOverlay.cpp:

(WebCore::PageOverlay::bounds):
(WebCore::PageOverlay::viewToOverlayOffset): Convenience function to map between
view and overlay coordinates.

  • page/PageOverlay.h:
  • page/scrolling/AsyncScrollingCoordinator.cpp: New computeNonFastScrollableRegion() signature.

(WebCore::AsyncScrollingCoordinator::updateNonFastScrollableRegion):
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
(WebCore::AsyncScrollingCoordinator::scrollingStateTreeAsText):

  • page/scrolling/ScrollingCoordinator.cpp:

(WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame): This function
recurses on frames, computing an absolute (document-relative) region per frame. This
removes the confusing offsetting through top content inset.
Change how we get to plugins that want wheel events; we can't get from PluginViewBase
to renderers, so use FrameView's list of Widgets, and their RenderWidgets. This fixes
regions for transformed plugin-ins.
For subframes, we get a region in the subframe's document coords. Map to that sub-frame,
then to our frame, then to our document.
(WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegion): Wrapper that hides
the recursive function.
(WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Deleted.

  • page/scrolling/ScrollingCoordinator.h:
  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::shouldHandleWheelEventSynchronously): Map the event point
from view coordinates to document coordinates for testing against the non-fast region.
We previously assert that the root note is a FrameScrolling node.

  • page/scrolling/ScrollingTreeFrameScrollingNode.cpp:

(WebCore::ScrollingTreeFrameScrollingNode::viewToContentsOffset): Similar to ScrollView::viewToContents()
for the scrolling tree.

  • page/scrolling/ScrollingTreeFrameScrollingNode.h:
  • testing/Internals.cpp:

(WebCore::Internals::nonFastScrollableRects): No need for frame arg.

LayoutTests:

We now report the non-fast region in document coordinates, so these two results change.

  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-expected.txt:
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-header-expected.txt:
Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r183589 r183597  
     12015-04-29  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Compute the non-fast-scrollable region in main-document coordinates
     4        https://bugs.webkit.org/show_bug.cgi?id=144420
     5
     6        Reviewed by Tim Horton.
     7
     8        We now report the non-fast region in document coordinates, so these two results change.
     9
     10        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-expected.txt:
     11        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-header-expected.txt:
     12
    1132015-04-29  Joseph Pecoraro  <pecoraro@apple.com>
    214
  • trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-expected.txt

    r183586 r183597  
    11Wheel event rect:
    22
    3 28, 110 - 128, 210
     328, 50 - 128, 150
  • trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/top-content-inset-header-expected.txt

    r183586 r183597  
    11Wheel event rect:
    22
    3 28, 110 - 128, 210
     328, 50 - 128, 150
  • trunk/Source/WebCore/ChangeLog

    r183595 r183597  
     12015-04-29  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Compute the non-fast-scrollable region in main-document coordinates
     4        https://bugs.webkit.org/show_bug.cgi?id=144420
     5
     6        Reviewed by Tim Horton.
     7
     8        Compute the non-fast-scrollable region in document coordinates, to make it easier
     9        to reason about. Previously, it was document coordinates offset by top content inset.
     10
     11        * page/DebugPageOverlays.cpp:
     12        (WebCore::MouseWheelRegionOverlay::updateRegion): Traverse all frames to compute the wheel
     13        event handler region, mapping each to root view coords, and then mapping back into document
     14        coords at the end.
     15        (WebCore::NonFastScrollableRegionOverlay::updateRegion): No offset needed here; the
     16        overlay and region are both document coordinates.
     17        * page/FrameView.h: Make some mapping function overrides public, and expose widgetsInRenderTree().
     18        * page/Page.cpp:
     19        (WebCore::Page::nonFastScrollableRects): Remove frame argument.
     20        * page/Page.h:
     21        * page/PageOverlay.cpp:
     22        (WebCore::PageOverlay::bounds):
     23        (WebCore::PageOverlay::viewToOverlayOffset): Convenience function to map between
     24        view and overlay coordinates.
     25        * page/PageOverlay.h:
     26        * page/scrolling/AsyncScrollingCoordinator.cpp: New computeNonFastScrollableRegion() signature.
     27        (WebCore::AsyncScrollingCoordinator::updateNonFastScrollableRegion):
     28        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
     29        (WebCore::AsyncScrollingCoordinator::scrollingStateTreeAsText):
     30        * page/scrolling/ScrollingCoordinator.cpp:
     31        (WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame): This function
     32        recurses on frames, computing an absolute (document-relative) region per frame. This
     33        removes the confusing offsetting through top content inset.
     34        Change how we get to plugins that want wheel events; we can't get from PluginViewBase
     35        to renderers, so use FrameView's list of Widgets, and their RenderWidgets. This fixes
     36        regions for transformed plugin-ins.
     37        For subframes, we get a region in the subframe's document coords. Map to that sub-frame,
     38        then to our frame, then to our document.
     39        (WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegion): Wrapper that hides
     40        the recursive function.
     41        (WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Deleted.
     42        * page/scrolling/ScrollingCoordinator.h:
     43        * page/scrolling/ScrollingTree.cpp:
     44        (WebCore::ScrollingTree::shouldHandleWheelEventSynchronously): Map the event point
     45        from view coordinates to document coordinates for testing against the non-fast region.
     46        We previously assert that the root note is a FrameScrolling node.
     47        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
     48        (WebCore::ScrollingTreeFrameScrollingNode::viewToContentsOffset): Similar to ScrollView::viewToContents()
     49        for the scrolling tree.
     50        * page/scrolling/ScrollingTreeFrameScrollingNode.h:
     51        * testing/Internals.cpp:
     52        (WebCore::Internals::nonFastScrollableRects): No need for frame arg.
     53
    1542015-04-29  Brent Fulgham  <bfulgham@apple.com>
    255
  • trunk/Source/WebCore/page/DebugPageOverlays.cpp

    r182242 r183597  
    9191bool MouseWheelRegionOverlay::updateRegion()
    9292{
    93     std::unique_ptr<Region> region = std::make_unique<Region>(m_frame.document()->absoluteRegionForEventTargets(m_frame.document()->wheelEventTargets()).first);
     93    std::unique_ptr<Region> region = std::make_unique<Region>();
     94   
     95    for (const Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext()) {
     96        if (!frame->view() || !frame->document())
     97            continue;
     98
     99        Document::RegionFixedPair frameRegion = frame->document()->absoluteRegionForEventTargets(frame->document()->wheelEventTargets());
     100   
     101        IntPoint frameOffset = frame->view()->contentsToRootView(IntPoint());
     102        frameRegion.first.translate(toIntSize(frameOffset));
     103       
     104        region->unite(frameRegion.first);
     105    }
     106   
     107    region->translate(m_overlay->viewToOverlayOffset());
    94108
    95109    bool regionChanged = !m_region || !(*m_region == *region);
     
    120134    if (Page* page = m_frame.page()) {
    121135        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
    122             *region = scrollingCoordinator->computeNonFastScrollableRegion(m_frame, IntPoint());
    123     }
    124 
    125     // computeNonFastScrollableRegion() applies topContentInset.
    126     region->translate(IntSize(0, -m_frame.view()->topContentInset()));
     136            *region = scrollingCoordinator->absoluteNonFastScrollableRegion();
     137    }
    127138
    128139    bool regionChanged = !m_region || !(*m_region == *region);
  • trunk/Source/WebCore/page/FrameView.h

    r183530 r183597  
    403403    WEBCORE_EXPORT IntPoint convertFromContainingViewToRenderer(const RenderElement*, const IntPoint&) const;
    404404
     405    // Override ScrollView methods to do point conversion via renderers, in order to take transforms into account.
     406    virtual IntRect convertToContainingView(const IntRect&) const override;
     407    virtual IntRect convertFromContainingView(const IntRect&) const override;
     408    virtual IntPoint convertToContainingView(const IntPoint&) const override;
     409    virtual IntPoint convertFromContainingView(const IntPoint&) const override;
     410
    405411    bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
    406412
     
    508514    void didAddWidgetToRenderTree(Widget&);
    509515    void willRemoveWidgetFromRenderTree(Widget&);
     516
     517    const HashSet<Widget*>& widgetsInRenderTree() const { return m_widgetsInRenderTree; }
    510518
    511519    void addTrackedRepaintRect(const FloatRect&);
     
    588596
    589597    virtual void delegatesScrollingDidChange() override;
    590 
    591     // Override ScrollView methods to do point conversion via renderers, in order to
    592     // take transforms into account.
    593     virtual IntRect convertToContainingView(const IntRect&) const override;
    594     virtual IntRect convertFromContainingView(const IntRect&) const override;
    595     virtual IntPoint convertToContainingView(const IntPoint&) const override;
    596     virtual IntPoint convertFromContainingView(const IntPoint&) const override;
    597598
    598599    // ScrollableArea interface
  • trunk/Source/WebCore/page/Page.cpp

    r183595 r183597  
    370370}
    371371
    372 Ref<ClientRectList> Page::nonFastScrollableRects(const Frame& frame)
     372Ref<ClientRectList> Page::nonFastScrollableRects()
    373373{
    374374    if (Document* document = m_mainFrame->document())
     
    377377    Vector<IntRect> rects;
    378378    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    379         rects = scrollingCoordinator->computeNonFastScrollableRegion(frame, IntPoint()).rects();
     379        rects = scrollingCoordinator->absoluteNonFastScrollableRegion().rects();
    380380
    381381    Vector<FloatQuad> quads(rects.size());
    382382    for (size_t i = 0; i < rects.size(); ++i)
    383383        quads[i] = FloatRect(rects[i]);
     384
    384385    return ClientRectList::create(quads);
    385386}
  • trunk/Source/WebCore/page/Page.h

    r183595 r183597  
    197197    WEBCORE_EXPORT String scrollingStateTreeAsText();
    198198    WEBCORE_EXPORT String synchronousScrollingReasonsAsText();
    199     WEBCORE_EXPORT Ref<ClientRectList> nonFastScrollableRects(const Frame&);
     199    WEBCORE_EXPORT Ref<ClientRectList> nonFastScrollableRects();
    200200
    201201    Settings& settings() const { return *m_settings; }
  • trunk/Source/WebCore/page/PageOverlay.cpp

    r182364 r183597  
    102102    case OverlayType::Document:
    103103        return IntRect(IntPoint(), frameView->contentsSize());
    104     };
     104    }
    105105
    106106    ASSERT_NOT_REACHED();
     
    125125    if (auto pageOverlayController = controller())
    126126        pageOverlayController->didChangeOverlayFrame(*this);
     127}
     128
     129IntSize PageOverlay::viewToOverlayOffset() const
     130{
     131    switch (m_overlayType) {
     132    case OverlayType::View:
     133        return IntSize();
     134
     135    case OverlayType::Document: {
     136        FrameView* frameView = m_page->mainFrame().view();
     137        return frameView ? toIntSize(frameView->viewToContents(IntPoint())) : IntSize();
     138    }
     139    }
     140    return IntSize();
    127141}
    128142
  • trunk/Source/WebCore/page/PageOverlay.h

    r180301 r183597  
    106106    WEBCORE_EXPORT void setFrame(IntRect);
    107107
     108    WEBCORE_EXPORT IntSize viewToOverlayOffset() const;
     109
    108110    RGBA32 backgroundColor() const { return m_backgroundColor; }
    109111    void setBackgroundColor(RGBA32);
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r183595 r183597  
    9696        return;
    9797
    98     m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint()));
     98    m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
    9999    m_nonFastScrollableRegionDirty = false;
    100100}
     
    114114    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    115115    // just the root node. But right now, this concept only applies to the root.
    116     m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint()));
     116    m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
    117117    m_nonFastScrollableRegionDirty = false;
    118118
     
    545545    if (m_scrollingStateTree->rootStateNode()) {
    546546        if (m_nonFastScrollableRegionDirty)
    547             m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint()));
     547            m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
    548548        return m_scrollingStateTree->rootStateNode()->scrollingStateTreeAsText();
    549549    }
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r182346 r183597  
    9696}
    9797
    98 Region ScrollingCoordinator::computeNonFastScrollableRegion(const Frame& frame, const IntPoint& frameLocation) const
     98Region ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame(const Frame& frame) const
    9999{
    100100    RenderView* renderView = frame.contentRenderer();
     
    129129    // to not ask for regions at bad times.
    130130
    131     IntPoint offset = frameLocation;
    132     offset.moveBy(frameView->frameRect().location());
    133     offset.move(0, frameView->topContentInset());
    134 
    135131    if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) {
    136132        for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
     
    139135            if (scrollableArea->usesAsyncScrolling())
    140136                continue;
     137
    141138            IntRect box = scrollableArea->scrollableAreaBoundingBox();
    142             box.moveBy(offset);
    143139            nonFastScrollableRegion.unite(box);
    144140        }
    145141    }
    146142
    147     for (const auto& child : frameView->children()) {
    148         if (!is<PluginViewBase>(*child))
     143    for (auto& widget : frameView->widgetsInRenderTree()) {
     144        RenderWidget* renderWidget = RenderWidget::find(widget);
     145        if (!renderWidget || !is<PluginViewBase>(*widget))
    149146            continue;
    150         PluginViewBase& pluginViewBase = downcast<PluginViewBase>(*child);
    151         if (pluginViewBase.wantsWheelEvents())
    152             nonFastScrollableRegion.unite(pluginViewBase.frameRect());
     147   
     148        if (downcast<PluginViewBase>(*widget).wantsWheelEvents())
     149            nonFastScrollableRegion.unite(renderWidget->absoluteBoundingBoxRect());
    153150    }
    154 
    155     for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling())
    156         nonFastScrollableRegion.unite(computeNonFastScrollableRegion(*subframe, offset));
    157 
    158     // Include wheel event handler region for the main frame.
     151   
     152    // FIXME: if we've already accounted for this subframe as a scrollable area, we can avoid recursing into it here.
     153    for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) {
     154        FrameView* subframeView = subframe->view();
     155        if (!subframeView)
     156            continue;
     157
     158        Region subframeRegion = absoluteNonFastScrollableRegionForFrame(*subframe);
     159        // Map from the frame document to our document.
     160        IntPoint offset = subframeView->contentsToView(IntPoint());
     161        offset = subframeView->convertToContainingView(offset);
     162        offset = frameView->viewToContents(offset);
     163
     164        // FIXME: this translation ignores non-trival transforms on the frame.
     165        subframeRegion.translate(toIntSize(offset));
     166        nonFastScrollableRegion.unite(subframeRegion);
     167    }
     168
    159169    Document::RegionFixedPair wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
    160170    bool wheelHandlerInFixedContent = wheelHandlerRegion.second;
     
    166176        wheelHandlerRegion.first.unite(enclosingIntRect(frame.document()->absoluteEventHandlerBounds(inFixed)));
    167177    }
    168     wheelHandlerRegion.first.translate(toIntSize(offset));
     178   
    169179    nonFastScrollableRegion.unite(wheelHandlerRegion.first);
    170180
     181    // FIXME: If this is not the main frame, we could clip the region to the frame's bounds.
    171182    return nonFastScrollableRegion;
    172183#endif
     184}
     185
     186Region ScrollingCoordinator::absoluteNonFastScrollableRegion() const
     187{
     188    return absoluteNonFastScrollableRegionForFrame(m_page->mainFrame());
    173189}
    174190
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r182346 r183597  
    200200    String synchronousScrollingReasonsAsText() const;
    201201
    202     Region computeNonFastScrollableRegion(const Frame&, const IntPoint& frameLocation) const;
     202    Region absoluteNonFastScrollableRegion() const;
    203203
    204204protected:
     
    224224    virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const;
    225225    void updateSynchronousScrollingReasons(FrameView&);
     226
     227    Region absoluteNonFastScrollableRegionForFrame(const Frame&) const;
    226228   
    227229    bool m_forceSynchronousScrollLayerPositionUpdates { false };
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r182242 r183597  
    3131#include "PlatformWheelEvent.h"
    3232#include "ScrollingStateTree.h"
     33#include "ScrollingTreeFrameScrollingNode.h"
    3334#include "ScrollingTreeNode.h"
    3435#include "ScrollingTreeOverflowScrollingNode.h"
     
    7374        m_latchedNode = 0;
    7475   
    75     if (!m_nonFastScrollableRegion.isEmpty()) {
     76    if (!m_nonFastScrollableRegion.isEmpty() && m_rootNode) {
     77        ScrollingTreeFrameScrollingNode& frameScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(*m_rootNode);
    7678        // FIXME: This is not correct for non-default scroll origins.
    7779        FloatPoint position = wheelEvent.position();
    78         position.moveBy(m_mainFrameScrollPosition);
     80        position.move(frameScrollingNode.viewToContentsOffset(m_mainFrameScrollPosition));
    7981        if (m_nonFastScrollableRegion.contains(roundedIntPoint(position)))
    8082            return true;
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp

    r174340 r183597  
    9393}
    9494
     95FloatSize ScrollingTreeFrameScrollingNode::viewToContentsOffset(const FloatPoint& scrollOffset) const
     96{
     97    return toFloatSize(scrollOffset) - FloatSize(0, headerHeight() + topContentInset());
     98}
     99
    95100} // namespace WebCore
    96101
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h

    r176915 r183597  
    5656    bool shouldUpdateScrollLayerPositionSynchronously() const { return m_synchronousScrollingReasons; }
    5757
     58    FloatSize viewToContentsOffset(const FloatPoint& scrollOffset) const;
     59
    5860protected:
    5961    ScrollingTreeFrameScrollingNode(ScrollingTree&, ScrollingNodeID);
  • trunk/Source/WebCore/testing/Internals.cpp

    r183563 r183597  
    17981798        return nullptr;
    17991799
    1800     return page->nonFastScrollableRects(*document->frame());
     1800    return page->nonFastScrollableRects();
    18011801}
    18021802
Note: See TracChangeset for help on using the changeset viewer.