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

Changeset 107168 in webkit


Ignore:
Timestamp:
Feb 8, 2012, 7:02:25 PM (15 years ago)
Author:
andersca@apple.com
Message:

Don't use the wheel event handler count to track if a page has horizontal scrollbars
https://bugs.webkit.org/show_bug.cgi?id=78192

Reviewed by Andreas Kling.

Source/WebCore:

Stop calling Document::didAddWheelEventHandler and Document::didRemoveWheelEventHandler when
adding and removing scrollbars.

  • page/FrameView.cpp:
  • page/FrameView.h:

(FrameView):

  • rendering/RenderLayer.cpp:
  • rendering/RenderLayer.h:

Source/WebKit2:

Prior to this change, we were incrementing and decrementing the wheel event handler count
whenever a scrollable area gained or lost a horizontal scrollbar, so we could use the count
to determine if Safari can handle horizontal wheel events directly or whether they have to be sent
to the web process first.

What this meant was that whenever a page had horizontal scrollbars we'd have to send all scroll wheel events
to the main thread instead of the scrolling thread, regardless of whether there were any wheel event handlers.

After this change, we traverse the tree of scrollable areas after every layout and check if any of them
have a horizontal scrollbar. (We still also check if there are wheel event handlers).

If traversing the tree after every layout is deemed to slow we can go back to caching the number of horizontal scrollbars
in a page, but the number of subframes in a page is usually very small and the number of other scrollable areas is even smaller.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::WebPageProxy):
(WebKit::WebPageProxy::willHandleHorizontalScrollEvents):

  • UIProcess/WebPageProxy.h:

(WebKit::WebPageProxy::setCanShortCircuitHorizontalWheelEvents):
(WebPageProxy):

  • UIProcess/WebPageProxy.messages.in:
  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::numWheelEventHandlersChanged):

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::dispatchDidLayout):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::WebPage):
(WebKit::WebPage::numWheelEventHandlersChanged):
(WebKit):
(WebKit::hasEnabledHorizontalScrollbar):
(WebKit::pageContainsAnyHorizontalScrollbars):
(WebKit::WebPage::recomputeShortCircuitHorizontalWheelEventsState):

  • WebProcess/WebPage/WebPage.h:

(WebPage):

