From e8b47ff03b97265a85d98bc38620479070fbc014 Mon Sep 17 00:00:00 2001 From: "andersca@apple.com" Date: Wed, 15 Feb 2012 22:06:39 +0000 Subject: [PATCH] Wheel events should be re-dispatched to the scrolling thread https://bugs.webkit.org/show_bug.cgi?id=78731 Reviewed by Sam Weinig. When threaded scrolling is enabled, all the state is assumed to be kept in the scrolling tree, on the scrolling thread. This means that even if we do end up processing an event on the main thread (because of wheel event handlers for example), we still have to dispatch the wheel event back to the scrolling thread. * page/FrameView.cpp: (WebCore::FrameView::wheelEvent): Move wheelEvent from ScrollView and ask the scrolling coordinator to handle the wheel event. * page/scrolling/ScrollingCoordinator.cpp: (WebCore::ScrollingCoordinator::handleWheelEvent): Dispatch the event to the scrolling thread, unless it will start a gesture. In that case we'll return false so that information will be passed back to the UI process. (ScrollingCoordinator): * platform/ScrollView.cpp: * platform/ScrollView.h: Move wheelEvent to FrameView. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107838 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 27 ++++++++++++++++++++++ Source/WebCore/page/FrameView.cpp | 24 +++++++++++++++++++ Source/WebCore/page/FrameView.h | 5 ++++ .../page/scrolling/ScrollingCoordinator.cpp | 12 ++++++++++ .../WebCore/page/scrolling/ScrollingCoordinator.h | 3 +++ Source/WebCore/platform/ScrollView.cpp | 14 ----------- Source/WebCore/platform/ScrollView.h | 5 ---- 7 files changed, 71 insertions(+), 19 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 25edf5a..b79a197 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,30 @@ +2012-02-15 Anders Carlsson + + Wheel events should be re-dispatched to the scrolling thread + https://bugs.webkit.org/show_bug.cgi?id=78731 + + + Reviewed by Sam Weinig. + + When threaded scrolling is enabled, all the state is assumed to be kept in the scrolling tree, + on the scrolling thread. This means that even if we do end up processing an event on the main thread + (because of wheel event handlers for example), we still have to dispatch the wheel event back to the + scrolling thread. + + * page/FrameView.cpp: + (WebCore::FrameView::wheelEvent): + Move wheelEvent from ScrollView and ask the scrolling coordinator to handle the wheel event. + + * page/scrolling/ScrollingCoordinator.cpp: + (WebCore::ScrollingCoordinator::handleWheelEvent): + Dispatch the event to the scrolling thread, unless it will start a gesture. In that case we'll return false + so that information will be passed back to the UI process. + + (ScrollingCoordinator): + * platform/ScrollView.cpp: + * platform/ScrollView.h: + Move wheelEvent to FrameView. + 2012-02-15 Mark Hahnenberg RootObject::finalize can cause a crash in object->invalidate() diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp index 7744565..079652f 100644 --- a/Source/WebCore/page/FrameView.cpp +++ b/Source/WebCore/page/FrameView.cpp @@ -3332,6 +3332,30 @@ void FrameView::removeChild(Widget* widget) ScrollView::removeChild(widget); } +bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent) +{ + // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled. + if (!canHaveScrollbars()) + return false; + +#if !PLATFORM(WX) + if (platformWidget()) + return false; +#endif + +#if ENABLE(THREADED_SCROLLING) + if (Page* page = m_frame->page()) { + if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) { + if (scrollingCoordinator->coordinatesScrollingForFrameView(this)) + return scrollingCoordinator->handleWheelEvent(this, wheelEvent); + } + } +#endif + + return ScrollableArea::handleWheelEvent(wheelEvent); +} + + bool FrameView::isVerticalDocument() const { RenderView* root = rootRenderer(this); diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h index 903e67e..cfd35a3 100644 --- a/Source/WebCore/page/FrameView.h +++ b/Source/WebCore/page/FrameView.h @@ -316,6 +316,11 @@ public: virtual void addChild(PassRefPtr) OVERRIDE; virtual void removeChild(Widget*) OVERRIDE; + // This function exists for ports that need to handle wheel events manually. + // On Mac WebKit1 the underlying NSScrollView just does the scrolling, but on most other platforms + // we need this function in order to do the scroll ourselves. + bool wheelEvent(const PlatformWheelEvent&); + protected: virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual void scrollContentsSlowPath(const IntRect& updateRect); diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp index 7c10bed..db7696a 100644 --- a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp +++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp @@ -180,6 +180,18 @@ bool ScrollingCoordinator::requestScrollPositionUpdate(FrameView* frameView, con return true; } +bool ScrollingCoordinator::handleWheelEvent(FrameView*, const PlatformWheelEvent& wheelEvent) +{ + ASSERT(isMainThread()); + ASSERT(m_page); + + if (m_scrollingTree->willWheelEventStartSwipeGesture(wheelEvent)) + return false; + + ScrollingThread::dispatch(bind(&ScrollingTree::handleWheelEvent, m_scrollingTree.get(), wheelEvent)); + return true; +} + void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition) { ASSERT(isMainThread()); diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/Source/WebCore/page/scrolling/ScrollingCoordinator.h index 4831052..fd30453 100644 --- a/Source/WebCore/page/scrolling/ScrollingCoordinator.h +++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.h @@ -93,6 +93,9 @@ public: // position will be updated asynchronously. If it returns false, the caller should update the scrolling position itself. bool requestScrollPositionUpdate(FrameView*, const IntPoint&); + // Handle the wheel event on the scrolling thread. Returns whether the event was handled or not. + bool handleWheelEvent(FrameView*, const PlatformWheelEvent&); + // Dispatched by the scrolling tree whenever the main frame scroll position changes. void updateMainFrameScrollPosition(const IntPoint&); diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp index 6a67140..42837a1 100644 --- a/Source/WebCore/platform/ScrollView.cpp +++ b/Source/WebCore/platform/ScrollView.cpp @@ -845,20 +845,6 @@ void ScrollView::setScrollbarOverlayStyle(ScrollbarOverlayStyle overlayStyle) platformSetScrollbarOverlayStyle(overlayStyle); } -bool ScrollView::wheelEvent(const PlatformWheelEvent& e) -{ - // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled. -#if PLATFORM(WX) - if (!canHaveScrollbars()) { -#else - if (!canHaveScrollbars() || platformWidget()) { -#endif - return false; - } - - return ScrollableArea::handleWheelEvent(e); -} - void ScrollView::setFrameRect(const IntRect& newRect) { IntRect oldRect = frameRect(); diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h index 8560e0d..6e58d0e 100644 --- a/Source/WebCore/platform/ScrollView.h +++ b/Source/WebCore/platform/ScrollView.h @@ -235,11 +235,6 @@ public: // For platforms that need to hit test scrollbars from within the engine's event handlers (like Win32). Scrollbar* scrollbarAtPoint(const IntPoint& windowPoint); - // This function exists for scrollviews that need to handle wheel events manually. - // On Mac the underlying NSScrollView just does the scrolling, but on other platforms - // (like Windows), we need this function in order to do the scroll ourselves. - bool wheelEvent(const PlatformWheelEvent&); - IntPoint convertChildToSelf(const Widget* child, const IntPoint& point) const { IntPoint newPoint = point; -- 2.7.4