Source/WebCore: Sideways 'wobble' when scrolling with trackpad on Mavericks
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 19:04:21 +0000 (19:04 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 19:04:21 +0000 (19:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127521
-and corresponding-
<rdar://problem/14137306>

Reviewed by Simon Fraser.

This patch takes http://trac.webkit.org/changeset/154535 which introduced
filtering wheel events for overflow areas to try to make them less sensitive to X
deltas when scrolling in a primarily Y direction, and it factors that code out
into its own class, now called WheelEventDeltaTracker. So now this new class can
use the same code to filter events for WebKit2’s EventDispatcher.

Files for WheelEventDeltaTracker.
* CMakeLists.txt:
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:

WK2 needs these new WheelEventDeltaTracker functions.
* WebCore.exp.in:

Move a bunch of code over to WheelEventDeltaTracker and use
m_recentWheelEventTracker to serve the same purpose.
* page/EventHandler.cpp:
(WebCore::EventHandler::EventHandler):
(WebCore::EventHandler::handleWheelEvent):
(WebCore::EventHandler::defaultWheelEventHandler):
* page/EventHandler.h:

Allow horizontal rubber banding now that we have some event filtering in place.
* page/FrameView.cpp:
(WebCore::FrameView::FrameView):

New files. Most of this code was from EventHandler.
* page/WheelEventDeltaTracker.cpp: Added.
(WebCore::WheelEventDeltaTracker::WheelEventDeltaTracker):
(WebCore::WheelEventDeltaTracker::~WheelEventDeltaTracker):
(WebCore::WheelEventDeltaTracker::beginTrackingDeltas):
(WebCore::WheelEventDeltaTracker::endTrackingDeltas):
(WebCore::WheelEventDeltaTracker::recordWheelEventDelta):
(WebCore::deltaIsPredominantlyVertical):
(WebCore::WheelEventDeltaTracker::dominantScrollGestureDirection):
* page/WheelEventDeltaTracker.h: Added.
(WebCore::WheelEventDeltaTracker::isTrackingDeltas):

New function to clone events while zero-ing out certain deltas.
* platform/PlatformWheelEvent.h:
(WebCore::PlatformWheelEvent::copyIgnoringHorizontalDelta):
(WebCore::PlatformWheelEvent::copyIgnoringVerticalDelta):

Source/WebKit2: Sideways 'wobble' when scrolling with trackpad on Mavericks
https://bugs.webkit.org/show_bug.cgi?id=127521
-and corresponding-
<rdar://problem/14137306>

Reviewed by Simon Fraser.

Start using WebCore::WheelEventDeltaTracker to filter events.
* WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::EventDispatcher):
(WebKit::EventDispatcher::wheelEvent):
* WebProcess/WebPage/EventDispatcher.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@163180 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/EventHandler.h
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/WheelEventDeltaTracker.cpp [new file with mode: 0644]
Source/WebCore/page/WheelEventDeltaTracker.h [new file with mode: 0644]
Source/WebCore/platform/PlatformWheelEvent.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
Source/WebKit2/WebProcess/WebPage/EventDispatcher.h

index f80005f279163ba08e2a5385ee143ea5402461e7..7cc64836a50513d8af2839e12dd7b84f5856b3d5 100644 (file)
@@ -1769,6 +1769,7 @@ set(WebCore_SOURCES
     page/UserContentController.cpp
     page/UserContentURLPattern.cpp
     page/VisitedLinkProvider.cpp
+    page/WheelEventDeltaTracker.cpp
     page/WindowFeatures.cpp
     page/WindowFocusAllowedIndicator.cpp
     page/WorkerNavigator.cpp
index b3c432f3409d458eacd3b9402c1aba5fdaf24ab0..fae2d5ef46dda8c1a285f413e9aedd58eb270c38 100644 (file)
@@ -1,3 +1,57 @@
+2014-01-31  Beth Dakin  <bdakin@apple.com>
+
+        Sideways 'wobble' when scrolling with trackpad on Mavericks
+        https://bugs.webkit.org/show_bug.cgi?id=127521
+        -and corresponding-
+        <rdar://problem/14137306>
+
+        Reviewed by Simon Fraser.
+
+        This patch takes http://trac.webkit.org/changeset/154535 which introduced 
+        filtering wheel events for overflow areas to try to make them less sensitive to X 
+        deltas when scrolling in a primarily Y direction, and it factors that code out 
+        into its own class, now called WheelEventDeltaTracker. So now this new class can 
+        use the same code to filter events for WebKit2’s EventDispatcher.
+
+        Files for WheelEventDeltaTracker.
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        WK2 needs these new WheelEventDeltaTracker functions.
+        * WebCore.exp.in:
+
+        Move a bunch of code over to WheelEventDeltaTracker and use
+        m_recentWheelEventTracker to serve the same purpose.
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::EventHandler):
+        (WebCore::EventHandler::handleWheelEvent):
+        (WebCore::EventHandler::defaultWheelEventHandler):
+        * page/EventHandler.h:
+
+        Allow horizontal rubber banding now that we have some event filtering in place.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::FrameView):
+
+        New files. Most of this code was from EventHandler.
+        * page/WheelEventDeltaTracker.cpp: Added.
+        (WebCore::WheelEventDeltaTracker::WheelEventDeltaTracker):
+        (WebCore::WheelEventDeltaTracker::~WheelEventDeltaTracker):
+        (WebCore::WheelEventDeltaTracker::beginTrackingDeltas):
+        (WebCore::WheelEventDeltaTracker::endTrackingDeltas):
+        (WebCore::WheelEventDeltaTracker::recordWheelEventDelta):
+        (WebCore::deltaIsPredominantlyVertical):
+        (WebCore::WheelEventDeltaTracker::dominantScrollGestureDirection):
+        * page/WheelEventDeltaTracker.h: Added.
+        (WebCore::WheelEventDeltaTracker::isTrackingDeltas):
+
+        New function to clone events while zero-ing out certain deltas.
+        * platform/PlatformWheelEvent.h:
+        (WebCore::PlatformWheelEvent::copyIgnoringHorizontalDelta):
+        (WebCore::PlatformWheelEvent::copyIgnoringVerticalDelta):
+
 2014-01-31  Simon Fraser  <simon.fraser@apple.com>
 
         Don't do logging from Range::collectSelectionRects() on iOS
