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; }
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; }