void WebCompositorInputHandlerImpl::scrollBy(const IntPoint& increment) { if (increment == IntPoint::zero()) return; TRACE_EVENT2("cc", "WebCompositorInputHandlerImpl::scrollBy", "x", increment.x(), "y", increment.y()); WebMouseWheelEvent event; event.type = WebInputEvent::MouseWheel; event.deltaX = -increment.x(); event.deltaY = -increment.y(); event.hasPreciseScrollingDeltas = true; event.x = m_wheelFlingPoint.x(); event.y = m_wheelFlingPoint.y(); WebCompositorInputHandlerImpl::EventDisposition disposition = handleInputEventInternal(event); switch (disposition) { case DidHandle: case DropEvent: break; case DidNotHandle: TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::scrollBy::AbortFling"); // FIXME: If we got a DidNotHandle, that means we need to deliver wheels on the main thread. // In this case we need to schedule a commit and transfer the fling curve over to the main // thread and run the rest of the wheels from there. // This can happen when flinging a page that contains a scrollable subarea that we can't // scroll on the thread if the fling starts outside the subarea but then is flung "under" the // pointer. // For now, just abort the fling. cancelCurrentFling(); } }
bool WebCompositorInputHandlerImpl::touchpadFlingScroll(const WebPoint& increment) { WebMouseWheelEvent syntheticWheel; syntheticWheel.type = WebInputEvent::MouseWheel; syntheticWheel.deltaX = increment.x; syntheticWheel.deltaY = increment.y; syntheticWheel.hasPreciseScrollingDeltas = true; syntheticWheel.x = m_flingParameters.point.x; syntheticWheel.y = m_flingParameters.point.y; syntheticWheel.globalX = m_flingParameters.globalPoint.x; syntheticWheel.globalY = m_flingParameters.globalPoint.y; syntheticWheel.modifiers = m_flingParameters.modifiers; WebCompositorInputHandlerImpl::EventDisposition disposition = handleInputEventInternal(syntheticWheel); switch (disposition) { case DidHandle: return true; case DropEvent: break; case DidNotHandle: TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::scrollBy::AbortFling"); // If we got a DidNotHandle, that means we need to deliver wheels on the main thread. // In this case we need to schedule a commit and transfer the fling curve over to the main // thread and run the rest of the wheels from there. // This can happen when flinging a page that contains a scrollable subarea that we can't // scroll on the thread if the fling starts outside the subarea but then is flung "under" the // pointer. m_client->transferActiveWheelFlingAnimation(m_flingParameters); m_flingActiveOnMainThread = true; cancelCurrentFling(); break; } return false; }
void WebCompositorInputHandlerImpl::animate(double monotonicTime) { if (!m_wheelFlingAnimation) return; if (!m_wheelFlingParameters.startTime) m_wheelFlingParameters.startTime = monotonicTime; if (m_wheelFlingAnimation->animate(monotonicTime)) m_inputHandlerClient->scheduleAnimation(); else { TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::animate::flingOver"); cancelCurrentFling(); } }
void WebCompositorInputHandlerImpl::animate(double monotonicTime) { if (!m_flingCurve) return; if (!m_flingParameters.startTime) { m_flingParameters.startTime = monotonicTime; m_inputHandlerClient->scheduleAnimation(); return; } if (m_flingCurve->apply(monotonicTime - m_flingParameters.startTime, this)) m_inputHandlerClient->scheduleAnimation(); else { TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::animate::flingOver"); cancelCurrentFling(); } }
WebCompositorInputHandlerImpl::EventDisposition WebCompositorInputHandlerImpl::handleInputEventInternal(const WebInputEvent& event) { if (event.type == WebInputEvent::MouseWheel) { const WebMouseWheelEvent& wheelEvent = *static_cast<const WebMouseWheelEvent*>(&event); WebInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(WebPoint(wheelEvent.x, wheelEvent.y), WebInputHandlerClient::ScrollInputTypeWheel); switch (scrollStatus) { case WebInputHandlerClient::ScrollStatusStarted: { TRACE_EVENT_INSTANT2("webkit", "WebCompositorInputHandlerImpl::handleInput wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY); bool didScroll = m_inputHandlerClient->scrollByIfPossible(WebPoint(wheelEvent.x, wheelEvent.y), IntSize(-wheelEvent.deltaX, -wheelEvent.deltaY)); m_inputHandlerClient->scrollEnd(); return didScroll ? DidHandle : DropEvent; } case WebInputHandlerClient::ScrollStatusIgnored: // FIXME: This should be DropEvent, but in cases where we fail to properly sync scrollability it's safer to send the // event to the main thread. Change back to DropEvent once we have synchronization bugs sorted out. return DidNotHandle; case WebInputHandlerClient::ScrollStatusOnMainThread: return DidNotHandle; } } else if (event.type == WebInputEvent::GestureScrollBegin) { ASSERT(!m_gestureScrollOnImplThread); ASSERT(!m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = true; #endif const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); WebInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(WebPoint(gestureEvent.x, gestureEvent.y), WebInputHandlerClient::ScrollInputTypeGesture); switch (scrollStatus) { case WebInputHandlerClient::ScrollStatusStarted: m_gestureScrollOnImplThread = true; return DidHandle; case WebInputHandlerClient::ScrollStatusOnMainThread: return DidNotHandle; case WebInputHandlerClient::ScrollStatusIgnored: return DropEvent; } } else if (event.type == WebInputEvent::GestureScrollUpdate) { ASSERT(m_expectScrollUpdateEnd); if (!m_gestureScrollOnImplThread && !m_gesturePinchOnImplThread) return DidNotHandle; const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); bool didScroll = m_inputHandlerClient->scrollByIfPossible(WebPoint(gestureEvent.x, gestureEvent.y), IntSize(-gestureEvent.data.scrollUpdate.deltaX, -gestureEvent.data.scrollUpdate.deltaY)); return didScroll ? DidHandle : DropEvent; } else if (event.type == WebInputEvent::GestureScrollEnd) { ASSERT(m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = false; #endif if (!m_gestureScrollOnImplThread) return DidNotHandle; m_inputHandlerClient->scrollEnd(); m_gestureScrollOnImplThread = false; return DidHandle; } else if (event.type == WebInputEvent::GesturePinchBegin) { ASSERT(!m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = true; #endif m_inputHandlerClient->pinchGestureBegin(); m_gesturePinchOnImplThread = true; return DidHandle; } else if (event.type == WebInputEvent::GesturePinchEnd) { ASSERT(m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = false; #endif m_gesturePinchOnImplThread = false; m_inputHandlerClient->pinchGestureEnd(); return DidHandle; } else if (event.type == WebInputEvent::GesturePinchUpdate) { ASSERT(m_expectPinchUpdateEnd); const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); m_inputHandlerClient->pinchGestureUpdate(gestureEvent.data.pinchUpdate.scale, WebPoint(gestureEvent.x, gestureEvent.y)); return DidHandle; } else if (event.type == WebInputEvent::GestureFlingStart) { const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); return handleGestureFling(gestureEvent); } else if (event.type == WebInputEvent::GestureFlingCancel) { if (cancelCurrentFling()) return DidHandle; else if (!m_flingActiveOnMainThread) return DropEvent; #if ENABLE(TOUCH_EVENT_TRACKING) } else if (event.type == WebInputEvent::TouchStart) { const WebTouchEvent& touchEvent = *static_cast<const WebTouchEvent*>(&event); if (!m_inputHandlerClient->haveTouchEventHandlersAt(touchEvent.touches[0].position)) return DropEvent; #endif } else if (WebInputEvent::isKeyboardEventType(event.type)) { cancelCurrentFling(); } return DidNotHandle; }
WebCompositorInputHandlerImpl::EventDisposition WebCompositorInputHandlerImpl::handleInputEventInternal(const WebInputEvent& event) { if (event.type == WebInputEvent::MouseWheel) { const WebMouseWheelEvent& wheelEvent = *static_cast<const WebMouseWheelEvent*>(&event); CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(IntPoint(wheelEvent.x, wheelEvent.y), CCInputHandlerClient::Wheel); switch (scrollStatus) { case CCInputHandlerClient::ScrollStarted: { TRACE_EVENT_INSTANT2("cc", "WebCompositorInputHandlerImpl::handleInput wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY); m_inputHandlerClient->scrollBy(IntSize(-wheelEvent.deltaX, -wheelEvent.deltaY)); m_inputHandlerClient->scrollEnd(); return DidHandle; } case CCInputHandlerClient::ScrollIgnored: return DropEvent; case CCInputHandlerClient::ScrollFailed: return DidNotHandle; } } else if (event.type == WebInputEvent::GestureScrollBegin) { ASSERT(!m_gestureScrollStarted); ASSERT(!m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = true; #endif const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(IntPoint(gestureEvent.x, gestureEvent.y), CCInputHandlerClient::Gesture); switch (scrollStatus) { case CCInputHandlerClient::ScrollStarted: m_gestureScrollStarted = true; return DidHandle; case CCInputHandlerClient::ScrollFailed: return DidNotHandle; case CCInputHandlerClient::ScrollIgnored: return DropEvent; } } else if (event.type == WebInputEvent::GestureScrollUpdate) { ASSERT(m_expectScrollUpdateEnd); if (!m_gestureScrollStarted) return DidNotHandle; const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); m_inputHandlerClient->scrollBy(IntSize(-gestureEvent.deltaX, -gestureEvent.deltaY)); return DidHandle; } else if (event.type == WebInputEvent::GestureScrollEnd) { ASSERT(m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = false; #endif if (!m_gestureScrollStarted) return DidNotHandle; m_inputHandlerClient->scrollEnd(); m_gestureScrollStarted = false; return DidHandle; } else if (event.type == WebInputEvent::GesturePinchBegin) { ASSERT(!m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = true; #endif m_inputHandlerClient->pinchGestureBegin(); return DidHandle; } else if (event.type == WebInputEvent::GesturePinchEnd) { ASSERT(m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = false; #endif m_inputHandlerClient->pinchGestureEnd(); return DidHandle; } else if (event.type == WebInputEvent::GesturePinchUpdate) { ASSERT(m_expectPinchUpdateEnd); const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); m_inputHandlerClient->pinchGestureUpdate(gestureEvent.deltaX, IntPoint(gestureEvent.x, gestureEvent.y)); return DidHandle; } else if (event.type == WebInputEvent::GestureFlingStart) { const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); return handleGestureFling(gestureEvent); } else if (event.type == WebInputEvent::GestureFlingCancel) { if (cancelCurrentFling()) return DidHandle; } else if (WebInputEvent::isKeyboardEventType(event.type)) { cancelCurrentFling(); } return DidNotHandle; }
WebCompositorInputHandlerImpl::EventDisposition WebCompositorInputHandlerImpl::handleInputEventInternal(const WebInputEvent& event) { if (event.type == WebInputEvent::MouseWheel) { const WebMouseWheelEvent& wheelEvent = *static_cast<const WebMouseWheelEvent*>(&event); CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(IntPoint(wheelEvent.x, wheelEvent.y), CCInputHandlerClient::Wheel); switch (scrollStatus) { case CCInputHandlerClient::ScrollStarted: { TRACE_EVENT_INSTANT2("cc", "WebCompositorInputHandlerImpl::handleInput wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY); m_inputHandlerClient->scrollBy(IntPoint(wheelEvent.x, wheelEvent.y), IntSize(-wheelEvent.deltaX, -wheelEvent.deltaY)); m_inputHandlerClient->scrollEnd(); return DidHandle; } case CCInputHandlerClient::ScrollIgnored: // FIXME: This should be DropEvent, but in cases where we fail to properly sync scrollability it's safer to send the // event to the main thread. Change back to DropEvent once we have synchronization bugs sorted out. return DidNotHandle; case CCInputHandlerClient::ScrollOnMainThread: return DidNotHandle; } } else if (event.type == WebInputEvent::GestureScrollBegin) { ASSERT(!m_gestureScrollStarted); ASSERT(!m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = true; #endif const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(IntPoint(gestureEvent.x, gestureEvent.y), CCInputHandlerClient::Gesture); switch (scrollStatus) { case CCInputHandlerClient::ScrollStarted: m_gestureScrollStarted = true; return DidHandle; case CCInputHandlerClient::ScrollOnMainThread: return DidNotHandle; case CCInputHandlerClient::ScrollIgnored: return DropEvent; } } else if (event.type == WebInputEvent::GestureScrollUpdate) { ASSERT(m_expectScrollUpdateEnd); if (!m_gestureScrollStarted) return DidNotHandle; const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); m_inputHandlerClient->scrollBy(IntPoint(gestureEvent.x, gestureEvent.y), IntSize(-gestureEvent.deltaX, -gestureEvent.deltaY)); return DidHandle; } else if (event.type == WebInputEvent::GestureScrollEnd) { ASSERT(m_expectScrollUpdateEnd); #ifndef NDEBUG m_expectScrollUpdateEnd = false; #endif if (!m_gestureScrollStarted) return DidNotHandle; m_inputHandlerClient->scrollEnd(); m_gestureScrollStarted = false; return DidHandle; } else if (event.type == WebInputEvent::GesturePinchBegin) { ASSERT(!m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = true; #endif m_inputHandlerClient->pinchGestureBegin(); return DidHandle; } else if (event.type == WebInputEvent::GesturePinchEnd) { ASSERT(m_expectPinchUpdateEnd); #ifndef NDEBUG m_expectPinchUpdateEnd = false; #endif m_inputHandlerClient->pinchGestureEnd(); return DidHandle; } else if (event.type == WebInputEvent::GesturePinchUpdate) { ASSERT(m_expectPinchUpdateEnd); const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); m_inputHandlerClient->pinchGestureUpdate(gestureEvent.deltaX, IntPoint(gestureEvent.x, gestureEvent.y)); return DidHandle; } else if (event.type == WebInputEvent::GestureFlingStart) { const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent*>(&event); return handleGestureFling(gestureEvent); } else if (event.type == WebInputEvent::GestureFlingCancel) { if (cancelCurrentFling()) return DidHandle; } else if (WebInputEvent::isKeyboardEventType(event.type)) { cancelCurrentFling(); } return DidNotHandle; }