void EventSenderProxy::touchStart() { if (!m_touchActive) { sendTouchEvent(QEvent::TouchBegin); m_touchActive = true; } else sendTouchEvent(QEvent::TouchUpdate); }
void EventSender::touchEnd() { for (int i = 0; i < m_touchPoints.count(); ++i) if (m_touchPoints[i].state() != Qt::TouchPointReleased) { sendTouchEvent(QEvent::TouchUpdate); return; } sendTouchEvent(QEvent::TouchEnd); m_touchActive = false; }
void EventSender::touchStart() { #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) if (!m_touchActive) { sendTouchEvent(QEvent::TouchBegin); m_touchActive = true; } else sendTouchEvent(QEvent::TouchUpdate); #endif }
void EventSender::touchEnd() { #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) for (int i = 0; i < m_touchPoints.count(); ++i) if (m_touchPoints[i].state() != Qt::TouchPointReleased) { sendTouchEvent(QEvent::TouchUpdate); return; } sendTouchEvent(QEvent::TouchEnd); m_touchActive = false; #endif }
bool MiniBrowserApplication::notify(QObject* target, QEvent* event) { // We try to be smart, if we received real touch event, we are probably on a device // with touch screen, and we should not have touch mocking. if (!event->spontaneous() || m_realTouchEventReceived || !m_windowOptions.touchMockingEnabled()) return QGuiApplication::notify(target, event); if (isTouchEvent(event)) { if (m_pendingFakeTouchEventCount) --m_pendingFakeTouchEventCount; else m_realTouchEventReceived = true; return QGuiApplication::notify(target, event); } BrowserWindow* browserWindow = qobject_cast<BrowserWindow*>(target); if (!browserWindow) return QGuiApplication::notify(target, event); m_holdingControl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); // In QML events are propagated through parents. But since the WebView // may consume key events, a shortcut might never reach the top QQuickItem. // Therefore we are checking here for shortcuts. if (event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); if ((keyEvent->key() == Qt::Key_R && keyEvent->modifiers() == Qt::ControlModifier) || keyEvent->key() == Qt::Key_F5) { browserWindow->reload(); return true; } if ((keyEvent->key() == Qt::Key_L && keyEvent->modifiers() == Qt::ControlModifier) || keyEvent->key() == Qt::Key_F6) { browserWindow->focusAddressBar(); return true; } if ((keyEvent->key() == Qt::Key_F && keyEvent->modifiers() == Qt::ControlModifier) || keyEvent->key() == Qt::Key_F3) { browserWindow->toggleFind(); return true; } } if (event->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Control) { foreach (int id, m_heldTouchPoints) if (m_touchPoints.contains(id) && !QGuiApplication::mouseButtons().testFlag(Qt::MouseButton(id))) { m_touchPoints[id].setState(Qt::TouchPointReleased); m_heldTouchPoints.remove(id); } else m_touchPoints[id].setState(Qt::TouchPointStationary); sendTouchEvent(browserWindow, m_heldTouchPoints.isEmpty() ? QEvent::TouchEnd : QEvent::TouchUpdate, static_cast<QKeyEvent*>(event)->timestamp()); }
void EventSenderProxy::touchMove() { sendTouchEvent(QEvent::TouchUpdate); }
void EventSender::touchCancel() { sendTouchEvent(QEvent::TouchCancel); m_touchActive = false; }
void EventSender::touchMove() { #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) sendTouchEvent(QEvent::TouchUpdate); #endif }
void TouchActionTest::runTestOnTree(ContainerNode* root, WebView* webView, TouchActionTrackingWebViewClient& client) { // Find all elements to test the touch-action of in the document. TrackExceptionState es; // Oilpan: see runTouchActionTest() comment why these are persistent // references. Persistent<StaticElementList> elements = root->querySelectorAll("[expected-action]", es); ASSERT_FALSE(es.hadException()); for (unsigned index = 0; index < elements->length(); index++) { Element* element = elements->item(index); element->scrollIntoViewIfNeeded(); std::string failureContext("Test case: "); if (element->hasID()) { failureContext.append(element->getIdAttribute().ascii().data()); } else if (element->firstChild()) { failureContext.append("\""); failureContext.append(element->firstChild() ->textContent(false) .stripWhiteSpace() .ascii() .data()); failureContext.append("\""); } else { failureContext += "<missing ID>"; } // Run each test three times at different positions in the element. // Note that we don't want the bounding box because our tests sometimes have // elements with multiple border boxes with other elements in between. Use // the first border box (which we can easily visualize in a browser for // debugging). Persistent<ClientRectList> rects = element->getClientRects(); ASSERT_GE(rects->length(), 0u) << failureContext; Persistent<ClientRect> r = rects->item(0); FloatRect clientFloatRect = FloatRect(r->left(), r->top(), r->width(), r->height()); IntRect clientRect = enclosedIntRect(clientFloatRect); for (int locIdx = 0; locIdx < 3; locIdx++) { IntPoint framePoint; std::stringstream contextStream; contextStream << failureContext << " ("; switch (locIdx) { case 0: framePoint = clientRect.center(); contextStream << "center"; break; case 1: framePoint = clientRect.location(); contextStream << "top-left"; break; case 2: framePoint = clientRect.maxXMaxYCorner(); framePoint.move(-1, -1); contextStream << "bottom-right"; break; default: FAIL() << "Invalid location index."; } IntPoint windowPoint = root->document().frame()->view()->convertToRootFrame(framePoint); contextStream << "=" << windowPoint.x() << "," << windowPoint.y() << ")."; std::string failureContextPos = contextStream.str(); LocalFrame* mainFrame = static_cast<LocalFrame*>(webView->mainFrame()->toImplBase()->frame()); FrameView* mainFrameView = mainFrame->view(); IntRect visibleRect = windowClipRect(*mainFrameView); ASSERT_TRUE(visibleRect.contains(windowPoint)) << failureContextPos << " Test point not contained in visible area: " << visibleRect.x() << "," << visibleRect.y() << "-" << visibleRect.maxX() << "," << visibleRect.maxY(); // First validate that a hit test at this point will really hit the // element we intended. This is the easiest way for a test to be broken, // but has nothing really to do with touch action. Note that we can't use // WebView's hit test API because it doesn't look into shadow DOM. IntPoint docPoint(mainFrameView->frameToContents(windowPoint)); HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint( docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); ASSERT_EQ(element, result.innerElement()) << "Unexpected hit test result " << failureContextPos << " Got element: \"" << result.innerElement() ->outerHTML() .stripWhiteSpace() .left(80) .ascii() .data() << "\"" << std::endl << "Document render tree:" << std::endl << externalRepresentation(root->document().frame()).utf8().data(); // Now send the touch event and check any touch action result. sendTouchEvent(webView, WebInputEvent::TouchStart, windowPoint); AtomicString expectedAction = element->getAttribute("expected-action"); if (expectedAction == "auto") { // Auto is the default - no action set. EXPECT_EQ(0, client.touchActionSetCount()) << failureContextPos; EXPECT_EQ(WebTouchActionAuto, client.lastTouchAction()) << failureContextPos; } else { // Should have received exactly one touch action. EXPECT_EQ(1, client.touchActionSetCount()) << failureContextPos; if (client.touchActionSetCount()) { if (expectedAction == "none") { EXPECT_EQ(WebTouchActionNone, client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "pan-x") { EXPECT_EQ(WebTouchActionPanX, client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "pan-y") { EXPECT_EQ(WebTouchActionPanY, client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "pan-x-y") { EXPECT_EQ((WebTouchActionPan), client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "manipulation") { EXPECT_EQ((WebTouchActionManipulation), client.lastTouchAction()) << failureContextPos; } else { FAIL() << "Unrecognized expected-action \"" << expectedAction.ascii().data() << "\" " << failureContextPos; } } } // Reset webview touch state. client.reset(); sendTouchEvent(webView, WebInputEvent::TouchCancel, windowPoint); EXPECT_EQ(0, client.touchActionSetCount()); } } }