index 7770c07f5debb1d0cbf3be8c6d422cef0caf1667..d89abc0cac485460dbb5500d9d21b8414b20eb7a 100644 (file)
@@ -4224,6 +4224,8 @@ webcore_sources += \
        Source/WebCore/page/VisitedLinkProvider.h \
        Source/WebCore/page/WebCoreKeyboardUIMode.h \
        Source/WebCore/page/WebKitPoint.h \
+       Source/WebCore/page/WheelEventDeltaTracker.cpp \
+       Source/WebCore/page/WheelEventDeltaTracker.h \
        Source/WebCore/page/WindowFeatures.cpp \
        Source/WebCore/page/WindowFeatures.h \
        Source/WebCore/page/WindowFocusAllowedIndicator.cpp \
index d408da4cb274ffc70944bd1238d41b8a433d99ea..ed89750b0c7d419c32b75baa6d548fe0b23527e0 100644 (file)
@@ -867,6 +867,10 @@ __ZN7WebCore22externalRepresentationEPNS_5FrameEj
 __ZN7WebCore22externalRepresentationEPNS_7ElementEj
 __ZN7WebCore22systemMarketingVersionEv
 __ZN7WebCore22userPreferredLanguagesEv
+__ZN7WebCore22WheelEventDeltaTracker17endTrackingDeltasEv
+__ZN7WebCore22WheelEventDeltaTracker19beginTrackingDeltasEv
+__ZN7WebCore22WheelEventDeltaTracker21recordWheelEventDeltaERKNS_18PlatformWheelEventE
+__ZN7WebCore22WheelEventDeltaTrackerC1Ev
 __ZN7WebCore23ApplicationCacheStorage14setMaximumSizeEx
 __ZN7WebCore23ApplicationCacheStorage16deleteAllEntriesEv
 __ZN7WebCore23ApplicationCacheStorage16storeCopyOfCacheERKN3WTF6StringEPNS_20ApplicationCacheHostE
@@ -1659,6 +1663,7 @@ __ZNK7WebCore21NetworkStorageSession13cookieStorageEv
 __ZNK7WebCore21RenderLayerCompositor11scrollLayerEv
 __ZNK7WebCore21RenderLayerCompositor15rootRenderLayerEv
 __ZNK7WebCore21UserContentURLPattern7matchesERKNS_3URLE