Location:
trunk/Source
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r107162 r107168  
     12012-02-08  Anders Carlsson  <andersca@apple.com>
     2
     3        Don't use the wheel event handler count to track if a page has horizontal scrollbars
     4        https://bugs.webkit.org/show_bug.cgi?id=78192
     5
     6        Reviewed by Andreas Kling.
     7
     8        Stop calling Document::didAddWheelEventHandler and Document::didRemoveWheelEventHandler when
     9        adding and removing scrollbars.
     10
     11        * page/FrameView.cpp:
     12        * page/FrameView.h:
     13        (FrameView):
     14        * rendering/RenderLayer.cpp:
     15        * rendering/RenderLayer.h:
     16
    1172012-02-08  Igor Oliveira  <igor.o@sisa.samsung.com>
    218
  • trunk/Source/WebCore/page/FrameView.cpp

    r107102 r107168  
    322322}
    323323
    324 void FrameView::didAddHorizontalScrollbar(Scrollbar* scrollbar)
    325 {
    326     if (m_frame && m_frame->document())
    327         m_frame->document()->didAddWheelEventHandler();
    328     ScrollView::didAddHorizontalScrollbar(scrollbar);
    329 }
    330 
    331 void FrameView::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
    332 {
    333     ScrollView::willRemoveHorizontalScrollbar(scrollbar);
    334     // FIXME: maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback?
    335     if (m_frame && m_frame->document())
    336         m_frame->document()->didRemoveWheelEventHandler();
    337 }
    338 
    339324void FrameView::recalculateScrollbarOverlayStyle()
    340325{
  • trunk/Source/WebCore/page/FrameView.h

    r107001 r107168  
    8787
    8888    virtual bool avoidScrollbarCreation() const;
    89     virtual void didAddHorizontalScrollbar(Scrollbar*);
    90     virtual void willRemoveHorizontalScrollbar(Scrollbar*);
    9189
    9290    virtual void setContentsSize(const IntSize&);
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r107072 r107168  
    20622062}
    20632063
    2064 void RenderLayer::didAddHorizontalScrollbar(Scrollbar* scrollbar)
    2065 {
    2066     m_renderer->document()->didAddWheelEventHandler();
    2067     ScrollableArea::didAddHorizontalScrollbar(scrollbar);
    2068 }
    2069 
    2070 void RenderLayer::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
    2071 {
    2072     ScrollableArea::willRemoveHorizontalScrollbar(scrollbar);
    2073     // FIXME: maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback?
    2074     m_renderer->document()->didRemoveWheelEventHandler();
    2075 }
    2076 
    20772064void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
    20782065{
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r107032 r107168  
    313313    bool allowsScrolling() const; // Returns true if at least one scrollbar is visible and enabled.
    314314    bool hasScrollbars() const { return m_hBar || m_vBar; }
    315     virtual void didAddHorizontalScrollbar(Scrollbar*);
    316     virtual void willRemoveHorizontalScrollbar(Scrollbar*);
    317315    void setHasHorizontalScrollbar(bool);
    318316    void setHasVerticalScrollbar(bool);
  • trunk/Source/WebKit2/ChangeLog

    r107101 r107168  
     12012-02-08  Anders Carlsson  <andersca@apple.com>
     2
     3        Don't use the wheel event handler count to track if a page has horizontal scrollbars
     4        https://bugs.webkit.org/show_bug.cgi?id=78192
     5
     6        Reviewed by Andreas Kling.
     7
     8        Prior to this change, we were incrementing and decrementing the wheel event handler count
     9        whenever a scrollable area gained or lost a horizontal scrollbar, so we could use the count
     10        to determine if Safari can handle horizontal wheel events directly or whether they have to be sent
     11        to the web process first.
     12
     13        What this meant was that whenever a page had horizontal scrollbars we'd have to send all scroll wheel events
     14        to the main thread instead of the scrolling thread, regardless of whether there were any wheel event handlers.
     15       
     16        After this change, we traverse the tree of scrollable areas after every layout and check if any of them
     17        have a horizontal scrollbar. (We still also check if there are wheel event handlers).
     18
     19        If traversing the tree after every layout is deemed to slow we can go back to caching the number of horizontal scrollbars
     20        in a page, but the number of subframes in a page is usually very small and the number of other scrollable areas is even smaller.
     21
     22        * UIProcess/WebPageProxy.cpp:
     23        (WebKit::WebPageProxy::WebPageProxy):
     24        (WebKit::WebPageProxy::willHandleHorizontalScrollEvents):
     25        * UIProcess/WebPageProxy.h:
     26        (WebKit::WebPageProxy::setCanShortCircuitHorizontalWheelEvents):
     27        (WebPageProxy):
     28        * UIProcess/WebPageProxy.messages.in:
     29        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     30        (WebKit::WebChromeClient::numWheelEventHandlersChanged):
     31        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     32        (WebKit::WebFrameLoaderClient::dispatchDidLayout):
     33        * WebProcess/WebPage/WebPage.cpp:
     34        (WebKit::WebPage::WebPage):
     35        (WebKit::WebPage::numWheelEventHandlersChanged):
     36        (WebKit):
     37        (WebKit::hasEnabledHorizontalScrollbar):
     38        (WebKit::pageContainsAnyHorizontalScrollbars):
     39        (WebKit::WebPage::recomputeShortCircuitHorizontalWheelEventsState):
     40        * WebProcess/WebPage/WebPage.h:
     41        (WebPage):
     42
    1432012-02-08  Sheriff Bot  <webkit.review.bot@gmail.com>
    244
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r107068 r107168  
    196196    , m_mainFrameHasHorizontalScrollbar(false)
    197197    , m_mainFrameHasVerticalScrollbar(false)
     198    , m_canShortCircuitHorizontalWheelEvents(true)
    198199    , m_mainFrameIsPinnedToLeftSide(false)
    199200    , m_mainFrameIsPinnedToRightSide(false)
     
    34573458bool WebPageProxy::willHandleHorizontalScrollEvents() const
    34583459{
    3459     return m_wheelEventHandlerCount > 0;
     3460    return !m_canShortCircuitHorizontalWheelEvents;
    34603461}
    34613462
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r107068 r107168  
    720720    void didChangePageCount(unsigned);
    721721    void didFailToInitializePlugin(const String& mimeType);
    722     void numWheelEventHandlersChanged(unsigned count) { m_wheelEventHandlerCount = count; }
     722    void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; }
    723723
    724724    void reattachToWebProcess();
     
    10101010    bool m_mainFrameHasHorizontalScrollbar;
    10111011    bool m_mainFrameHasVerticalScrollbar;
    1012     int m_wheelEventHandlerCount;
     1012
     1013    // Whether horizontal wheel events can be handled directly for swiping purposes.
     1014    bool m_canShortCircuitHorizontalWheelEvents;
    10131015
    10141016    bool m_mainFrameIsPinnedToLeftSide;
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in

    r107068 r107168  
    6767    DidChangePageCount(unsigned pageCount);
    6868    DidFailToInitializePlugin(WTF::String mimeType)
    69     NumWheelEventHandlersChanged(unsigned count)
     69    SetCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents)
    7070
    7171#if USE(TILED_BACKING_STORE)
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r103565 r107168  
    781781void WebChromeClient::numWheelEventHandlersChanged(unsigned count)
    782782{
    783     m_page->send(Messages::WebPageProxy::NumWheelEventHandlersChanged(count));
     783    m_page->numWheelEventHandlersChanged(count);
    784784}
    785785
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r106761 r107168  
    578578    webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
    579579
     580    webPage->recomputeShortCircuitHorizontalWheelEventsState();
     581
    580582    // NOTE: Unlike the other layout notifications, this does not notify the
    581583    // the UIProcess for every call.
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r106875 r107168  
    207207    , m_cachedMainFrameIsPinnedToLeftSide(false)
    208208    , m_cachedMainFrameIsPinnedToRightSide(false)
     209    , m_canShortCircuitHorizontalWheelEvents(false)
     210    , m_numWheelEventHandlers(0)
    209211    , m_cachedPageCount(0)
    210212    , m_isShowingContextMenu(false)
     
    30013003}
    30023004
     3005void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers)
     3006{
     3007    if (m_numWheelEventHandlers == numWheelEventHandlers)
     3008        return;
     3009
     3010    m_numWheelEventHandlers = numWheelEventHandlers;
     3011    recomputeShortCircuitHorizontalWheelEventsState();
     3012}
     3013
     3014static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea)
     3015{
     3016    if (Scrollbar* scrollbar = scrollableArea->horizontalScrollbar())
     3017        return scrollbar->enabled();
     3018
     3019    return false;
     3020}
     3021
     3022static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame)
     3023{
     3024    if (FrameView* frameView = mainFrame->view()) {
     3025        if (hasEnabledHorizontalScrollbar(frameView))
     3026            return true;
     3027    }
     3028
     3029    for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
     3030        FrameView* frameView = frame->view();
     3031        if (!frameView)
     3032            continue;
     3033
     3034        const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
     3035        if (!scrollableAreas)
     3036            continue;
     3037
     3038        for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
     3039            ScrollableArea* scrollableArea = *it;
     3040            ASSERT(scrollableArea->isOnActivePage());
     3041
     3042            if (hasEnabledHorizontalScrollbar(scrollableArea))
     3043                return true;
     3044        }
     3045    }
     3046
     3047    return false;
     3048}
     3049
     3050void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
     3051{
     3052    bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers;
     3053
     3054    if (canShortCircuitHorizontalWheelEvents) {
     3055        // Check if we have any horizontal scroll bars on the page.
     3056        if (pageContainsAnyHorizontalScrollbars(mainFrame()))
     3057            canShortCircuitHorizontalWheelEvents = false;
     3058    }
     3059
     3060    if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents)
     3061        return;
     3062
     3063    m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents;
     3064    send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents));
     3065}
     3066
    30033067Frame* WebPage::mainFrame() const
    30043068{
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r106800 r107168  
    501501#endif
    502502
     503    void numWheelEventHandlersChanged(unsigned);
     504    void recomputeShortCircuitHorizontalWheelEventsState();
     505
    503506private:
    504507    WebPage(uint64_t pageID, const WebPageCreationParameters&);
     
    757760    bool m_cachedMainFrameIsPinnedToLeftSide;
    758761    bool m_cachedMainFrameIsPinnedToRightSide;
     762    bool m_canShortCircuitHorizontalWheelEvents;
     763    unsigned m_numWheelEventHandlers;
    759764
    760765    unsigned m_cachedPageCount;
Note: See TracChangeset for help on using the changeset viewer.