Modified: branches/safari-537-branch/Source/WebCore/ChangeLog (154616 => 154617)
--- branches/safari-537-branch/Source/WebCore/ChangeLog 2013-08-26 17:54:33 UTC (rev 154616)
+++ branches/safari-537-branch/Source/WebCore/ChangeLog 2013-08-26 17:55:41 UTC (rev 154617)
@@ -1,3 +1,38 @@
+2013-08-26 Lucas Forschler <[email protected]>
+
+ Merge r154535
+
+ 2013-08-23 Simon Fraser <[email protected]>
+
+ Improve scrolling behavior in iTunes
+ https://bugs.webkit.org/show_bug.cgi?id=120241
+ <rdar://problem/14825344>
+
+ Reviewed by Sam Weinig.
+
+ When vertically scrolling a page with horizontally scrollable overflow areas,
+ vertical scroll gestures would be interrupted when wheel events with non-zero
+ X deltas were intercepted by the overflow areas.
+
+ Fix by storing a small history of wheel events deltas and using
+ it to determine of the scroll gesture is primarily vertical or horizontal.
+ When this is detected, avoid dispatching scroll events on the on the
+ non-dominant axis.
+
+ Currently this behavior is conditionalized to only apply in iTunes.
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::EventHandler):
+ (WebCore::EventHandler::recordWheelEventDelta):
+ (WebCore::deltaIsPredominantlyVertical):
+ (WebCore::EventHandler::dominantScrollGestureDirection):
+ (WebCore::EventHandler::handleWheelEvent):
+ (WebCore::EventHandler::defaultWheelEventHandler):
+ * page/EventHandler.h:
+ * platform/RuntimeApplicationChecks.cpp:
+ (WebCore::applicationIsITunes):
+ * platform/RuntimeApplicationChecks.h:
+
2013-08-21 Lucas Forschler <[email protected]>
Merge r154378
Modified: branches/safari-537-branch/Source/WebCore/page/EventHandler.cpp (154616 => 154617)
--- branches/safari-537-branch/Source/WebCore/page/EventHandler.cpp 2013-08-26 17:54:33 UTC (rev 154616)
+++ branches/safari-537-branch/Source/WebCore/page/EventHandler.cpp 2013-08-26 17:55:41 UTC (rev 154617)
@@ -74,6 +74,7 @@
#include "RenderTextControlSingleLine.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "RuntimeApplicationChecks.h"
#include "ScrollAnimator.h"
#include "Scrollbar.h"
#include "Settings.h"
@@ -330,6 +331,7 @@
, m_clickCount(0)
, m_mousePositionIsUnknown(true)
, m_mouseDownTimestamp(0)
+ , m_inTrackingScrollGesturePhase(false)
, m_widgetIsLatched(false)
#if PLATFORM(MAC)
, m_mouseDownView(nil)
@@ -2391,6 +2393,41 @@
}
#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* doc = m_frame->document();
@@ -2446,6 +2483,22 @@
if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, e))
event = event.copyTurningVerticalTicksIntoHorizontalTicks();
+#if PLATFORM(MAC)
+ switch (event.phase()) {
+ case PlatformWheelEventPhaseBegan:
+ m_recentWheelEventDeltas.clear();
+ m_inTrackingScrollGesturePhase = true;
+ break;
+ case PlatformWheelEventPhaseEnded:
+ m_inTrackingScrollGesturePhase = false;
+ break;
+ default:
+ break;
+ }
+#endif
+
+ recordWheelEventDelta(event);
+
if (node) {
// Figure out which view to send the event to.
RenderObject* target = node->renderer();
@@ -2480,12 +2533,17 @@
Node* stopNode = m_previousWheelScrolledNode.get();
ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
+ DominantScrollGestureDirection dominantDirection = DominantScrollDirectionNone;
+ // Workaround for scrolling issues in iTunes (<rdar://problem/14758615>).
+ if (m_inTrackingScrollGesturePhase && applicationIsITunes())
+ dominantDirection = dominantScrollGestureDirection();
+
// 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 (scrollNode(wheelEvent->rawDeltaX(), granularity, ScrollLeft, ScrollRight, startNode, &stopNode))
+ if (dominantDirection != DominantScrollDirectionVertical && scrollNode(wheelEvent->rawDeltaX(), granularity, ScrollLeft, ScrollRight, startNode, &stopNode))
wheelEvent->setDefaultHandled();
- if (scrollNode(wheelEvent->rawDeltaY(), granularity, ScrollUp, ScrollDown, startNode, &stopNode))
+ if (dominantDirection != DominantScrollDirectionHorizontal && scrollNode(wheelEvent->rawDeltaY(), granularity, ScrollUp, ScrollDown, startNode, &stopNode))
wheelEvent->setDefaultHandled();
if (!m_latchedWheelEventNode)
Modified: branches/safari-537-branch/Source/WebCore/page/EventHandler.h (154616 => 154617)
--- branches/safari-537-branch/Source/WebCore/page/EventHandler.h 2013-08-26 17:54:33 UTC (rev 154616)
+++ branches/safari-537-branch/Source/WebCore/page/EventHandler.h 2013-08-26 17:55:41 UTC (rev 154617)
@@ -38,6 +38,7 @@
#include "TextGranularity.h"
#include "Timer.h"
#include "UserGestureIndicator.h"
+#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
@@ -293,6 +294,14 @@
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; }
static bool isKeyboardOptionTab(KeyboardEvent*);
@@ -468,7 +477,9 @@
PlatformMouseEvent m_mouseDown;
RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
+ Deque<FloatSize> m_recentWheelEventDeltas;
RefPtr<Node> m_latchedWheelEventNode;
+ bool m_inTrackingScrollGesturePhase;
bool m_widgetIsLatched;
RefPtr<Node> m_previousWheelScrolledNode;
Modified: branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.cpp (154616 => 154617)
--- branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.cpp 2013-08-26 17:54:33 UTC (rev 154616)
+++ branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.cpp 2013-08-26 17:55:41 UTC (rev 154617)
@@ -66,6 +66,12 @@
return isAppleMail;
}
+bool applicationIsITunes()
+{
+ static bool isITunes = mainBundleIsEqualTo("com.apple.iTunes");
+ return isITunes;
+}
+
bool applicationIsMicrosoftMessenger()
{
static bool isMicrosoftMessenger = mainBundleIsEqualTo("com.microsoft.Messenger");
Modified: branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.h (154616 => 154617)
--- branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.h 2013-08-26 17:54:33 UTC (rev 154616)
+++ branches/safari-537-branch/Source/WebCore/platform/RuntimeApplicationChecks.h 2013-08-26 17:55:41 UTC (rev 154617)
@@ -32,6 +32,7 @@
bool applicationIsAdobeInstaller();
bool applicationIsAperture();
bool applicationIsAppleMail();
+bool applicationIsITunes();
bool applicationIsMicrosoftMessenger();
bool applicationIsMicrosoftMyDay();
bool applicationIsMicrosoftOutlook();