+__ZNK7WebCore22WheelEventDeltaTracker30dominantScrollGestureDirectionEv
 __ZNK7WebCore23ApplicationCacheStorage11maximumSizeEv
 __ZNK7WebCore23AuthenticationChallenge20authenticationClientEv
 __ZNK7WebCore23FrameLoaderStateMachine15firstLayoutDoneEv
index 48a507fe749fe9a422cf7409a3f0301d9855fd8b..45ded39b583d84e39485898eddc1d6f469341b86 100644 (file)
     <ClCompile Include="..\page\UserContentURLPattern.cpp" />
     <ClCompile Include="..\page\VisitedLinkProvider.cpp" />
     <ClCompile Include="..\fileapi\WebKitBlobBuilder.cpp" />
+    <ClCompile Include="..\page\WheelEventDeltaTracker.cpp" />
     <ClCompile Include="..\page\WindowFeatures.cpp" />
     <ClCompile Include="..\page\WindowFocusAllowedIndicator.cpp" />
     <ClCompile Include="..\page\WorkerNavigator.cpp" />
     <ClInclude Include="..\page\VisitedLinkProvider.h" />
     <ClInclude Include="..\fileapi\WebKitBlobBuilder.h" />
     <ClInclude Include="..\page\WebKitPoint.h" />
+    <ClInclude Include="..\page\WheelEventDeltaTracker.h" />
     <ClInclude Include="..\page\WindowFeatures.h" />
     <ClInclude Include="..\page\WindowFocusAllowedIndicator.h" />
     <ClInclude Include="..\page\WorkerNavigator.h" />
index 0daff3bbe040e27b4a8dc2eab096ecb5805b3969..6d804140cfcfec618c2bc3e6425f3784b490d8f1 100644 (file)
     <ClCompile Include="..\fileapi\WebKitBlobBuilder.cpp">
       <Filter>page</Filter>
     </ClCompile>
+    <ClCompile Include="..\page\WheelEventDeltaTracker.cpp">
+      <Filter>page</Filter>
+    </ClCompile>
     <ClCompile Include="..\page\WindowFeatures.cpp">
       <Filter>page</Filter>
     </ClCompile>
     <ClInclude Include="..\page\WebKitPoint.h">
       <Filter>page</Filter>
     </ClInclude>
+    <ClInclude Include="..\page\WheelEventDeltaTracker.h">
+      <Filter>page</Filter>
+    </ClInclude>
     <ClInclude Include="..\page\WindowFeatures.h">
       <Filter>page</Filter>
     </ClInclude>
index 4a8f66c02c21a2ed15c6d17ad7e8928bd3eb2763..a9a74ad0f9503a7cbff25609aef02a10ff3b47a9 100644 (file)
                93EB169509F880B00091F8FF /* WebCoreSystemInterface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93EB169409F880B00091F8FF /* WebCoreSystemInterface.mm */; };
                93EB169709F880C00091F8FF /* WebCoreSystemInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 93EB169609F880C00091F8FF /* WebCoreSystemInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93EB355F09E37FD600F43799 /* MouseEventWithHitTestResults.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93EB355E09E37FD600F43799 /* MouseEventWithHitTestResults.cpp */; };
+               93EC44A1188F4BB800661DF1 /* WheelEventDeltaTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93EC449F188F4BB800661DF1 /* WheelEventDeltaTracker.cpp */; };
+               93EC44A2188F4BB800661DF1 /* WheelEventDeltaTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 93EC44A0188F4BB800661DF1 /* WheelEventDeltaTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F198E508245E59001E9ABC /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D23C02DE4396018635CA /* HTMLDocument.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F198E608245E59001E9ABC /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D23F02DE4396018635CA /* HTMLElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F198F608245E59001E9ABC /* TextResourceDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D27902DE43D7018635CA /* TextResourceDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93EB169409F880B00091F8FF /* WebCoreSystemInterface.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreSystemInterface.mm; sourceTree = "<group>"; };
                93EB169609F880C00091F8FF /* WebCoreSystemInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreSystemInterface.h; sourceTree = "<group>"; };
                93EB355E09E37FD600F43799 /* MouseEventWithHitTestResults.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseEventWithHitTestResults.cpp; sourceTree = "<group>"; };
+               93EC449F188F4BB800661DF1 /* WheelEventDeltaTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WheelEventDeltaTracker.cpp; sourceTree = "<group>"; };
+               93EC44A0188F4BB800661DF1 /* WheelEventDeltaTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WheelEventDeltaTracker.h; sourceTree = "<group>"; };
                93EEC1E509C2877700C515D1 /* Attr.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Attr.idl; sourceTree = "<group>"; };
                93EEC1E609C2877700C515D1 /* CharacterData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CharacterData.idl; sourceTree = "<group>"; };
                93EEC1E809C2877700C515D1 /* DocumentType.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DocumentType.idl; sourceTree = "<group>"; };
                                BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */,
                                494BD7930F55C8EE00747828 /* WebKitPoint.h */,
                                494BD7940F55C8EE00747828 /* WebKitPoint.idl */,
