From 9334feb682db6e6e35bc98dce377a091eb640438 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Fri, 22 Apr 2022 14:06:39 +0200 Subject: Fix touch input for html's popup in quick impl Ammends 292f573f4e. Now that touch events are forwarded to popup delegate also instead of synthesized mouse events, the bug with touch event being ignored became present. Also extend testing of touch events for html popups. Task-number: QTBUG-79254 Fixes: QTBUG-103217 Pick-to: 6.2 6.3 Change-Id: I097a6617493355c7603fef8eb41025e299a6e809 Reviewed-by: Shawn Rutledge Reviewed-by: Michal Klocek --- .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 51 +++++++++++++++++----- tests/auto/widgets/touchinput/tst_touchinput.cpp | 48 ++++++++++++++++++++ 2 files changed, 87 insertions(+), 12 deletions(-) (limited to 'tests/auto/widgets') 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 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("withTouch"); + QTest::addRow("mouse") << false; + QTest::addRow("touch") << true; +} + void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() { QWebEngineView view; @@ -1311,9 +1332,10 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() "")); 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("withTouch"); + QTest::addRow("mouse") << false; + QTest::addRow("touch") << true; +} + void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() { QWidget mainWidget; @@ -1373,9 +1401,10 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() "")); 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() "

The Qt Company

" "
" "
" + "" + "" "" "" "" @@ -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" -- cgit v1.2.3
BEFORE
AFTER
BEFORE
AFTER