// Copyright (C) 2017 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace QQuickVisualTestUtils; using namespace QQuickControlsTestUtils; class tst_focus : public QQmlDataTest { Q_OBJECT public: tst_focus(); private slots: void init() override; void initTestCase() override; void navigation_data(); void navigation(); void policy_data(); void policy(); void reason(); void visualFocus(); void scope_data(); void scope(); }; tst_focus::tst_focus() : QQmlDataTest(QT_QMLTEST_DATADIR) { } void tst_focus::init() { QTest::failOnWarning(QRegularExpression(".?")); } void tst_focus::initTestCase() { SKIP_IF_NO_WINDOW_ACTIVATION; QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows); QQuickStyle::setStyle("Basic"); QQmlDataTest::initTestCase(); } void tst_focus::navigation_data() { QTest::addColumn("key"); QTest::addColumn("testFile"); QTest::addColumn("behavior"); QTest::addColumn("order"); QTest::newRow("tab-all-controls") << Qt::Key_Tab << QString("activeFocusOnTab.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "rangeslider.first" << "rangeslider.second" << "slider" << "spinbox" << "switch" << "tabbutton1" << "tabbutton2" << "textfield" << "toolbutton" << "textarea" << "button1"); QTest::newRow("backtab-all-controls") << Qt::Key_Backtab << QString("activeFocusOnTab.qml") << Qt::TabFocusAllControls << (QStringList() << "textarea" << "toolbutton" << "textfield" << "tabbutton2" << "tabbutton1" << "switch" << "spinbox" << "slider" << "rangeslider.second" << "rangeslider.first" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); QTest::newRow("tab-text-controls") << Qt::Key_Tab << QString("activeFocusOnTab.qml") << Qt::TabFocusTextControls << (QStringList() << "spinbox" << "textfield" << "textarea"); QTest::newRow("backtab-text-controls") << Qt::Key_Backtab << QString("activeFocusOnTab.qml") << Qt::TabFocusTextControls << (QStringList() << "textarea" << "textfield" << "spinbox"); QTest::newRow("key-up") << Qt::Key_Up << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "textarea" << "toolbutton" << "textfield" << "tabbutton2" << "tabbutton1" << "switch" << "slider" << "rangeslider.first" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); QTest::newRow("key-down") << Qt::Key_Down << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "rangeslider.first" << "slider" << "switch" << "tabbutton1" << "tabbutton2" << "textfield" << "toolbutton" << "textarea" << "button1"); QTest::newRow("key-left") << Qt::Key_Left << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "toolbutton" << "tabbutton2" << "tabbutton1" << "switch" << "spinbox" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); QTest::newRow("key-right") << Qt::Key_Right << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "spinbox" << "switch" << "tabbutton1" << "tabbutton2" << "toolbutton" << "button1"); } void tst_focus::navigation() { QFETCH(Qt::Key, key); QFETCH(QString, testFile); QFETCH(Qt::TabFocusBehavior, behavior); QFETCH(QStringList, order); QGuiApplication::styleHints()->setTabFocusBehavior(behavior); QQuickView view; view.contentItem()->setObjectName("contentItem"); view.setSource(testFileUrl(testFile)); view.show(); view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); QVERIFY(QGuiApplication::focusWindow() == &view); for (const QString &name : std::as_const(order)) { QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier); QGuiApplication::sendEvent(&view, &event); QVERIFY(event.isAccepted()); QQuickItem *item = findItem(view.rootObject(), name); QVERIFY2(item, qPrintable(name)); QVERIFY2(item->hasActiveFocus(), qPrintable(QString("expected: '%1', actual: '%2'").arg(name).arg(view.activeFocusItem() ? view.activeFocusItem()->objectName() : "null"))); } QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); } void tst_focus::policy_data() { QTest::addColumn("name"); QTest::newRow("Control") << "Control"; QTest::newRow("ComboBox") << "ComboBox"; QTest::newRow("Button") << "Button"; QTest::newRow("Slider") << "Slider"; QTest::newRow("ScrollBar") << "ScrollBar"; } void tst_focus::policy() { QFETCH(QString, name); QQmlEngine engine; QScopedPointer device(QTest::createTouchDevice()); QQmlComponent component(&engine); component.setData(QString("import QtQuick.Controls; ApplicationWindow { width: 100; height: 100; %1 { anchors.fill: parent } }").arg(name).toUtf8(), QUrl()); QScopedPointer window(qobject_cast(component.create())); QVERIFY(window); QQuickControl *control = qobject_cast(window->contentItem()->childItems().first()); QVERIFY(control); QVERIFY(!control->hasActiveFocus()); QVERIFY(!control->hasVisualFocus()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); control->setFocusPolicy(Qt::NoFocus); QCOMPARE(control->focusPolicy(), Qt::NoFocus); // Qt::TabFocus vs. QQuickItem::activeFocusOnTab control->setActiveFocusOnTab(true); QCOMPARE(control->focusPolicy(), Qt::TabFocus); control->setActiveFocusOnTab(false); QCOMPARE(control->focusPolicy(), Qt::NoFocus); control->setFocusPolicy(Qt::TabFocus); QCOMPARE(control->focusPolicy(), Qt::TabFocus); QCOMPARE(control->activeFocusOnTab(), true); // Qt::TabFocus QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusAllControls); QTest::keyClick(window.data(), Qt::Key_Tab); QVERIFY_ACTIVE_FOCUS(control); VERIFY_VISUAL_FOCUS(control); QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); // reset control->setFocus(false); QVERIFY(!control->hasActiveFocus()); // Qt::ClickFocus (mouse) control->setFocusPolicy(Qt::NoFocus); control->setAcceptedMouseButtons(Qt::LeftButton); QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); QVERIFY(!control->hasActiveFocus()); QVERIFY(!control->hasVisualFocus()); control->setFocusPolicy(Qt::ClickFocus); QCOMPARE(control->focusPolicy(), Qt::ClickFocus); QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); QVERIFY_ACTIVE_FOCUS(control); QVERIFY(!control->hasVisualFocus()); // reset control->setFocus(false); QVERIFY(!control->hasActiveFocus()); // Qt::ClickFocus (touch) control->setFocusPolicy(Qt::NoFocus); QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); QVERIFY(!control->hasActiveFocus()); QVERIFY(!control->hasVisualFocus()); control->setFocusPolicy(Qt::ClickFocus); QCOMPARE(control->focusPolicy(), Qt::ClickFocus); QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); QVERIFY_ACTIVE_FOCUS(control); QVERIFY(!control->hasVisualFocus()); // reset control->setFocus(false); QVERIFY(!control->hasActiveFocus()); #if QT_CONFIG(wheelevent) // Qt::WheelFocus QWheelEvent wheelEvent(QPointF(control->width() / 2, control->height() / 2), QPointF(), QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QGuiApplication::sendEvent(control, &wheelEvent); QVERIFY(!control->hasActiveFocus()); QVERIFY(!control->hasVisualFocus()); control->setFocusPolicy(Qt::WheelFocus); QCOMPARE(control->focusPolicy(), Qt::WheelFocus); QGuiApplication::sendEvent(control, &wheelEvent); QVERIFY_ACTIVE_FOCUS(control); QVERIFY(!control->hasVisualFocus()); #endif } void tst_focus::reason() { QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusAllControls); auto resetTabFocusBehavior = qScopeGuard([]{ QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); }); QQuickView view; view.setSource(testFileUrl("focusReason.qml")); view.show(); view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); QQuickControl *control = view.findChild("control"); QQuickControl *combobox = view.findChild("combobox"); QQuickControl *editcombo = view.findChild("editcombo"); QQuickControl *spinbox = view.findChild("spinbox"); QQuickControl *customText = view.findChild("customText"); QQuickControl *customItem = view.findChild("customItem"); // not a QQuickControl subclass QQuickTextField *textfield = view.findChild("textfield"); // helper for clicking into a control const auto itemCenter = [](const QQuickItem *item) -> QPoint { return item->mapToScene(item->clipRect().center()).toPoint(); }; QVERIFY(control); QVERIFY(combobox); QVERIFY(editcombo); QVERIFY(spinbox); QVERIFY(textfield); QVERIFY(customText); QVERIFY(customItem); // setting focusPolicy to Strong/WheelFocus doesn't implicitly turn on event delivery customText->setAcceptedMouseButtons(Qt::LeftButton); customItem->setAcceptedMouseButtons(Qt::LeftButton); customItem->setWheelEnabled(true); // window activation -> ActiveWindowFocusReason QVERIFY(control->hasFocus()); QVERIFY_ACTIVE_FOCUS(control); if (control->focusReason() != Qt::ActiveWindowFocusReason && QStringList{"windows", "offscreen"}.contains(QGuiApplication::platformName())) { QEXPECT_FAIL("", "On Windows and offscreen platforms, window activation does not set focus reason", Continue); } QCOMPARE(control->focusReason(), Qt::ActiveWindowFocusReason); QSignalSpy controlSpy(control, SIGNAL(focusReasonChanged())); QSignalSpy textfieldSpy(textfield, SIGNAL(focusReasonChanged())); QSignalSpy customItemSpy(customItem, SIGNAL(focusReasonChanged())); int controlSpyCount = 0, textfieldSpyCount = 0, customItemSpyCount = 0; QVERIFY(!controlSpy.count()); QVERIFY(!textfieldSpy.count()); QVERIFY(!customItemSpy.count()); // test setter/getter control->setFocus(false, Qt::MouseFocusReason); QCOMPARE(control->focusReason(), Qt::MouseFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); control->setFocus(true, Qt::TabFocusReason); QCOMPARE(control->focusReason(), Qt::TabFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); control->setFocus(false, Qt::BacktabFocusReason); QCOMPARE(control->focusReason(), Qt::BacktabFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); control->forceActiveFocus(Qt::ShortcutFocusReason); QCOMPARE(control->focusReason(), Qt::ShortcutFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); control->setFocusReason(Qt::PopupFocusReason); QCOMPARE(control->focusReason(), Qt::PopupFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); // programmatic focus changes combobox->setFocus(true, Qt::OtherFocusReason); QCOMPARE(control->focusReason(), Qt::OtherFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); QVERIFY(combobox->hasFocus()); QVERIFY_ACTIVE_FOCUS(combobox); QCOMPARE(combobox->focusReason(), Qt::OtherFocusReason); // tab focus -> TabFocusReason QTest::keyClick(&view, Qt::Key_Tab); QVERIFY(editcombo->hasFocus()); QVERIFY_ACTIVE_FOCUS(editcombo); QCOMPARE(qApp->focusObject(), editcombo->contentItem()); QCOMPARE(combobox->focusReason(), Qt::TabFocusReason); QCOMPARE(editcombo->focusReason(), Qt::TabFocusReason); editcombo->setFocusReason(Qt::NoFocusReason); // reset so that we can verify that focusOut sets it QTest::keyClick(&view, Qt::Key_Tab); QVERIFY(spinbox->hasFocus()); QVERIFY_ACTIVE_FOCUS(spinbox); QCOMPARE(qApp->focusObject(), spinbox->contentItem()); QCOMPARE(editcombo->focusReason(), Qt::TabFocusReason); QCOMPARE(spinbox->focusReason(), Qt::TabFocusReason); spinbox->setFocusReason(Qt::NoFocusReason); QTest::keyClick(&view, Qt::Key_Tab); QVERIFY(customText->hasFocus()); QVERIFY_ACTIVE_FOCUS(customText); QCOMPARE(qApp->focusObject(), customText); QCOMPARE(spinbox->focusReason(), Qt::TabFocusReason); QCOMPARE(customText->focusReason(), Qt::TabFocusReason); customText->setFocusReason(Qt::NoFocusReason); QTest::keyClick(&view, Qt::Key_Tab); QCOMPARE(qApp->focusObject(), customItem); QVERIFY(customItem->hasFocus()); QVERIFY_ACTIVE_FOCUS(customItem); QCOMPARE(customText->focusReason(), Qt::TabFocusReason); QCOMPARE(customItem->focusReason(), Qt::TabFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); customItem->setFocusReason(Qt::NoFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); QTest::keyClick(&view, Qt::Key_Tab); QVERIFY(textfield->hasFocus()); QVERIFY_ACTIVE_FOCUS(textfield); QCOMPARE(qApp->focusObject(), textfield); QCOMPARE(customItem->focusReason(), Qt::TabFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); QCOMPARE(textfieldSpy.count(), ++textfieldSpyCount); QTest::keyClick(&view, Qt::Key_Tab); QVERIFY(control->hasFocus()); QVERIFY_ACTIVE_FOCUS(control); QCOMPARE(control->focusReason(), Qt::TabFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); // backtab -> BacktabFocusReason QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(textfield->hasFocus()); QCOMPARE(control->focusReason(), Qt::BacktabFocusReason); QCOMPARE(controlSpy.count(), ++controlSpyCount); QCOMPARE(textfieldSpy.count(), ++textfieldSpyCount); QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(customItem->hasFocus()); QCOMPARE(customItem->focusReason(), Qt::BacktabFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(customText->hasFocus()); QCOMPARE(customText->focusReason(), Qt::BacktabFocusReason); QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(spinbox->hasFocus()); QCOMPARE(spinbox->focusReason(), Qt::BacktabFocusReason); QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(editcombo->hasFocus()); QCOMPARE(editcombo->focusReason(), Qt::BacktabFocusReason); QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); QVERIFY(combobox->hasFocus()); QCOMPARE(combobox->focusReason(), Qt::BacktabFocusReason); // click focus -> MouseFocusReason QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(editcombo)); QTRY_VERIFY(editcombo->hasFocus()); QVERIFY(editcombo->contentItem()->hasFocus()); QVERIFY_ACTIVE_FOCUS(editcombo); QVERIFY_ACTIVE_FOCUS(editcombo->contentItem()); QCOMPARE(editcombo->focusReason(), Qt::MouseFocusReason); editcombo->setFocusReason(Qt::NoFocusReason); QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(combobox)); // opens popup QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(combobox)); // closes popup QVERIFY(combobox->hasFocus()); QVERIFY_ACTIVE_FOCUS(combobox); QCOMPARE(editcombo->focusReason(), Qt::MouseFocusReason); QCOMPARE(combobox->focusReason(), Qt::MouseFocusReason); combobox->setFocusReason(Qt::NoFocusReason); QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(spinbox)); QVERIFY(spinbox->hasFocus()); QVERIFY_ACTIVE_FOCUS(spinbox); QCOMPARE(combobox->focusReason(), Qt::MouseFocusReason); QCOMPARE(spinbox->focusReason(), Qt::MouseFocusReason); spinbox->setFocusReason(Qt::NoFocusReason); QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(customText)); QTRY_VERIFY2(customText->contentItem()->hasFocus(), qPrintable(qApp->focusObject()->objectName())); QVERIFY_ACTIVE_FOCUS(customText->contentItem()); QCOMPARE(spinbox->focusReason(), Qt::MouseFocusReason); QCOMPARE(customText->focusReason(), Qt::MouseFocusReason); customText->setFocusReason(Qt::NoFocusReason); QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(customItem)); QVERIFY(customItem->hasFocus()); QVERIFY_ACTIVE_FOCUS(customItem); QCOMPARE(customText->focusReason(), Qt::MouseFocusReason); QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); customItem->setFocusReason(Qt::NoFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(textfield)); QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); customItem->setFocusReason(Qt::NoFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); customText->setFocusReason(Qt::NoFocusReason); #if QT_CONFIG(wheelevent) // Wheel focus -> MouseFocusReason QWheelEvent wheelEvent(QPointF(customItem->width() / 2, customItem->height() / 2), QPointF(), QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QGuiApplication::sendEvent(customItem, &wheelEvent); QVERIFY_ACTIVE_FOCUS(customItem); QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); // Popup opens -> PopupFocusReason QTest::mouseClick(&view, Qt::RightButton, {}, itemCenter(control)); QTRY_VERIFY(!customItem->hasActiveFocus()); QCOMPARE(customItem->focusReason(), Qt::PopupFocusReason); QCOMPARE(customItemSpy.count(),++customItemSpyCount); QTest::keyClick(&view, Qt::Key_Escape); // close the popup #endif } void tst_focus::visualFocus() { QQuickView view; view.setSource(testFileUrl("visualFocus.qml")); view.show(); view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); QQuickItem *column = view.rootObject(); QVERIFY(column); QCOMPARE(column->childItems().size(), 2); QQuickControl *button = qobject_cast(column->childItems().first()); QVERIFY(button); QQuickItem *textfield = column->childItems().last(); QVERIFY(textfield); button->forceActiveFocus(Qt::TabFocusReason); QVERIFY_ACTIVE_FOCUS(button); VERIFY_VISUAL_FOCUS(button); QVERIFY(button->property("showFocus").toBool()); QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, QPoint(textfield->x() + textfield->width() / 2, textfield->y() + textfield->height() / 2)); QVERIFY(!button->hasActiveFocus()); QVERIFY(!button->hasVisualFocus()); QVERIFY(!button->property("showFocus").toBool()); } void tst_focus::scope_data() { QTest::addColumn("name"); QTest::newRow("Frame") << "Frame"; QTest::newRow("GroupBox") << "Frame"; QTest::newRow("Page") << "Page"; QTest::newRow("Pane") << "Pane"; QTest::newRow("StackView") << "StackView"; } void tst_focus::scope() { QFETCH(QString, name); QQmlEngine engine; QQmlComponent component(&engine); component.setData(QString("import QtQuick; import QtQuick.Controls; ApplicationWindow { property alias child: child; width: 100; height: 100; %1 { anchors.fill: parent; Item { id: child; width: 10; height: 10 } } }").arg(name).toUtf8(), QUrl()); QScopedPointer device(QTest::createTouchDevice()); QScopedPointer window(qobject_cast(component.create())); QVERIFY2(window, qPrintable(component.errorString())); QQuickControl *control = qobject_cast(window->contentItem()->childItems().first()); QVERIFY(control); control->setFocusPolicy(Qt::WheelFocus); control->setAcceptedMouseButtons(Qt::LeftButton); QQuickItem *child = window->property("child").value(); QVERIFY(child); window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window.data())); child->forceActiveFocus(); QVERIFY_ACTIVE_FOCUS(child); QVERIFY_ACTIVE_FOCUS(control); // Qt::ClickFocus (mouse) QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); QVERIFY(!child->hasActiveFocus()); QVERIFY_ACTIVE_FOCUS(control); // reset child->forceActiveFocus(); QVERIFY_ACTIVE_FOCUS(child); QVERIFY_ACTIVE_FOCUS(control); // Qt::ClickFocus (touch) QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); QVERIFY(!child->hasActiveFocus()); QVERIFY_ACTIVE_FOCUS(control); // reset child->forceActiveFocus(); QVERIFY_ACTIVE_FOCUS(child); QVERIFY_ACTIVE_FOCUS(control); #if QT_CONFIG(wheelevent) // Qt::WheelFocus QWheelEvent wheelEvent(QPointF(control->width() / 2, control->height() / 2), QPointF(), QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QGuiApplication::sendEvent(control, &wheelEvent); QVERIFY(!child->hasActiveFocus()); QVERIFY_ACTIVE_FOCUS(control); #endif } QTEST_MAIN(tst_focus) #include "tst_focus.moc"