+                               93EC449F188F4BB800661DF1 /* WheelEventDeltaTracker.cpp */,
+                               93EC44A0188F4BB800661DF1 /* WheelEventDeltaTracker.h */,
                                BC8243E60D0CFD7500460C8F /* WindowFeatures.cpp */,
                                BC8243E70D0CFD7500460C8F /* WindowFeatures.h */,
                                7E99AF520B13846468FB01A5 /* WindowFocusAllowedIndicator.cpp */,
                                77A17A7B12F2890B004E02F6 /* GraphicsTypes3D.h in Headers */,
                                A12705C31656BD6500C2E27C /* GridPosition.h in Headers */,
                                A12A1050166444FD008FA311 /* GridTrackSize.h in Headers */,
+                               93EC44A2188F4BB800661DF1 /* WheelEventDeltaTracker.h in Headers */,
                                C50B561712119D23008B46E0 /* GroupSettings.h in Headers */,
                                E1FF8F65180745D800132674 /* JSSubtleCrypto.h in Headers */,
                                078E094017D16E1C00420AA1 /* RTCIceCandidateDescriptor.h in Headers */,
                                A871DB2D0A150BD600B12A68 /* HTMLTablePartElement.cpp in Sources */,
                                A871DB300A150BD600B12A68 /* HTMLTableRowElement.cpp in Sources */,
                                93442CA00D2B336000338FF9 /* HTMLTableRowsCollection.cpp in Sources */,
+                               93EC44A1188F4BB800661DF1 /* WheelEventDeltaTracker.cpp in Sources */,
                                A871DB260A150BD600B12A68 /* HTMLTableSectionElement.cpp in Sources */,
                                E19AC3F01824DC7900349426 /* CryptoAlgorithmSHA256.cpp in Sources */,
                                511EF2CB17F0FD3500E4FA16 /* JSIDBVersionChangeEvent.cpp in Sources */,
index 554572874a474ae9105b5aebc84ce2f4fa4a88e4..ae3f25938063a21ba1c1e1b1742a14da879534f7 100644 (file)
@@ -355,7 +355,7 @@ EventHandler::EventHandler(Frame& frame)
 #endif
     , m_mousePositionIsUnknown(true)
     , m_mouseDownTimestamp(0)
-    , m_inTrackingScrollGesturePhase(false)
+    , m_recentWheelEventDeltaTracker(adoptPtr(new WheelEventDeltaTracker))
     , m_widgetIsLatched(false)
 #if PLATFORM(MAC)
     , m_mouseDownView(nil)
@@ -2467,41 +2467,6 @@ bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, c
 }
 #endif
 
