Modified: trunk/Source/WebKit2/UIProcess/ViewGestureController.cpp (188832 => 188833)
--- trunk/Source/WebKit2/UIProcess/ViewGestureController.cpp 2015-08-23 02:28:09 UTC (rev 188832)
+++ trunk/Source/WebKit2/UIProcess/ViewGestureController.cpp 2015-08-23 04:14:44 UTC (rev 188833)
@@ -52,10 +52,12 @@
return viewGestureControllers.get();
}
-
ViewGestureController::ViewGestureController(WebPageProxy& webPageProxy)
: m_webPageProxy(webPageProxy)
, m_swipeActiveLoadMonitoringTimer(RunLoop::main(), this, &ViewGestureController::checkForActiveLoads)
+#if PLATFORM(MAC)
+ , m_pendingSwipeTracker(webPageProxy, std::bind(&ViewGestureController::trackSwipeGesture, this, std::placeholders::_1, std::placeholders::_2))
+#endif
{
m_webPageProxy.process().addMessageReceiver(Messages::ViewGestureController::messageReceiverName(), m_webPageProxy.pageID(), *this);
Modified: trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h (188832 => 188833)
--- trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h 2015-08-23 02:28:09 UTC (rev 188832)
+++ trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h 2015-08-23 04:14:44 UTC (rev 188833)
@@ -89,12 +89,6 @@
Forward
};
- enum class PendingSwipeReason {
- None,
- WebCoreMayScroll,
- InsufficientMagnitude
- };
-
#if PLATFORM(MAC)
double magnification() const;
@@ -104,15 +98,15 @@
void handleSmartMagnificationGesture(WebCore::FloatPoint origin);
bool handleScrollWheelEvent(NSEvent *);
- void wheelEventWasNotHandledByWebCore(NSEvent *);
+ void wheelEventWasNotHandledByWebCore(NSEvent *event) { m_pendingSwipeTracker.eventWasNotHandledByWebCore(event); }
void setCustomSwipeViews(Vector<RetainPtr<NSView>> views) { m_customSwipeViews = WTF::move(views); }
void setCustomSwipeViewsTopContentInset(float topContentInset) { m_customSwipeViewsTopContentInset = topContentInset; }
WebCore::FloatRect windowRelativeBoundsForCustomSwipeViews() const;
void setDidMoveSwipeSnapshotCallback(void(^)(CGRect));
- bool shouldIgnorePinnedState() { return m_shouldIgnorePinnedState; }
- void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; }
+ bool shouldIgnorePinnedState() { return m_pendingSwipeTracker.shouldIgnorePinnedState(); }
+ void setShouldIgnorePinnedState(bool ignore) { m_pendingSwipeTracker.setShouldIgnorePinnedState(ignore); }
#else
void installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView);
void setAlternateBackForwardListSourceView(WKWebView *);
@@ -195,8 +189,6 @@
void handleSwipeGesture(WebBackForwardListItem* targetItem, double progress, SwipeDirection);
void willEndSwipeGesture(WebBackForwardListItem& targetItem, bool cancelled);
void endSwipeGesture(WebBackForwardListItem* targetItem, bool cancelled);
- bool deltaIsSufficientToBeginSwipe(NSEvent *);
- bool scrollEventCanBecomeSwipe(NSEvent *, SwipeDirection&);
bool shouldUseSnapshotForSize(ViewSnapshot&, WebCore::FloatSize swipeLayerSize, float topContentInset);
CALayer *determineSnapshotLayerParent() const;
@@ -205,6 +197,37 @@
void didMoveSwipeSnapshotLayer();
void forceRepaintIfNeeded();
+
+ class PendingSwipeTracker {
+ public:
+ PendingSwipeTracker(WebPageProxy&, std::function<void(NSEvent *, SwipeDirection)> trackSwipeCallback);
+ bool handleEvent(NSEvent *);
+ void eventWasNotHandledByWebCore(NSEvent *);
+
+ void reset(const char* resetReasonForLogging);
+
+ bool shouldIgnorePinnedState() { return m_shouldIgnorePinnedState; }
+ void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; }
+
+ private:
+ bool tryToStartSwipe(NSEvent *);
+ bool scrollEventCanBecomeSwipe(NSEvent *, SwipeDirection&);
+
+ enum class State {
+ None,
+ WaitingForWebCore,
+ InsufficientMagnitude
+ };
+
+ State m_state { State::None };
+ SwipeDirection m_direction;
+ WebCore::FloatSize m_cumulativeDelta;
+
+ bool m_shouldIgnorePinnedState { false };
+
+ std::function<void(NSEvent *, SwipeDirection)> m_trackSwipeCallback;
+ WebPageProxy& m_webPageProxy;
+ };
#endif
WebPageProxy& m_webPageProxy;
@@ -240,16 +263,10 @@
float m_customSwipeViewsTopContentInset { 0 };
WebCore::FloatRect m_currentSwipeCustomViewBounds;
- // If we need to wait for content to decide if it is going to consume
- // the scroll event that would have started a swipe, we'll fill these in.
- PendingSwipeReason m_pendingSwipeReason { PendingSwipeReason::None };
- SwipeDirection m_pendingSwipeDirection;
- WebCore::FloatSize m_cumulativeDeltaForPendingSwipe;
+ PendingSwipeTracker m_pendingSwipeTracker;
void (^m_didMoveSwipeSnapshotCallback)(CGRect) { nullptr };
- bool m_shouldIgnorePinnedState { false };
-
bool m_hasOutstandingRepaintRequest { false };
#else
UIView *m_liveSwipeView { nullptr };
Modified: trunk/Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm (188832 => 188833)
--- trunk/Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm 2015-08-23 02:28:09 UTC (rev 188832)
+++ trunk/Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm 2015-08-23 04:14:44 UTC (rev 188833)
@@ -29,6 +29,7 @@
#if PLATFORM(MAC)
#import "FrameLoadState.h"
+#import "Logging.h"
#import "NativeWebWheelEvent.h"
#import "ViewGestureControllerMessages.h"
#import "ViewGestureGeometryCollectorMessages.h"
@@ -120,7 +121,7 @@
// Outside of the extremes, resist further scaling.
double limit = currentScale < minMagnification ? minMagnification : maxMagnification;
- double scaleDistance = fabs(limit - currentScale);
+ double scaleDistance = std::abs(limit - currentScale);
double scalePercent = std::min(std::max(scaleDistance / limit, 0.), 1.);
double resistance = zoomOutResistance + scalePercent * (0.01 - zoomOutResistance);
@@ -204,7 +205,7 @@
static float maximumRectangleComponentDelta(FloatRect a, FloatRect b)
{
- return std::max(fabs(a.x() - b.x()), std::max(fabs(a.y() - b.y()), std::max(fabs(a.width() - b.width()), fabs(a.height() - b.height()))));
+ return std::max(std::abs(a.x() - b.x()), std::max(std::abs(a.y() - b.y()), std::max(std::abs(a.width() - b.width()), std::abs(a.height() - b.height()))));
}
void ViewGestureController::didCollectGeometryForSmartMagnificationGesture(FloatPoint origin, FloatRect renderRect, FloatRect visibleContentRect, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale)
@@ -264,20 +265,33 @@
m_lastMagnificationGestureWasSmartMagnification = true;
}
-bool ViewGestureController::scrollEventCanBecomeSwipe(NSEvent *event, ViewGestureController::SwipeDirection& potentialSwipeDirection)
+static bool scrollEventCanInfluenceSwipe(NSEvent *event)
{
+ return event.hasPreciseScrollingDeltas && [NSEvent isSwipeTrackingFromScrollEventsEnabled];
+}
+
+static bool deltaShouldCancelSwipe(float x, float y)
+{
+ return std::abs(y) >= std::abs(x) * minimumScrollEventRatioForSwipe;
+}
+
+ViewGestureController::PendingSwipeTracker::PendingSwipeTracker(WebPageProxy& webPageProxy, std::function<void(NSEvent *, SwipeDirection)> trackSwipeCallback)
+ : m_trackSwipeCallback(WTF::move(trackSwipeCallback))
+ , m_webPageProxy(webPageProxy)
+{
+}
+
+bool ViewGestureController::PendingSwipeTracker::scrollEventCanBecomeSwipe(NSEvent *event, ViewGestureController::SwipeDirection& potentialSwipeDirection)
+{
if (event.phase != NSEventPhaseBegan)
return false;
- if (!event.hasPreciseScrollingDeltas)
+ if (!scrollEventCanInfluenceSwipe(event))
return false;
- if (![NSEvent isSwipeTrackingFromScrollEventsEnabled])
+ if (deltaShouldCancelSwipe(event.scrollingDeltaX, event.scrollingDeltaY))
return false;
- if (fabs(event.scrollingDeltaX) <= fabs(event.scrollingDeltaY))
- return false;
-
bool isPinnedToLeft = m_shouldIgnorePinnedState || m_webPageProxy.isPinnedToLeftSide();
bool isPinnedToRight = m_shouldIgnorePinnedState || m_webPageProxy.isPinnedToRightSide();
@@ -291,95 +305,91 @@
return true;
}
-bool ViewGestureController::deltaIsSufficientToBeginSwipe(NSEvent *event)
+bool ViewGestureController::handleScrollWheelEvent(NSEvent *event)
{
- if (m_pendingSwipeReason != PendingSwipeReason::InsufficientMagnitude)
+ if (m_activeGestureType != ViewGestureType::None)
return false;
+ return m_pendingSwipeTracker.handleEvent(event);
+}
- m_cumulativeDeltaForPendingSwipe += FloatSize(event.scrollingDeltaX, event.scrollingDeltaY);
-
- // If the cumulative delta is ever "too vertical", we will stop tracking this
- // as a potential swipe until we get another "begin" event.
- if (fabs(m_cumulativeDeltaForPendingSwipe.height()) >= fabs(m_cumulativeDeltaForPendingSwipe.width()) * minimumScrollEventRatioForSwipe) {
- m_pendingSwipeReason = PendingSwipeReason::None;
+bool ViewGestureController::PendingSwipeTracker::handleEvent(NSEvent *event)
+{
+ if (event.phase == NSEventPhaseEnded) {
+ reset("gesture ended");
return false;
}
- if (fabs(m_cumulativeDeltaForPendingSwipe.width()) < minimumHorizontalSwipeDistance)
+ if (m_state == State::None) {
+ if (!scrollEventCanBecomeSwipe(event, m_direction))
+ return false;
+
+ if (!m_shouldIgnorePinnedState && m_webPageProxy.willHandleHorizontalScrollEvents()) {
+ m_state = State::WaitingForWebCore;
+ LOG(ViewGestures, "Swipe Start Hysteresis - waiting for WebCore to handle event");
+ }
+ }
+
+ if (m_state == State::WaitingForWebCore)
return false;
- return true;
+ return tryToStartSwipe(event);
}
-void ViewGestureController::setDidMoveSwipeSnapshotCallback(void(^callback)(CGRect))
+void ViewGestureController::PendingSwipeTracker::eventWasNotHandledByWebCore(NSEvent *event)
{
- if (m_didMoveSwipeSnapshotCallback)
- Block_release(m_didMoveSwipeSnapshotCallback);
- m_didMoveSwipeSnapshotCallback = Block_copy(callback);
+ if (m_state != State::WaitingForWebCore)
+ return;
+
+ LOG(ViewGestures, "Swipe Start Hysteresis - WebCore didn't handle event");
+ m_state = State::None;
+ m_cumulativeDelta = FloatSize();
+ tryToStartSwipe(event);
}
-bool ViewGestureController::handleScrollWheelEvent(NSEvent *event)
+bool ViewGestureController::PendingSwipeTracker::tryToStartSwipe(NSEvent *event)
{
- if (event.phase == NSEventPhaseEnded) {
- m_cumulativeDeltaForPendingSwipe = FloatSize();
- m_pendingSwipeReason = PendingSwipeReason::None;
- }
+ ASSERT(m_state != State::WaitingForWebCore);
- if (m_pendingSwipeReason == PendingSwipeReason::InsufficientMagnitude) {
- if (deltaIsSufficientToBeginSwipe(event)) {
- trackSwipeGesture(event, m_pendingSwipeDirection);
- return true;
- }
+ if (m_state == State::None) {
+ SwipeDirection direction;
+ if (!scrollEventCanBecomeSwipe(event, direction))
+ return false;
}
- if (m_activeGestureType != ViewGestureType::None)
+ if (!scrollEventCanInfluenceSwipe(event))
return false;
- SwipeDirection direction;
- if (!scrollEventCanBecomeSwipe(event, direction))
- return false;
+ m_cumulativeDelta += FloatSize(event.scrollingDeltaX, event.scrollingDeltaY);
+ LOG(ViewGestures, "Swipe Start Hysteresis - consumed event, cumulative delta (%0.2f, %0.2f)", m_cumulativeDelta.width(), m_cumulativeDelta.height());
- if (!m_shouldIgnorePinnedState && m_webPageProxy.willHandleHorizontalScrollEvents()) {
- m_pendingSwipeReason = PendingSwipeReason::WebCoreMayScroll;
- m_pendingSwipeDirection = direction;
+ if (deltaShouldCancelSwipe(m_cumulativeDelta.width(), m_cumulativeDelta.height())) {
+ reset("cumulative delta became too vertical");
return false;
}
- if (!deltaIsSufficientToBeginSwipe(event)) {
- m_pendingSwipeReason = PendingSwipeReason::InsufficientMagnitude;
- m_pendingSwipeDirection = direction;
- return true;
- }
+ if (std::abs(m_cumulativeDelta.width()) >= minimumHorizontalSwipeDistance)
+ m_trackSwipeCallback(event, m_direction);
+ else
+ m_state = State::InsufficientMagnitude;
- trackSwipeGesture(event, direction);
-
return true;
}
-void ViewGestureController::wheelEventWasNotHandledByWebCore(NSEvent *event)
+void ViewGestureController::PendingSwipeTracker::reset(const char* resetReasonForLogging)
{
- if (m_pendingSwipeReason != PendingSwipeReason::WebCoreMayScroll)
- return;
+ if (m_state != State::None)
+ LOG(ViewGestures, "Swipe Start Hysteresis - reset; %s", resetReasonForLogging);
- m_pendingSwipeReason = PendingSwipeReason::None;
-
- SwipeDirection direction;
- if (!scrollEventCanBecomeSwipe(event, direction))
- return;
-
- if (!deltaIsSufficientToBeginSwipe(event)) {
- m_pendingSwipeReason = PendingSwipeReason::InsufficientMagnitude;
- return;
- }
-
- trackSwipeGesture(event, m_pendingSwipeDirection);
+ m_state = State::None;
+ m_cumulativeDelta = FloatSize();
}
void ViewGestureController::trackSwipeGesture(NSEvent *event, SwipeDirection direction)
{
ASSERT(m_activeGestureType == ViewGestureType::None);
- m_pendingSwipeReason = PendingSwipeReason::None;
+ m_pendingSwipeTracker.reset("starting to track swipe");
+
m_webPageProxy.recordNavigationSnapshot();
CGFloat maxProgress = (direction == SwipeDirection::Back) ? 1 : 0;
@@ -694,8 +704,8 @@
dimmingProgress = std::min(1., std::max(dimmingProgress, 0.));
[m_swipeDimmingLayer setOpacity:dimmingProgress * swipeOverlayDimmingOpacity];
- double absoluteProgress = fabs(progress);
- double remainingSwipeDistance = width - fabs(absoluteProgress * width);
+ double absoluteProgress = std::abs(progress);
+ double remainingSwipeDistance = width - std::abs(absoluteProgress * width);
double shadowFadeDistance = [m_swipeShadowLayer bounds].size.width;
if (remainingSwipeDistance < shadowFadeDistance)
[m_swipeShadowLayer setOpacity:(remainingSwipeDistance / shadowFadeDistance) * swipeOverlayShadowOpacity];
@@ -723,6 +733,13 @@
}
}
+void ViewGestureController::setDidMoveSwipeSnapshotCallback(void(^callback)(CGRect))
+{
+ if (m_didMoveSwipeSnapshotCallback)
+ Block_release(m_didMoveSwipeSnapshotCallback);
+ m_didMoveSwipeSnapshotCallback = Block_copy(callback);
+}
+
void ViewGestureController::didMoveSwipeSnapshotLayer()
{
if (!m_didMoveSwipeSnapshotCallback)