Wheel events don't latch to inner scrollable elements
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Feb 2014 20:43:56 +0000 (20:43 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Feb 2014 20:43:56 +0000 (20:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128225

Reviewed by Beth Dakin.

* page/EventHandler.cpp:
(WebCore::EventHandler::handleWheelEvent): Identify the case
where we have hit the end of a scroll, and treat that as a
valid 'handled' case. If the scroll event is just starting,
treat end-of-scroll as unhandled so the parent element can
handle things.
* page/WheelEventDeltaTracker.h:
(WebCore::WheelEventDeltaTracker::isFirstWheelEvent): Added.

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

Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/WheelEventDeltaTracker.h

index 784bdfbe8779411e5b71a6ebb95fc32a0bdda58c..5cf6e886e4e85253dd9e104d0111483d3456ce9a 100644 (file)
@@ -1,3 +1,19 @@
+2014-02-05  Brent Fulgham  <bfulgham@apple.com>
+
+        Wheel events don't latch to inner scrollable elements 
+        https://bugs.webkit.org/show_bug.cgi?id=128225
+
+        Reviewed by Beth Dakin.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleWheelEvent): Identify the case
+        where we have hit the end of a scroll, and treat that as a
+        valid 'handled' case. If the scroll event is just starting,
+        treat end-of-scroll as unhandled so the parent element can
+        handle things.
+        * page/WheelEventDeltaTracker.h:
+        (WebCore::WheelEventDeltaTracker::isFirstWheelEvent): Added.
+
 2014-02-06  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r163542.
index 1a3f10e6bbbf1f3dc62a006b414f9ee9b8eadab5..08ae860b0ccb8bdcc746f3ab67b80e0616ca856d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
  * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
  *
@@ -2528,6 +2528,35 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
 
     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     view = m_frame.view();
+    
+#if PLATFORM(MAC)
+    if (useLatchedWheelEventElement && m_latchedWheelEventElement == element) {
+        bool enclosingFrameIsMainFrame = view ? view->frame().isMainFrame() : false;
+
+        // If we are latched, and have nowhere to scroll, treat the scroll event as ended so that we don't
+        // cause the scroll to break free of the current scrolling widget.
+        if (!enclosingFrameIsMainFrame) {
+            bool didHandleWheelEvent = view ? view->wheelEvent(event) : false;
+            if (!didHandleWheelEvent) {
+                // If we are just starting a scroll event, and have nowhere left to scroll, allow
+                // the enclosing frame to handle the scroll.
+                didHandleWheelEvent = !m_recentWheelEventDeltaTracker->isFirstWheelEvent();
+            }
+
+            m_isHandlingWheelEvent = false;
+            return didHandleWheelEvent;
+        }
+
+        if (!m_recentWheelEventDeltaTracker->isFirstWheelEvent()) {
+            // When the main frame is our parent, and we have been scrolling within this region, we do not
+            // want to have the main frame consume any remaining scroll events. Keep them latched to this
+            // element.
+            m_isHandlingWheelEvent = false;
+            return true;
+        }
+    }
+#endif
+
     bool didHandleEvent = view ? view->wheelEvent(event) : false;
     m_isHandlingWheelEvent = false;
     return didHandleEvent;
index 1dc818b0b2bf15d42da17adc583b0bff660b7ae9..fb5f931416dcd01a067596ac34beb5606080b553 100644 (file)
@@ -51,6 +51,7 @@ public:
     void endTrackingDeltas();
 
     bool isTrackingDeltas() const { return m_isTrackingDeltas; }
+    bool isFirstWheelEvent() const { return m_recentWheelEventDeltas.size() <= 1; }
 
     void recordWheelEventDelta(const PlatformWheelEvent&);
     DominantScrollGestureDirection dominantScrollGestureDirection() const;