diff options
author | Alexandru Croitor <alexandru.croitor@theqtcompany.com> | 2016-05-09 10:11:36 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@theqtcompany.com> | 2016-05-26 09:05:10 +0000 |
commit | 292f573f4e86d938a3bde80627637d245a949e56 (patch) | |
tree | db9a74bc68f9d23838498443310a0fa877cb626f /tests/auto | |
parent | 4c305cba0bf7cc021fd355af574b431f0d5a057d (diff) |
Fix event forwarding when activeFocusOnPress is false.
If a QQuickWebEngineView does not have focus, and activeFocusOnPress is
set to false, a user can still partially interact with the view. For
instance hovering the mouse over a link would change the cursor, a link
can be clicked to go to a different page.
Clicking on a text input field would focus the text field, but entering
characters will not be possible, because the view does not have QtQuick
keyboard focus, and clicking does not give the focus (because
activeFocusOnPress is set to false) and this leads to confusing
behavior.
Thus the fix is to make sure no mouse / keyboard events are forwarded
to Chromium if the view has no focus, and activeFocusOnPress is set
to false, in order to maintain a more user-friendly behavior.
Manually forcing the focus via some user-provided method that calls
forceActiveFocus() would allow further proper interaction.
Change-Id: I72c3ff69438972b9a93ee2d415fa1d4b44b86cd9
Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/quick/qquickwebengineview/qquickwebengineview.pro | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp | 108 |
2 files changed, 109 insertions, 1 deletions
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro index 826b47de7..36e74a2a8 100644 --- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro +++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro @@ -1,6 +1,6 @@ include(../tests.pri) exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc -QT_PRIVATE += webengine-private +QT_PRIVATE += webengine-private gui-private HEADERS += ../shared/util.h diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index d39a6df54..7e684a35a 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -22,6 +22,7 @@ #include <QScopedPointer> #include <QtCore/qelapsedtimer.h> +#include <QtGui/qpa/qwindowsysteminterface.h> #include <QtQml/QQmlEngine> #include <QtTest/QtTest> #include <private/qquickwebengineview_p.h> @@ -63,6 +64,7 @@ private Q_SLOTS: void setZoomFactor(); void stopSettingFocusWhenDisabled(); void stopSettingFocusWhenDisabled_data(); + void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled(); private: inline QQuickWebEngineView *newWebEngineView(); @@ -511,5 +513,111 @@ void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled_data() QTest::newRow("disabled view does not get active focus") << false << false; } +class MouseTouchEventRecordingItem : public QQuickItem { +public: + explicit MouseTouchEventRecordingItem(QQuickItem *parent = 0) : + QQuickItem(parent), m_eventCounter(0) { + setFlag(ItemHasContents); + setAcceptedMouseButtons(Qt::AllButtons); + setAcceptHoverEvents(true); + } + + bool event(QEvent *event) Q_DECL_OVERRIDE + { + switch (event->type()) { + case QEvent::TabletPress: + case QEvent::TabletRelease: + case QEvent::TabletMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + ++m_eventCounter; + event->accept(); + return true; + default: + break; + } + return QQuickItem::event(event); + } + + void clearEventCount() + { + m_eventCounter = 0; + } + + int eventCount() + { + return m_eventCounter; + } + +private: + int m_eventCounter; +}; + +void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPressDisabled() +{ + QQuickWebEngineView *view = webEngineView(); + MouseTouchEventRecordingItem item; + item.setParentItem(m_window->contentItem()); + item.setSize(QSizeF(640, 480)); + view->setParentItem(&item); + view->setSize(QSizeF(640, 480)); + m_window->show(); + + // Simulate click and move of mouse, so that last known position in the application + // is updated, thus a mouse move event is not generated when we don't expect it. + QTest::mouseClick(view->window(), Qt::LeftButton); + item.clearEventCount(); + + // First disable view, so it does not receive focus on page load. + view->setEnabled(false); + view->setActiveFocusOnPress(false); + view->loadHtml("<html><head>" + "<script>" + "window.onload = function() { document.getElementById(\"input\").focus(); }" + "</script>" + "<title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + QVERIFY(waitForLoadSucceeded(view)); + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000); + + // Enable the view back so we can try to interact with it. + view->setEnabled(true); + + // Click on the view, to try and set focus. + QTest::mouseClick(view->window(), Qt::LeftButton); + + // View should not have focus after click, because setActiveFocusOnPress is false. + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000); + + // Now test sending various input events, to check that indeed all the input events are not + // forwarded to Chromium, but rather processed and accepted by the view's parent item. + QTest::mousePress(view->window(), Qt::LeftButton); + QTest::mouseRelease(view->window(), Qt::LeftButton); + + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + + 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()); + + // We expect to catch 7 events - click = 2, press + release = 2, touches = 3. + QCOMPARE(item.eventCount(), 7); + + // Manually forcing focus should still be possible. + view->forceActiveFocus(); + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), true, 1000); +} + QTEST_MAIN(tst_QQuickWebEngineView) #include "tst_qquickwebengineview.moc" |