-void EventHandler::recordWheelEventDelta(const PlatformWheelEvent& event)
-{
-    const size_t recentEventCount = 3;
-    
-    m_recentWheelEventDeltas.append(FloatSize(event.deltaX(), event.deltaY()));
-    if (m_recentWheelEventDeltas.size() > recentEventCount)
-        m_recentWheelEventDeltas.removeFirst();
-}
-
-static bool deltaIsPredominantlyVertical(const FloatSize& delta)
-{
-    return fabs(delta.height()) > fabs(delta.width());
-}
-
-EventHandler::DominantScrollGestureDirection EventHandler::dominantScrollGestureDirection() const
-{
-    bool allVertical = m_recentWheelEventDeltas.size();
-    bool allHorizontal = m_recentWheelEventDeltas.size();
-
-    Deque<FloatSize>::const_iterator end = m_recentWheelEventDeltas.end();
-    for (Deque<FloatSize>::const_iterator it = m_recentWheelEventDeltas.begin(); it != end; ++it) {
-        bool isVertical = deltaIsPredominantlyVertical(*it);
-        allVertical &= isVertical;
-        allHorizontal &= !isVertical;
-    }
-    
-    if (allVertical)
-        return DominantScrollDirectionVertical;
-
-    if (allHorizontal)
-        return DominantScrollDirectionHorizontal;
-    
-    return DominantScrollDirectionNone;
-}
-
 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
 {
     Document* document = m_frame.document();
@@ -2555,18 +2520,17 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
 #if PLATFORM(MAC)
     switch (event.phase()) {
     case PlatformWheelEventPhaseBegan:
-        m_recentWheelEventDeltas.clear();
-        m_inTrackingScrollGesturePhase = true;
+        m_recentWheelEventDeltaTracker->beginTrackingDeltas();
         break;
     case PlatformWheelEventPhaseEnded:
-        m_inTrackingScrollGesturePhase = false;
+        m_recentWheelEventDeltaTracker->endTrackingDeltas();
         break;
     default:
         break;
     }
 #endif
 
-    recordWheelEventDelta(event);
+    m_recentWheelEventDeltaTracker->recordWheelEventDelta(event);
 
     if (element) {
         // Figure out which view to send the event to.
@@ -2601,18 +2565,20 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
     
     Element* stopElement = m_previousWheelScrolledElement.get();
     ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
-    
-    DominantScrollGestureDirection dominantDirection = DominantScrollDirectionNone;
-    // Workaround for scrolling issues in iTunes (<rdar://problem/14758615>).
-    if (m_inTrackingScrollGesturePhase && applicationIsITunes())
-        dominantDirection = dominantScrollGestureDirection();
+    DominantScrollGestureDirection dominantDirection = DominantScrollGestureDirection::None;
+
+    // Workaround for scrolling issues <rdar://problem/14758615>.
+#if PLATFORM(MAC)
+    if (m_recentWheelEventDeltaTracker->isTrackingDeltas())
+        dominantDirection = m_recentWheelEventDeltaTracker->dominantScrollGestureDirection();
+#endif
     
     // Break up into two scrolls if we need to.  Diagonal movement on 
     // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
-    if (dominantDirection != DominantScrollDirectionVertical && scrollNode(wheelEvent->deltaX(), granularity, ScrollRight, ScrollLeft, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
+    if (dominantDirection != DominantScrollGestureDirection::Vertical && scrollNode(wheelEvent->deltaX(), granularity, ScrollRight, ScrollLeft, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
         wheelEvent->setDefaultHandled();
     
-    if (dominantDirection != DominantScrollDirectionHorizontal && scrollNode(wheelEvent->deltaY(), granularity, ScrollDown, ScrollUp, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
+    if (dominantDirection != DominantScrollGestureDirection::Horizontal && scrollNode(wheelEvent->deltaY(), granularity, ScrollDown, ScrollUp, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
         wheelEvent->setDefaultHandled();
     
     if (!m_latchedWheelEventElement)
index f5a4fca03eeb95dd5f92ea7973fd0337c47f00c0..6651849eb8c87d7a7ee85a8e558fbb30163d86c5 100644 (file)
@@ -37,7 +37,7 @@
 #include "TextEventInputType.h"
 #include "TextGranularity.h"
 #include "Timer.h"
-#include <wtf/Deque.h>
+#include "WheelEventDeltaTracker.h"
 #include <wtf/Forward.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
@@ -329,13 +329,6 @@ private:
     bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
     
     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
-    void recordWheelEventDelta(const PlatformWheelEvent&);
-    enum DominantScrollGestureDirection {
-        DominantScrollDirectionNone,
-        DominantScrollDirectionVertical,
-        DominantScrollDirectionHorizontal
-    };
-    DominantScrollGestureDirection dominantScrollGestureDirection() const;
     
     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
 
@@ -521,9 +514,8 @@ private:
     double m_mouseDownTimestamp;
     PlatformMouseEvent m_mouseDown;
 
-    Deque<FloatSize> m_recentWheelEventDeltas;
+    OwnPtr<WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
     RefPtr<Element> m_latchedWheelEventElement;
-    bool m_inTrackingScrollGesturePhase;
     bool m_widgetIsLatched;
 
     RefPtr<Element> m_previousWheelScrolledElement;
index 9c4f1e6fb744d075d2071db86d759853029e7797..2909bec24e7c5b233de303df2317929e429b2eac 100644 (file)
@@ -197,7 +197,7 @@ FrameView::FrameView(Frame& frame)
 
     if (frame.isMainFrame()) {
         ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
-        ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAutomatic);
+        ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
     }
 }
 
diff --git a/Source/WebCore/page/WheelEventDeltaTracker.cpp b/Source/WebCore/page/WheelEventDeltaTracker.cpp
new file mode 100644 (file)
index 0000000..d410646
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "WheelEventDeltaTracker.h"
+
+#include "PlatformWheelEvent.h"
+
+namespace WebCore {
+
+WheelEventDeltaTracker::WheelEventDeltaTracker()
+    : m_isTrackingDeltas(false)
+{
+}
+
+WheelEventDeltaTracker::~WheelEventDeltaTracker()
+{
+}
+
+void WheelEventDeltaTracker::beginTrackingDeltas()
+{
+    m_recentWheelEventDeltas.clear();
+    m_isTrackingDeltas = true;
+}
+
+void WheelEventDeltaTracker::endTrackingDeltas()
+{
+    m_isTrackingDeltas = false;
+}
+
+void WheelEventDeltaTracker::recordWheelEventDelta(const PlatformWheelEvent& event)
+{
+    m_recentWheelEventDeltas.append(FloatSize(event.deltaX(), event.deltaY()));
+    if (m_recentWheelEventDeltas.size() > recentEventCount)
+        m_recentWheelEventDeltas.removeFirst();
+}
+
+static bool deltaIsPredominantlyVertical(const FloatSize& delta)
+{
+    return fabs(delta.height()) > fabs(delta.width());
+}
+
+DominantScrollGestureDirection WheelEventDeltaTracker::dominantScrollGestureDirection() const
+{
+    bool allVertical = m_recentWheelEventDeltas.size();
+    bool allHorizontal = m_recentWheelEventDeltas.size();
+
+    auto end = m_recentWheelEventDeltas.end();
+    for (auto it = m_recentWheelEventDeltas.begin(); it != end; ++it) {
+        bool isVertical = deltaIsPredominantlyVertical(*it);
+        allVertical &= isVertical;
+        allHorizontal &= !isVertical;
+    }
+    
+    if (allVertical)
+        return DominantScrollGestureDirection::Vertical;
+
+    if (allHorizontal)
+        return DominantScrollGestureDirection::Horizontal;
+    
+    return DominantScrollGestureDirection::None;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/WheelEventDeltaTracker.h b/Source/WebCore/page/WheelEventDeltaTracker.h
new file mode 100644 (file)
index 0000000..1dc818b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef WheelEventDeltaTracker_h
+#define WheelEventDeltaTracker_h
+
+#include "FloatSize.h"
+#include <wtf/Deque.h>
+
+namespace WebCore {
+
+class PlatformWheelEvent;
+
+const size_t recentEventCount = 3;
+
+enum class DominantScrollGestureDirection {
+    None,
+    Vertical,
+    Horizontal
+};
+
+class WheelEventDeltaTracker {
+public:
+    WheelEventDeltaTracker();
+    virtual ~WheelEventDeltaTracker();
+
+    void beginTrackingDeltas();
+    void endTrackingDeltas();
+
+    bool isTrackingDeltas() const { return m_isTrackingDeltas; }
+
+    void recordWheelEventDelta(const PlatformWheelEvent&);
+    DominantScrollGestureDirection dominantScrollGestureDirection() const;
+
+private:
+    Deque<FloatSize, recentEventCount> m_recentWheelEventDeltas;
+    bool m_isTrackingDeltas;
+
+};
+
+} // namespace WebCore
+
+#endif // WheelEventDeltaTracker_h
index ae089b09c6336785c3d9bcf5b4e23f367300adf7..81ea276dc31bef37abfbedbb41d613ff4de763c6 100644 (file)
@@ -119,6 +119,20 @@ namespace WebCore {
             return copy;
         }
 
+        PlatformWheelEvent copyIgnoringHorizontalDelta() const
+        {
+            PlatformWheelEvent copy = *this;
+            copy.m_deltaX = 0;
+            return copy;
+        }
+
+        PlatformWheelEvent copyIgnoringVerticalDelta() const
+        {
+            PlatformWheelEvent copy = *this;
+            copy.m_deltaY = 0;
+            return copy;
+        }
+
         const IntPoint& position() const { return m_position; } // PlatformWindow coordinates.
         const IntPoint& globalPosition() const { return m_globalPosition; } // Screen coordinates.
 
index 5b5d7d59c033da9c8510b3bf6951bc37af0fa525..98be160dae35e31cc155286d8b308bb51c30b3ce 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-31  Beth Dakin  <bdakin@apple.com>
+
+        Sideways 'wobble' when scrolling with trackpad on Mavericks\r
+        https://bugs.webkit.org/show_bug.cgi?id=127521\r
+        -and corresponding-\r
+        <rdar://problem/14137306>
+
+        Reviewed by Simon Fraser.
+
+        Start using WebCore::WheelEventDeltaTracker to filter events.
+        * WebProcess/WebPage/EventDispatcher.cpp:
+        (WebKit::EventDispatcher::EventDispatcher):
+        (WebKit::EventDispatcher::wheelEvent):
+        * WebProcess/WebPage/EventDispatcher.h:
+
 2014-01-31  Zan Dobersek  <zdobersek@igalia.com>
 
         Fix the forward declaration of RawPluginMetaData in NetscapePluginModule.h
index 2dc475856557b1b27aa2f0a8b12f1103e594dd33..01ec316568de67e59319377035a1a7852cbd1f9f 100644 (file)
@@ -53,6 +53,7 @@ PassRefPtr<EventDispatcher> EventDispatcher::create()
 
 EventDispatcher::EventDispatcher()
     : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher"))
+    , m_recentWheelEventDeltaTracker(adoptPtr(new WheelEventDeltaTracker))
 {
 }
 
@@ -88,11 +89,37 @@ void EventDispatcher::initializeConnection(IPC::Connection* connection)
 
 void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent, bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom)
 {
+    PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
+
+#if PLATFORM(MAC)
+    switch (wheelEvent.phase()) {
+    case PlatformWheelEventPhaseBegan:
+        m_recentWheelEventDeltaTracker->beginTrackingDeltas();
+        break;
+    case PlatformWheelEventPhaseEnded:
+        m_recentWheelEventDeltaTracker->endTrackingDeltas();
+        break;
+    default:
+        break;
+    }
+
+    if (m_recentWheelEventDeltaTracker->isTrackingDeltas()) {
+        m_recentWheelEventDeltaTracker->recordWheelEventDelta(platformWheelEvent);
+
+        DominantScrollGestureDirection dominantDirection = DominantScrollGestureDirection::None;
+        dominantDirection = m_recentWheelEventDeltaTracker->dominantScrollGestureDirection();
+
+        // Workaround for scrolling issues <rdar://problem/14758615>.
+        if (dominantDirection == DominantScrollGestureDirection::Vertical && platformWheelEvent.deltaX())
+            platformWheelEvent = platformWheelEvent.copyIgnoringHorizontalDelta();
+        else if (dominantDirection == DominantScrollGestureDirection::Horizontal && platformWheelEvent.deltaY())
+            platformWheelEvent = platformWheelEvent.copyIgnoringVerticalDelta();
+    }
+#endif
+
 #if ENABLE(ASYNC_SCROLLING)
     MutexLocker locker(m_scrollingTreesMutex);
     if (ThreadedScrollingTree* scrollingTree = m_scrollingTrees.get(pageID)) {
-        PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
-
         // FIXME: It's pretty horrible that we're updating the back/forward state here.
         // WebCore should always know the current state and know when it changes so the
         // scrolling tree can be notified.
index b9998f17e90a73ea83543e1983a5b6bf95e4ae89..274cabbc091b7561fee47c2f59370b3d56637bd9 100644 (file)
@@ -27,6 +27,8 @@
 #define EventDispatcher_h
 
 #include "Connection.h"
+
+#include <WebCore/WheelEventDeltaTracker.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefPtr.h>
@@ -76,6 +78,7 @@ private:
     Mutex m_scrollingTreesMutex;
     HashMap<uint64_t, RefPtr<WebCore::ThreadedScrollingTree>> m_scrollingTrees;
 #endif
+    OwnPtr<WebCore::WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
 };
 
 } // namespace WebKit