예제 #1
0
bool TouchEventHandler::handleTouchPoint(Platform::TouchPoint& point)
{
    // Enable input mode on any touch event.
    m_webPage->m_inputHandler->enableInputMode();

    switch (point.m_state) {
    case Platform::TouchPoint::TouchPressed:
        {
            m_lastFatFingersResult.reset(); // Theoretically this shouldn't be required. Keep it just in case states get mangled.
            m_didCancelTouch = false;
            m_lastScreenPoint = point.m_screenPos;

            IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos));

            m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint();

            Element* elementUnderFatFinger = 0;
            if (m_lastFatFingersResult.positionWasAdjusted() && m_lastFatFingersResult.node()) {
                ASSERT(m_lastFatFingersResult.node()->isElementNode());
                elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
            }

            // Set or reset the touch mode.
            Element* possibleTargetNodeForMouseMoveEvents = static_cast<Element*>(m_lastFatFingersResult.positionWasAdjusted() ? elementUnderFatFinger : m_lastFatFingersResult.node());
            m_convertTouchToMouse = shouldConvertTouchToMouse(possibleTargetNodeForMouseMoveEvents);

            if (elementUnderFatFinger)
                drawTapHighlight();

            // Lets be conservative here: since we have problems on major website having
            // mousemove listener for no good reason (e.g. google.com, desktop edition),
            // let only delay client notifications when there is not input text node involved.
            if (m_convertTouchToMouse
                && (m_webPage->m_inputHandler->isInputMode() && !m_lastFatFingersResult.isTextInput())) {
                m_webPage->m_inputHandler->setDelayKeyboardVisibilityChange(true);
                handleFatFingerPressed();
            } else if (!shouldSuppressMouseDownOnTouchDown())
                handleFatFingerPressed();

            return true;
        }
    case Platform::TouchPoint::TouchReleased:
        {
            unsigned spellLength = spellCheck(point);
            // Apply any suppressed changes. This does not eliminate the need
            // for the show after the handling of fat finger pressed as it may
            // have triggered a state change.
            m_webPage->m_inputHandler->processPendingKeyboardVisibilityChange();

            if (shouldSuppressMouseDownOnTouchDown())
                handleFatFingerPressed();

            // The rebase has eliminated a necessary event when the mouse does not
            // trigger an actual selection change preventing re-showing of the
            // keyboard. If input mode is active, call showVirtualKeyboard which
            // will update the state and display keyboard if needed.
            if (m_webPage->m_inputHandler->isInputMode())
                m_webPage->m_inputHandler->notifyClientOfKeyboardVisibilityChange(true);

            IntPoint adjustedPoint;
            if (m_convertTouchToMouse) {
                adjustedPoint = point.m_pos;
                m_convertTouchToMouse = false;
            } else // Fat finger point in viewport coordinates.
                adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition());

            PlatformMouseEvent mouseEvent(adjustedPoint, m_lastScreenPoint, PlatformEvent::MouseReleased, 1, LeftButton, TouchScreen);
            m_webPage->handleMouseEvent(mouseEvent);
            m_lastFatFingersResult.reset(); // Reset the fat finger result as its no longer valid when a user's finger is not on the screen.
            if (spellLength) {
                unsigned end = m_webPage->m_inputHandler->caretPosition();
                unsigned start = end - spellLength;
                m_webPage->m_client->requestSpellingSuggestionsForString(start, end);
            }
            return true;
        }
    case Platform::TouchPoint::TouchMoved:
        if (m_convertTouchToMouse) {
            PlatformMouseEvent mouseEvent(point.m_pos, m_lastScreenPoint, PlatformEvent::MouseMoved, 1, LeftButton, TouchScreen);
            m_lastScreenPoint = point.m_screenPos;
            if (!m_webPage->handleMouseEvent(mouseEvent)) {
                m_convertTouchToMouse = false;
                return false;
            }
            return true;
        }
        break;
    default:
        break;
    }
    return false;
}
예제 #2
0
bool TouchEventHandler::handleTouchPoint(Platform::TouchPoint& point, bool useFatFingers)
{
    // Enable input mode on any touch event.
    m_webPage->m_inputHandler->setInputModeEnabled();
    bool pureWithMouseConversion = m_webPage->m_touchEventMode == PureTouchEventsWithMouseConversion;
    bool alwaysEnableMouseConversion = pureWithMouseConversion || (!isMainFrameScrollable(m_webPage) && !m_webPage->m_inRegionScroller->d->isActive());

    switch (point.m_state) {
    case Platform::TouchPoint::TouchPressed:
        {
            // FIXME: bypass FatFingers if useFatFingers is false
            m_lastFatFingersResult.reset(); // Theoretically this shouldn't be required. Keep it just in case states get mangled.
            m_didCancelTouch = false;
            m_lastScreenPoint = point.m_screenPos;

            IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos));

            m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint();

            Element* elementUnderFatFinger = 0;
            if (m_lastFatFingersResult.positionWasAdjusted() && m_lastFatFingersResult.node()) {
                ASSERT(m_lastFatFingersResult.node()->isElementNode());
                elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
            }

            // Set or reset the touch mode.
            Element* possibleTargetNodeForMouseMoveEvents = static_cast<Element*>(m_lastFatFingersResult.positionWasAdjusted() ? elementUnderFatFinger : m_lastFatFingersResult.node());
            m_convertTouchToMouse = alwaysEnableMouseConversion ? true : shouldConvertTouchToMouse(possibleTargetNodeForMouseMoveEvents);

            if (!possibleTargetNodeForMouseMoveEvents || (!possibleTargetNodeForMouseMoveEvents->hasEventListeners(eventNames().touchmoveEvent) && !m_convertTouchToMouse))
                m_webPage->client()->notifyNoMouseMoveOrTouchMoveHandlers();

            if (elementUnderFatFinger)
                drawTapHighlight();

            // Lets be conservative here: since we have problems on major website having
            // mousemove listener for no good reason (e.g. google.com, desktop edition),
            // let only delay client notifications when there is not input text node involved.
            if (m_convertTouchToMouse
                && (m_webPage->m_inputHandler->isInputMode() && !m_lastFatFingersResult.isTextInput())) {
                m_webPage->m_inputHandler->setDelayKeyboardVisibilityChange(true);
                handleFatFingerPressed();
            } else if (!shouldSuppressMouseDownOnTouchDown())
                handleFatFingerPressed();

            return true;
        }
    case Platform::TouchPoint::TouchReleased:
        {
            imf_sp_text_t spellCheckOptionRequest;
            bool shouldRequestSpellCheckOptions = false;

            if (m_lastFatFingersResult.isTextInput())
                shouldRequestSpellCheckOptions = m_webPage->m_inputHandler->shouldRequestSpellCheckingOptionsForPoint(point.m_pos
                                                                                                                      , m_lastFatFingersResult.nodeAsElementIfApplicable(FatFingersResult::ShadowContentNotAllowed)
                                                                                                                      , spellCheckOptionRequest);

            // Apply any suppressed changes. This does not eliminate the need
            // for the show after the handling of fat finger pressed as it may
            // have triggered a state change. Leave the change suppressed if
            // we are triggering spell check options.
            if (!shouldRequestSpellCheckOptions)
                m_webPage->m_inputHandler->processPendingKeyboardVisibilityChange();

            if (shouldSuppressMouseDownOnTouchDown())
                handleFatFingerPressed();

            // The rebase has eliminated a necessary event when the mouse does not
            // trigger an actual selection change preventing re-showing of the
            // keyboard. If input mode is active, call showVirtualKeyboard which
            // will update the state and display keyboard if needed.
            if (m_webPage->m_inputHandler->isInputMode())
                m_webPage->m_inputHandler->notifyClientOfKeyboardVisibilityChange(true);

            IntPoint adjustedPoint;
            if (m_convertTouchToMouse || !useFatFingers) {
                adjustedPoint = point.m_pos;
                m_convertTouchToMouse = pureWithMouseConversion;
            } else // Fat finger point in viewport coordinates.
                adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition());

            PlatformMouseEvent mouseEvent(adjustedPoint, m_lastScreenPoint, PlatformEvent::MouseReleased, 1, LeftButton, TouchScreen);
            m_webPage->handleMouseEvent(mouseEvent);
            m_lastFatFingersResult.reset(); // Reset the fat finger result as its no longer valid when a user's finger is not on the screen.
            if (shouldRequestSpellCheckOptions)
                m_webPage->m_inputHandler->requestSpellingCheckingOptions(spellCheckOptionRequest);
            return true;
        }
    case Platform::TouchPoint::TouchMoved:
        if (m_convertTouchToMouse) {
            PlatformMouseEvent mouseEvent(point.m_pos, m_lastScreenPoint, PlatformEvent::MouseMoved, 1, LeftButton, TouchScreen);
            m_lastScreenPoint = point.m_screenPos;
            if (!m_webPage->handleMouseEvent(mouseEvent)) {
                m_convertTouchToMouse = alwaysEnableMouseConversion;
                return false;
            }
            return true;
        }
        break;
    default:
        break;
    }
    return false;
}