aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp')
-rw-r--r--tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp169
1 files changed, 136 insertions, 33 deletions
diff --git a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
index 9806eff7c3..12707998d7 100644
--- a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
+++ b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp
@@ -33,6 +33,8 @@
#include <QtGui/qkeysequence.h>
#endif
#include <QtGui/qstylehints.h>
+#include <QtGui/qpa/qplatformintegration.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlcontext.h>
@@ -74,7 +76,9 @@ private slots:
void menuSeparator();
void repeater();
void order();
+#if QT_CONFIG(cursor)
void popup();
+#endif
void actions();
#if QT_CONFIG(shortcut)
void actionShortcuts();
@@ -103,6 +107,11 @@ private slots:
void menuItemWidthAfterImplicitWidthChanged();
void menuItemWidthAfterRetranslate();
void giveMenuItemFocusOnButtonPress();
+ void customMenuCullItems();
+ void customMenuUseRepeaterAsTheContentItem();
+
+private:
+ static bool hasWindowActivation();
};
tst_QQuickMenu::tst_QQuickMenu()
@@ -110,6 +119,11 @@ tst_QQuickMenu::tst_QQuickMenu()
{
}
+bool tst_QQuickMenu::hasWindowActivation()
+{
+ return (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation));
+}
+
void tst_QQuickMenu::defaults()
{
QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
@@ -153,6 +167,9 @@ void tst_QQuickMenu::count()
void tst_QQuickMenu::mouse()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
QSKIP("Mouse hovering not functional on offscreen/minimal platforms");
@@ -183,14 +200,14 @@ void tst_QQuickMenu::mouse()
// Ensure that presses cause the current index to change,
// so that the highlight acts as a way of illustrating press state.
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier,
- QPoint(menu->leftPadding() + firstItem->width() / 2, menu->topPadding() + firstItem->height() / 2));
+ QPoint(menu->x() + menu->leftPadding() + firstItem->width() / 2, menu->y() + menu->topPadding() + firstItem->height() / 2));
QVERIFY(firstItem->hasActiveFocus());
QCOMPARE(menu->currentIndex(), 0);
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0));
QVERIFY(menu->isVisible());
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier,
- QPoint(menu->leftPadding() + firstItem->width() / 2, menu->topPadding() + firstItem->height() / 2));
+ QPoint(menu->x() + menu->leftPadding() + firstItem->width() / 2, menu->y() + menu->topPadding() + firstItem->height() / 2));
QCOMPARE(clickedSpy.count(), 1);
QCOMPARE(triggeredSpy.count(), 1);
QTRY_COMPARE(visibleSpy.count(), 1);
@@ -232,8 +249,8 @@ void tst_QQuickMenu::mouse()
if (!hoverItem || !hoverItem->isVisible() || hoverItem == prevHoverItem)
continue;
QTest::mouseMove(window, QPoint(
- menu->leftPadding() + hoverItem->x() + hoverItem->width() / 2,
- menu->topPadding() + hoverItem->y() + hoverItem->height() / 2));
+ menu->x() + menu->leftPadding() + hoverItem->x() + hoverItem->width() / 2,
+ menu->y() + menu->topPadding() + hoverItem->y() + hoverItem->height() / 2));
QTRY_VERIFY(hoverItem->property("highlighted").toBool());
if (prevHoverItem)
QVERIFY(!prevHoverItem->property("highlighted").toBool());
@@ -265,7 +282,7 @@ void tst_QQuickMenu::pressAndHold()
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
QVERIFY(menu);
@@ -282,6 +299,9 @@ void tst_QQuickMenu::pressAndHold()
void tst_QQuickMenu::contextMenuKeyboard()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)
QSKIP("This platform only allows tab focus for text controls");
@@ -468,6 +488,9 @@ void tst_QQuickMenu::contextMenuKeyboard()
// QTBUG-70181
void tst_QQuickMenu::disabledMenuItemKeyNavigation()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)
QSKIP("This platform only allows tab focus for text controls");
@@ -532,6 +555,9 @@ void tst_QQuickMenu::disabledMenuItemKeyNavigation()
void tst_QQuickMenu::mnemonics()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
#ifdef Q_OS_MACOS
QSKIP("Mnemonics are not used on macOS");
#endif
@@ -587,6 +613,9 @@ void tst_QQuickMenu::mnemonics()
void tst_QQuickMenu::menuButton()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)
QSKIP("This platform only allows tab focus for text controls");
@@ -621,7 +650,7 @@ void tst_QQuickMenu::addItem()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
QVERIFY(menu);
@@ -639,6 +668,9 @@ void tst_QQuickMenu::addItem()
void tst_QQuickMenu::menuSeparator()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
QQuickControlsApplicationHelper helper(this, QLatin1String("menuSeparator.qml"));
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
@@ -663,6 +695,7 @@ void tst_QQuickMenu::menuSeparator()
QVERIFY(saveMenuItem);
QCOMPARE(saveMenuItem->text(), QStringLiteral("Save"));
QTRY_VERIFY(!QQuickItemPrivate::get(saveMenuItem)->culled); // QTBUG-53262
+ QTRY_VERIFY(menu->isOpened());
// Clicking on items should still close the menu.
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
@@ -670,7 +703,7 @@ void tst_QQuickMenu::menuSeparator()
QTRY_VERIFY(!menu->isVisible());
menu->open();
- QVERIFY(menu->isVisible());
+ QTRY_VERIFY(menu->isOpened());
// Clicking on a separator shouldn't close the menu.
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
@@ -721,7 +754,7 @@ void tst_QQuickMenu::repeater()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
QVERIFY(menu);
@@ -766,7 +799,7 @@ void tst_QQuickMenu::order()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
QVERIFY(menu);
@@ -782,15 +815,29 @@ void tst_QQuickMenu::order()
}
}
+#if QT_CONFIG(cursor)
void tst_QQuickMenu::popup()
{
+#if defined(Q_OS_ANDROID)
+ QSKIP("Setting cursor position is not supported on Android");
+#endif
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland")))
+ QSKIP("Setting cursor position is not supported on Wayland");
+
+ // Try moving the cursor from the current position
+ // Skip if it fails since the test relies on moving the cursor
+ const QPoint point = QCursor::pos() + QPoint(1, 1);
+ QCursor::setPos(point);
+ if (!QTest::qWaitFor([point]{ return QCursor::pos() == point; }))
+ QSKIP("Setting cursor position is not supported on this platform");
+
QQuickControlsApplicationHelper helper(this, QLatin1String("popup.qml"));
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
centerOnScreen(window);
moveMouseAway(window);
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
QVERIFY(menu);
@@ -807,8 +854,6 @@ void tst_QQuickMenu::popup()
QQuickItem *button = window->property("button").value<QQuickItem *>();
QVERIFY(button);
- // Android does not support settings cursor position
-#if QT_CONFIG(cursor) && !defined(Q_OS_ANDROID)
QPoint oldCursorPos = QCursor::pos();
QPoint cursorPos = window->mapToGlobal(QPoint(11, 22));
QCursor::setPos(cursorPos);
@@ -832,16 +877,16 @@ void tst_QQuickMenu::popup()
QCOMPARE(menu->parentItem(), window->contentItem());
QCOMPARE(menu->currentIndex(), -1);
QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1);
- QTRY_VERIFY(qFuzzyCompare(menu->x(), 33));
- QTRY_VERIFY(qFuzzyCompare(menu->y(), 44));
+ QTRY_VERIFY(qFuzzyCompare(menu->x(), qMax(qreal(33), menu->leftMargin())));
+ QTRY_VERIFY(qFuzzyCompare(menu->y(), qMax(qreal(44), menu->topMargin())));
menu->close();
QVERIFY(QMetaObject::invokeMethod(window, "popupAtCoord", Q_ARG(QVariant, 55), Q_ARG(QVariant, 66)));
QCOMPARE(menu->parentItem(), window->contentItem());
QCOMPARE(menu->currentIndex(), -1);
QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1);
- QTRY_VERIFY(qFuzzyCompare(menu->x(), 55));
- QTRY_VERIFY(qFuzzyCompare(menu->y(), 66));
+ QTRY_VERIFY(qFuzzyCompare(menu->x(), qMax(qreal(55), menu->leftMargin())));
+ QTRY_VERIFY(qFuzzyCompare(menu->y(), qMax(qreal(66), menu->topMargin())));
menu->close();
menu->setParentItem(nullptr);
@@ -937,8 +982,8 @@ void tst_QQuickMenu::popup()
QCursor::setPos(oldCursorPos);
QTRY_COMPARE(QCursor::pos(), oldCursorPos);
-#endif
}
+#endif // QT_CONFIG(cursor)
void tst_QQuickMenu::actions()
{
@@ -946,7 +991,7 @@ void tst_QQuickMenu::actions()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
QVERIFY(menu);
@@ -1012,6 +1057,9 @@ void tst_QQuickMenu::actions()
#if QT_CONFIG(shortcut)
void tst_QQuickMenu::actionShortcuts()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
QQuickControlsApplicationHelper helper(this, QLatin1String("actionShortcuts.qml"));
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
@@ -1065,7 +1113,7 @@ void tst_QQuickMenu::removeTakeItem()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
QVERIFY(menu);
@@ -1125,7 +1173,7 @@ void tst_QQuickMenu::subMenuMouse()
centerOnScreen(window);
moveMouseAway(window);
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>();
QVERIFY(mainMenu);
@@ -1244,7 +1292,7 @@ void tst_QQuickMenu::subMenuDisabledMouse()
centerOnScreen(window);
moveMouseAway(window);
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>();
QVERIFY(mainMenu);
@@ -1258,16 +1306,22 @@ void tst_QQuickMenu::subMenuDisabledMouse()
QVERIFY(subMenu);
mainMenu->open();
- QVERIFY(mainMenu->isVisible());
+ QTRY_VERIFY(mainMenu->isOpened());
QVERIFY(!menuItem1->isHighlighted());
QVERIFY(!subMenu->isVisible());
+ // Hover-highlighting does not work on Android
+#ifndef Q_OS_ANDROID
+ // Generate a hover event to set the current index
+ QTest::mouseMove(window, menuItem1->mapToScene(QPoint(2, 2)).toPoint());
+ QTRY_VERIFY(menuItem1->isHighlighted());
+#endif
// Open the sub-menu with a mouse click.
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, menuItem1->mapToScene(QPoint(1, 1)).toPoint());
- // Need to use the TRY variant here when cascade is false,
- // as e.g. Material style menus have transitions and don't close immediately.
+ // Need to use the TRY variant here,
+ // as e.g. Material, iOS style menus have transitions and don't open/close immediately.
QTRY_COMPARE(mainMenu->isVisible(), cascade);
- QVERIFY(subMenu->isVisible());
+ QTRY_VERIFY(subMenu->isOpened());
QTRY_VERIFY(menuItem1->isHighlighted());
// Now the sub-menu is open. The current behavior is that the first menu item
// in the new menu is highlighted; make sure that we choose the next item if
@@ -1298,6 +1352,9 @@ void tst_QQuickMenu::subMenuKeyboard_data()
void tst_QQuickMenu::subMenuKeyboard()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
QFETCH(bool, cascade);
QFETCH(bool, mirrored);
@@ -1424,6 +1481,9 @@ void tst_QQuickMenu::subMenuDisabledKeyboard_data()
// QTBUG-69540
void tst_QQuickMenu::subMenuDisabledKeyboard()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
QFETCH(bool, cascade);
QFETCH(bool, mirrored);
@@ -1539,7 +1599,7 @@ void tst_QQuickMenu::subMenuPosition()
// unpredictable results
window->showNormal();
#endif
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
if (mirrored) {
QQmlExpression mirroringExpression(qmlContext(window), window,
@@ -1653,7 +1713,7 @@ void tst_QQuickMenu::addRemoveSubMenus()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>();
QVERIFY(mainMenu);
@@ -1729,7 +1789,7 @@ void tst_QQuickMenu::scrollable()
#else
window->showNormal();
#endif
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
menu->open();
@@ -1769,7 +1829,7 @@ void tst_QQuickMenu::disableWhenTriggered()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickWindow *window = helper.window;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->findChild<QQuickMenu*>("Menu");
QVERIFY(menu);
@@ -1834,7 +1894,7 @@ void tst_QQuickMenu::menuItemWidth()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
if (mirrored) {
QQmlExpression mirroringExpression(qmlContext(window), window,
@@ -1866,7 +1926,7 @@ void tst_QQuickMenu::menuItemWidthAfterMenuWidthChanged()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
if (mirrored) {
QQmlExpression mirroringExpression(qmlContext(window), window,
@@ -1914,7 +1974,7 @@ void tst_QQuickMenu::menuItemWidthAfterImplicitWidthChanged()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
if (mirrored) {
QQmlExpression mirroringExpression(qmlContext(window), window,
@@ -1948,7 +2008,7 @@ void tst_QQuickMenu::menuItemWidthAfterRetranslate()
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
QVERIFY(menu);
@@ -1976,6 +2036,9 @@ void tst_QQuickMenu::menuItemWidthAfterRetranslate()
void tst_QQuickMenu::giveMenuItemFocusOnButtonPress()
{
+ if (!hasWindowActivation())
+ QSKIP("Window activation is not supported");
+
QQuickControlsApplicationHelper helper(this, QLatin1String("giveMenuItemFocusOnButtonPress.qml"));
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
@@ -2000,6 +2063,46 @@ void tst_QQuickMenu::giveMenuItemFocusOnButtonPress()
QTRY_VERIFY(menu->isOpened());
}
+void tst_QQuickMenu::customMenuCullItems()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("customMenuCullItems.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
+ QVERIFY(menu);
+ menu->open();
+ QTRY_VERIFY(menu->isOpened());
+
+ QQuickItem *menuItemFirst = menu->itemAt(0);
+ QQuickItem *menuItemLast = menu->itemAt(menu->count() - 1);
+ QVERIFY(menuItemFirst);
+ QVERIFY(menuItemLast);
+ QTRY_VERIFY(!QQuickItemPrivate::get(menuItemFirst)->culled);
+ QTRY_VERIFY(QQuickItemPrivate::get(menuItemLast)->culled);
+}
+
+void tst_QQuickMenu::customMenuUseRepeaterAsTheContentItem()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("customMenuUseRepeaterAsTheContentItem.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
+ QVERIFY(menu);
+ menu->open();
+ QTRY_VERIFY(menu->isVisible());
+
+ QQuickItem *menuItemFirst = menu->itemAt(0);
+ QQuickItem *menuItemLast = menu->itemAt(menu->count() - 1);
+ QTRY_VERIFY(!QQuickItemPrivate::get(menuItemFirst)->culled);
+ QTRY_VERIFY(!QQuickItemPrivate::get(menuItemLast)->culled);
+}
+
QTEST_QUICKCONTROLS_MAIN(tst_QQuickMenu)
#include "tst_qquickmenu.moc"