diff options
-rw-r--r-- | src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp | 48 | ||||
-rw-r--r-- | tests/auto/util/util.h | 24 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 51 | ||||
-rw-r--r-- | tests/auto/widgets/touchinput/tst_touchinput.cpp | 48 |
5 files changed, 140 insertions, 45 deletions
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp index 7a9fa86b2..c2f168a99 100644 --- a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp @@ -250,12 +250,14 @@ void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event) void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event) { QQuickItem *parent = parentItem(); - if (event->type() == QEvent::TouchBegin && !m_isPopup - && (parent && parent->property("activeFocusOnPress").toBool())) - forceActiveFocus(); - if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { - event->ignore(); - return; + if (!m_isPopup && parent) { + if (event->type() == QEvent::TouchBegin && parent->property("activeFocusOnPress").toBool()) + forceActiveFocus(); + + if (!parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } } m_client->forwardEvent(event); } diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index 347f370f7..2bfedd707 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -96,6 +96,7 @@ private Q_SLOTS: void setProfile(); void focusChild(); void focusChild_data(); + void htmlSelectPopup(); private: inline QQuickWebEngineView *newWebEngineView(); @@ -105,6 +106,11 @@ private: QString m_testSourceDirPath; QScopedPointer<TestWindow> m_window; QScopedPointer<QQmlComponent> m_component; + + QPointingDevice *touchDevice() { + static auto d = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); + return d.get(); + } }; tst_QQuickWebEngineView::tst_QQuickWebEngineView() @@ -587,9 +593,8 @@ void tst_QQuickWebEngineView::interruptImeTextComposition() QTest::mouseClick(view->window(), Qt::LeftButton, {}, textInputCenter); } else if (eventType == "Touch") { QPoint textInputCenter = elementCenter(view, QStringLiteral("input2")); - QPointingDevice *touchDevice = QTest::createTouchDevice(); - QTest::touchEvent(view->window(), touchDevice).press(0, textInputCenter, view->window()); - QTest::touchEvent(view->window(), touchDevice).release(0, textInputCenter, view->window()); + QTest::touchEvent(view->window(), touchDevice()).press(0, textInputCenter, view->window()); + QTest::touchEvent(view->window(), touchDevice()).release(0, textInputCenter, view->window()); } QTRY_COMPARE(evaluateJavaScriptSync(view, "document.activeElement.id").toString(), QStringLiteral("input2")); #ifndef Q_OS_WIN @@ -987,11 +992,9 @@ void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPress QTest::mousePress(view->window(), Qt::LeftButton); QTest::mouseRelease(view->window(), Qt::LeftButton); - QPointingDevice *device = QTest::createTouchDevice(); - - QTest::touchEvent(view->window(), device).press(0, QPoint(0,0), view->window()); - QTest::touchEvent(view->window(), device).move(0, QPoint(1, 1), view->window()); - QTest::touchEvent(view->window(), device).release(0, QPoint(1, 1), view->window()); + QTest::touchEvent(view->window(), touchDevice()).press(0, QPoint(0,0), view->window()); + QTest::touchEvent(view->window(), touchDevice()).move(0, QPoint(1, 1), view->window()); + QTest::touchEvent(view->window(), touchDevice()).release(0, QPoint(1, 1), view->window()); // We expect to catch 7 events - click = 2, press + release = 2, touches = 3. QCOMPARE(item.eventCount(), 7); @@ -1170,6 +1173,8 @@ void tst_QQuickWebEngineView::setProfile() { QVERIFY(waitForLoadSucceeded(webEngineView())); QCOMPARE(loadSpy.size(), 4); QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(); + auto oldProfile = webEngineView()->profile(); + auto sc = qScopeGuard([&] () { webEngineView()->setProfile(oldProfile); delete profile; }); webEngineView()->setProfile(profile); QTRY_COMPARE(webEngineView()->url() ,urlFromTestPath("html/basic_page2.html")); } @@ -1237,6 +1242,33 @@ void tst_QQuickWebEngineView::focusChild() QCOMPARE(traverseToWebDocumentAccessibleInterface(iface)->child(0)->child(0), iface->focusChild()); } +void tst_QQuickWebEngineView::htmlSelectPopup() +{ + m_window->show(); + QQuickWebEngineView &view = *webEngineView(); + view.settings()->setFocusOnNavigationEnabled(true); + view.setSize(QSizeF(640, 480)); + view.loadHtml("<html><body>" + "<select id='select' onchange='console.log(\"option changed to: \" + this.value)'>" + "<option value='O1'>O1</option><option value='O2'>O2</option><option value='O3'>O3</option></select>" + "</body></html>"); + QVERIFY(waitForLoadSucceeded(&view)); + + auto makeTouch = [this] (QWindow *w, const QPoint &p) { + QTest::touchEvent(w, touchDevice()).press(1, p); + QTest::touchEvent(w, touchDevice()).release(1, p); + }; + + makeTouch(view.window(), elementCenter(&view, "select")); + QPointer<QQuickWindow> popup; + QTRY_VERIFY((popup = m_window->findChild<QQuickWindow *>())); + QCOMPARE(activeElementId(&view), QStringLiteral("select")); + + makeTouch(popup, QPoint(popup->width() / 2, popup->height() / 2)); + QTRY_VERIFY(!popup); + QCOMPARE(evaluateJavaScriptSync(&view, "document.getElementById('select').value").toString(), QStringLiteral("O2")); +} + static QByteArrayList params = QByteArrayList() << "--force-renderer-accessibility"; diff --git a/tests/auto/util/util.h b/tests/auto/util/util.h index a624a978f..232d26d8f 100644 --- a/tests/auto/util/util.h +++ b/tests/auto/util/util.h @@ -175,31 +175,13 @@ static inline bool loadSync(QWebEnginePage *page, const QUrl &url, bool ok = tru return (!spy.empty() || spy.wait(20000)) && (spy.front().value(0).toBool() == ok); } -static inline QPoint elementCenter(QWebEnginePage *page, const QString &id) -{ - const QString jsCode( - "(function(){" - " var elem = document.getElementById('" + id + "');" - " var rect = elem.getBoundingClientRect();" - " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];" - "})()"); - QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList(); - - if (rectList.count() != 2) { - qWarning("elementCenter failed."); - return QPoint(); - } - - return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt()); -} - static inline QRect elementGeometry(QWebEnginePage *page, const QString &id) { const QString jsCode( "(function() {" " var elem = document.getElementById('" + id + "');" " var rect = elem.getBoundingClientRect();" - " return [rect.left, rect.top, rect.right, rect.bottom];" + " return [rect.left, rect.top, rect.width, rect.height];" "})()"); QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList(); @@ -211,5 +193,9 @@ static inline QRect elementGeometry(QWebEnginePage *page, const QString &id) return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt()); } +static inline QPoint elementCenter(QWebEnginePage *page, const QString &id) +{ + return elementGeometry(page, id).center(); +} #define W_QSKIP(a, b) QSKIP(a) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 90ec9eb22..9c730e45d 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -96,7 +96,9 @@ public Q_SLOTS: private Q_SLOTS: void initTestCase(); void cleanupTestCase(); + void comboBoxPopupPositionAfterMove_data(); void comboBoxPopupPositionAfterMove(); + void comboBoxPopupPositionAfterChildMove_data(); void comboBoxPopupPositionAfterChildMove(); void acceptNavigationRequest(); void acceptNavigationRequestNavigationType(); @@ -262,6 +264,18 @@ private: + QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss")); return tmpd; } + + QScopedPointer<QPointingDevice> s_touchDevice; + void makeClick(QWindow *window, bool withTouch = false, const QPoint &p = QPoint()) { + if (!withTouch) { + QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), p); + } else { + if (!s_touchDevice) + s_touchDevice.reset(QTest::createTouchDevice()); + QTest::touchEvent(window, s_touchDevice.get()).press(1, p); + QTest::touchEvent(window, s_touchDevice.get()).release(1, p); + } + }; }; tst_QWebEnginePage::tst_QWebEnginePage() @@ -1298,6 +1312,13 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows) return nullptr; } +void tst_QWebEnginePage::comboBoxPopupPositionAfterMove_data() +{ + QTest::addColumn<bool>("withTouch"); + QTest::addRow("mouse") << false; + QTest::addRow("touch") << true; +} + void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() { QWebEngineView view; @@ -1311,9 +1332,10 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() "</select></body></html>")); QTRY_COMPARE(loadSpy.count(), 1); const auto oldTlws = QGuiApplication::topLevelWindows(); + + QFETCH(bool, withTouch); QWindow *window = view.windowHandle(); - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), - elementCenter(view.page(), "foo")); + makeClick(window, withTouch, elementCenter(view.page(), "foo")); QWindow *popup = nullptr; QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); @@ -1322,7 +1344,7 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() QPoint popupPos = popup->position(); // Close the popup by clicking somewhere into the page. - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1)); + makeClick(window, withTouch, QPoint(1, 1)); QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup)); auto jsViewPosition = [&view]() { @@ -1341,16 +1363,22 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() const QPoint offset(12, 13); view.move(view.pos() + offset); QTRY_COMPARE(jsViewPosition(), view.pos()); - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), - elementCenter(view.page(), "foo")); + makeClick(window, withTouch, elementCenter(view.page(), "foo")); QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup)); QTRY_VERIFY(!popup->position().isNull()); QCOMPARE(popupPos + offset, popup->position()); - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1)); + makeClick(window, withTouch, QPoint(1, 1)); QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup)); } +void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove_data() +{ + QTest::addColumn<bool>("withTouch"); + QTest::addRow("mouse") << false; + QTest::addRow("touch") << true; +} + void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() { QWidget mainWidget; @@ -1373,9 +1401,10 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() "</select></body></html>")); QTRY_COMPARE(loadSpy.count(), 1); const auto oldTlws = QGuiApplication::topLevelWindows(); + + QFETCH(bool, withTouch); QWindow *window = view.window()->windowHandle(); - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), - view.mapTo(view.window(), elementCenter(view.page(), "foo"))); + makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo"))); QWindow *popup = nullptr; QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); @@ -1384,8 +1413,7 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() QPoint popupPos = popup->position(); // Close the popup by clicking somewhere into the page. - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), - view.mapTo(view.window(), QPoint(1, 1))); + makeClick(window, withTouch, view.mapTo(view.window(), QPoint(1, 1))); QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup)); int originalViewWidth = view.size().width(); @@ -1400,8 +1428,7 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() spacer.setMinimumWidth(spacer.size().width() + offset); QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset); - QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), - view.mapTo(view.window(), elementCenter(view.page(), "foo"))); + makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo"))); QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); QTRY_VERIFY(!popup->position().isNull()); QCOMPARE(popupPos + QPoint(50, 0), popup->position()); diff --git a/tests/auto/widgets/touchinput/tst_touchinput.cpp b/tests/auto/widgets/touchinput/tst_touchinput.cpp index d60fd1d7b..957f3e74c 100644 --- a/tests/auto/widgets/touchinput/tst_touchinput.cpp +++ b/tests/auto/widgets/touchinput/tst_touchinput.cpp @@ -37,6 +37,12 @@ static QPointingDevice* s_touchDevice = nullptr; +struct Page : QWebEnginePage +{ + QStringList alerts; + void javaScriptAlert(const QUrl &/*origin*/, const QString &msg) override { alerts.append(msg); } +}; + class TouchInputTest : public QObject { Q_OBJECT @@ -54,14 +60,23 @@ private Q_SLOTS: void pinchZoom_data(); void pinchZoom(); void complexSequence(); + void buttonClickHandler(); + void htmlSelectPopup(); private: + Page page; QWebEngineView view; QSignalSpy loadSpy { &view, &QWebEngineView::loadFinished }; QPoint notextCenter, textCenter, inputCenter; QString activeElement() { return evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(); } + void makeTouch(QWindow *w, const QPoint &p) { + QTest::touchEvent(w, s_touchDevice).press(1, p); + QTest::touchEvent(w, s_touchDevice).release(1, p); + } + void makeTouch(const QPoint &p) { makeTouch(view.windowHandle(), p); } + void gestureScroll(bool down) { auto target = view.focusProxy(); QPoint p(target->width() / 2, target->height() / 4 * (down ? 3 : 1)); @@ -131,6 +146,7 @@ void TouchInputTest::initTestCase() { s_touchDevice = QTest::createTouchDevice(); + view.setPage(&page); view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); view.show(); view.resize(480, 320); @@ -140,6 +156,9 @@ void TouchInputTest::initTestCase() "<p id='text' style='width: 150px;'>The Qt Company</p>" "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>" "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>" + "<button id='btn' type='button' onclick='alert(\"button clicked!\")'>Click Me!</button>" + "<select id='select' onchange='alert(\"option changed to: \" + this.value)'>" + "<option value='O1'>O1</option><option value='O2'>O2</option><option value='O3'>O3</option></select>" "<table style='width: 100%; padding: 15px; text-align: center;'>" "<tr><td>BEFORE</td><td><div class='rect' style='background-color: #00f;'></div></td><td>AFTER</td></tr>" "<tr><td>BEFORE</td><td><div class='rect' style='background-color: #0f0;'></div></td><td>AFTER</td></tr>" @@ -163,6 +182,7 @@ void TouchInputTest::cleanup() evaluateJavaScriptSync(view.page(), "window.scrollTo(0, 0)"); QTRY_COMPARE(getScrollPosition(), 0); QTRY_COMPARE(pageScrollPosition(), 0); + page.alerts.clear(); } void TouchInputTest::touchTap() @@ -345,5 +365,33 @@ void TouchInputTest::complexSequence() } } +void TouchInputTest::buttonClickHandler() +{ + auto buttonCenter = elementGeometry(view.page(), "btn").center(); + makeTouch(buttonCenter); + QTRY_VERIFY(!page.alerts.isEmpty()); + QCOMPARE(page.alerts.first(), "button clicked!"); + QCOMPARE(page.alerts.size(), 1); + QEXPECT_FAIL("", "Shouldn't trigger twice due to synthesized mouse events for touch", Continue); + QTRY_VERIFY_WITH_TIMEOUT(page.alerts.size() == 2, 500); +} + +void TouchInputTest::htmlSelectPopup() +{ + auto selectRect = elementGeometry(view.page(), "select"); + makeTouch(selectRect.center()); + QTRY_VERIFY(QApplication::activePopupWidget()); + QCOMPARE(activeElement(), QStringLiteral("select")); + + auto popup = QApplication::activePopupWidget(); + makeTouch(popup->windowHandle(), QPoint(popup->width() / 2, popup->height() / 2)); + QTRY_VERIFY(!QApplication::activePopupWidget()); + + QTRY_VERIFY(!page.alerts.isEmpty()); + QCOMPARE(page.alerts.first(), "option changed to: O2"); + QEXPECT_FAIL("", "Shouldn't trigger twice due to synthesized mouse events for touch", Continue); + QTRY_VERIFY_WITH_TIMEOUT(page.alerts.size() == 2, 500); +} + QTEST_MAIN(TouchInputTest) #include "tst_touchinput.moc" |