aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMitch Curtis <[email protected]>2023-11-21 11:12:31 +0800
committerMitch Curtis <[email protected]>2024-01-16 18:09:10 +0800
commitd84556e6bcc91690e5fccd1a909707698b6be56c (patch)
tree9047a4e927eed8ca643680a8d0c02cd4ec1a8cd3 /tests
parent8ba21bb39fdb92de889c3ba5f3bc10428576a5f3 (diff)
Add beginnings of native Menu backend
This patch gets the basic functionality and initial API in place so that work on MenuBar can begin. Task-number: QTBUG-69558 Change-Id: I94df848f771d38cd1cabb964b695d383f66240f2 Reviewed-by: Richard Moe Gustavsen <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quickcontrols/CMakeLists.txt6
-rw-r--r--tests/auto/quickcontrols/nativemenus/CMakeLists.txt43
-rw-r--r--tests/auto/quickcontrols/nativemenus/data/emptyMenu.qml50
-rw-r--r--tests/auto/quickcontrols/nativemenus/data/staticActionsAndSubmenus.qml56
-rw-r--r--tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp181
-rw-r--r--tests/auto/quickcontrols/qquickmenu/tst_qquickmenu.cpp2
6 files changed, 338 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols/CMakeLists.txt b/tests/auto/quickcontrols/CMakeLists.txt
index f4f2e6b2c6..6b53bdf80e 100644
--- a/tests/auto/quickcontrols/CMakeLists.txt
+++ b/tests/auto/quickcontrols/CMakeLists.txt
@@ -17,6 +17,12 @@ if(NOT ANDROID) # QTBUG-100258
add_subdirectory(focus)
endif()
add_subdirectory(font)
+# For now there's no way of knowing (at built time) if the Linux we're on is
+# running with the GTK+ platform theme, which is the only context
+# in which native menus are supported there. So we don't include it.
+if(WIN32 OR MACOS OR IOS OR ANDROID)
+ add_subdirectory(nativemenus)
+endif()
add_subdirectory(palette)
add_subdirectory(platform)
add_subdirectory(pointerhandlers)
diff --git a/tests/auto/quickcontrols/nativemenus/CMakeLists.txt b/tests/auto/quickcontrols/nativemenus/CMakeLists.txt
new file mode 100644
index 0000000000..2112c9ab74
--- /dev/null
+++ b/tests/auto/quickcontrols/nativemenus/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_nativemenus LANGUAGES C CXX ASM)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_nativemenus
+ SOURCES
+ tst_nativemenus.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickControls2
+ Qt::QuickControls2Private
+ Qt::QuickControlsTestUtilsPrivate
+ Qt::QuickPrivate
+ Qt::QuickTemplates2Private
+ Qt::QuickTest
+ Qt::QuickTestUtilsPrivate
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+)
+
+qt_internal_extend_target(tst_nativemenus CONDITION ANDROID OR IOS
+ DEFINES
+ QT_QMLTEST_DATADIR=":/data"
+)
+
+qt_internal_extend_target(tst_nativemenus CONDITION NOT ANDROID AND NOT IOS
+ DEFINES
+ QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
+)
diff --git a/tests/auto/quickcontrols/nativemenus/data/emptyMenu.qml b/tests/auto/quickcontrols/nativemenus/data/emptyMenu.qml
new file mode 100644
index 0000000000..f1d4f33625
--- /dev/null
+++ b/tests/auto/quickcontrols/nativemenus/data/emptyMenu.qml
@@ -0,0 +1,50 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias contextMenu: contextMenu
+
+ function addAction(menu: T.Menu, text: string) {
+ menu.addAction(actionComponent.createObject(null, { text: text }))
+ }
+
+ function insertAction(menu: T.Menu, index: int, text: string) {
+ menu.insertAction(index, actionComponent.createObject(null, { text: text }))
+ }
+
+ function removeAction(menu: T.Menu, index: int) {
+ menu.removeAction(menu.actionAt(index))
+ }
+
+ function addMenu(menu: T.Menu, title: string) {
+ menu.addMenu(menuComponent.createObject(null, { title: title }))
+ }
+
+ Component {
+ id: actionComponent
+
+ Action {
+ objectName: text
+ }
+ }
+
+ Component {
+ id: menuComponent
+
+ Menu {
+ objectName: title
+ }
+ }
+
+ Menu {
+ id: contextMenu
+ objectName: "menu"
+ }
+}
diff --git a/tests/auto/quickcontrols/nativemenus/data/staticActionsAndSubmenus.qml b/tests/auto/quickcontrols/nativemenus/data/staticActionsAndSubmenus.qml
new file mode 100644
index 0000000000..54fb1497d0
--- /dev/null
+++ b/tests/auto/quickcontrols/nativemenus/data/staticActionsAndSubmenus.qml
@@ -0,0 +1,56 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias contextMenu: contextMenu
+// property alias buttonMenu: buttonMenu
+
+ Menu {
+ id: contextMenu
+ objectName: "menu"
+
+ Action {
+ objectName: text
+ text: "action1"
+ shortcut: "A"
+ }
+
+ Action {
+ objectName: text
+ text: "action2"
+ shortcut: "B"
+ }
+
+ Menu {
+ id: subMenu
+ objectName: "subMenu"
+
+ Action {
+ objectName: text
+ text: "subAction1"
+ shortcut: "1"
+ }
+ }
+ }
+
+// Button {
+// text: "Menu button"
+
+// Menu {
+// id: buttonMenu
+
+// Action {
+// objectName: text
+// text: "buttonMenuAction1"
+// shortcut: "Z"
+// }
+// }
+// }
+}
diff --git a/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp b/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp
new file mode 100644
index 0000000000..4e1fe9dd70
--- /dev/null
+++ b/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp
@@ -0,0 +1,181 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include <QtGui/qcursor.h>
+#if QT_CONFIG(shortcut)
+#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>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/visualtestutils_p.h>
+#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
+#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h>
+
+#include <QtQuickTemplates2/private/qquickaction_p.h>
+#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
+#include <QtQuickTemplates2/private/qquickmenu_p.h>
+#include <QtQuickTemplates2/private/qquickmenu_p_p.h>
+#include <QtQuickTemplates2/private/qquickmenuitem_p.h>
+#include <QtQuickTemplates2/private/qquickmenuseparator_p.h>
+
+using namespace QQuickVisualTestUtils;
+using namespace QQuickControlsTestUtils;
+
+/*
+ We have a separate test project for native menus because we don't
+ want to run them for every style, just the platforms that have
+ native menu support.
+*/
+
+class tst_NativeMenus : public QQmlDataTest
+{
+ Q_OBJECT
+
+public:
+ tst_NativeMenus();
+
+private slots:
+ void defaults();
+ void staticActionsAndSubmenus();
+ void dynamicActions();
+ void dynamicSubmenus();
+};
+
+tst_NativeMenus::tst_NativeMenus()
+ : QQmlDataTest(QT_QMLTEST_DATADIR)
+{
+ qputenv("QT_QUICK_CONTROLS_USE_NATIVE_MENUS", "1");
+}
+
+void tst_NativeMenus::defaults()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("emptyMenu.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *contextMenu = window->property("contextMenu").value<QQuickMenu*>();
+ QVERIFY(contextMenu);
+ auto *contextMenuPrivate = QQuickMenuPrivate::get(contextMenu);
+ QVERIFY(contextMenuPrivate->usingNativeMenu());
+}
+
+void tst_NativeMenus::staticActionsAndSubmenus()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("staticActionsAndSubmenus.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *contextMenu = window->property("contextMenu").value<QQuickMenu*>();
+ QVERIFY(contextMenu);
+ QVERIFY(contextMenu->requestNative());
+ auto *contextMenuPrivate = QQuickMenuPrivate::get(contextMenu);
+
+ // Check that the actions of the parent menu can be accessed
+ // and are in the appropriate places in contentData.
+ auto *action1 = contextMenu->actionAt(0);
+ QVERIFY(action1);
+ QCOMPARE(contextMenuPrivate->contentData.at(0), action1);
+
+ auto *action2 = contextMenu->actionAt(1);
+ QVERIFY(action2);
+ QCOMPARE(contextMenuPrivate->contentData.at(1), action2);
+
+ // Check that the sub-menu can be accessed and is in the
+ // appropriate place in contentData.
+ auto *subMenu = contextMenu->menuAt(2);
+ QVERIFY(subMenu);
+
+ // TODO: check that sub-menus exist
+}
+
+void tst_NativeMenus::dynamicActions()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("emptyMenu.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *contextMenu = window->property("contextMenu").value<QQuickMenu*>();
+ QVERIFY(contextMenu);
+ auto *contextMenuPrivate = QQuickMenuPrivate::get(contextMenu);
+
+ // Check that items can be appended to an empty menu.
+ QCOMPARE(contextMenu->actionAt(0), nullptr);
+ QVERIFY(QMetaObject::invokeMethod(window, "addAction",
+ Q_ARG(QQuickMenu *, contextMenu), Q_ARG(QString, "action1")));
+ {
+ auto action1 = contextMenu->actionAt(0);
+ QVERIFY(action1);
+ QCOMPARE(action1->text(), "action1");
+ QCOMPARE(contextMenuPrivate->contentData.at(0), action1);
+ }
+
+ // Check that actions can be appended after existing items in the parent menu.
+ QCOMPARE(contextMenu->actionAt(1), nullptr);
+ QVERIFY(QMetaObject::invokeMethod(window, "addAction",
+ Q_ARG(QQuickMenu *, contextMenu), Q_ARG(QString, "action2")));
+ {
+ auto action2 = contextMenu->actionAt(1);
+ QVERIFY(action2);
+ QCOMPARE(action2->text(), "action2");
+ QCOMPARE(contextMenuPrivate->contentData.at(1), action2);
+ }
+
+ // Check that actions can be inserted before existing items in the parent menu.
+ QVERIFY(QMetaObject::invokeMethod(window, "insertAction",
+ Q_ARG(QQuickMenu *, contextMenu), Q_ARG(int, 0), Q_ARG(QString, "action0")));
+ {
+ auto action0 = contextMenu->actionAt(0);
+ QVERIFY(action0);
+ QCOMPARE(action0->text(), "action0");
+ QCOMPARE(contextMenuPrivate->contentData.at(0), action0);
+ }
+}
+
+void tst_NativeMenus::dynamicSubmenus()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("emptyMenu.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickMenu *contextMenu = window->property("contextMenu").value<QQuickMenu*>();
+ QVERIFY(contextMenu);
+ auto *contextMenuPrivate = QQuickMenuPrivate::get(contextMenu);
+
+ // Check that sub-menus (with no menu items, yet) can be appended to an empty parent menu.
+ QVERIFY(QMetaObject::invokeMethod(window, "addMenu",
+ Q_ARG(QQuickMenu *, contextMenu), Q_ARG(QString, "subMenu1")));
+ auto subMenu1 = contextMenu->menuAt(0);
+ QVERIFY(subMenu1);
+ QCOMPARE(subMenu1->title(), "subMenu1");
+ QCOMPARE(contextMenuPrivate->contentData.at(0), subMenu1);
+
+ //
+ QVERIFY(QMetaObject::invokeMethod(window, "addAction",
+ Q_ARG(QQuickMenu *, subMenu1), Q_ARG(QString, "subMenuAction1")));
+
+ // TODO: insert another sub-menu action before the first one
+}
+
+// TODO: add a test that mixes items with native items
+// and ensure that all items are recreated as non-native
+
+QTEST_MAIN(tst_NativeMenus)
+
+#include "tst_nativemenus.moc"
diff --git a/tests/auto/quickcontrols/qquickmenu/tst_qquickmenu.cpp b/tests/auto/quickcontrols/qquickmenu/tst_qquickmenu.cpp
index fbb4e7d5f9..d446fbecac 100644
--- a/tests/auto/quickcontrols/qquickmenu/tst_qquickmenu.cpp
+++ b/tests/auto/quickcontrols/qquickmenu/tst_qquickmenu.cpp
@@ -32,6 +32,8 @@
using namespace QQuickVisualTestUtils;
using namespace QQuickControlsTestUtils;
+// Native menu tests are in "nativemenus".
+
class tst_QQuickMenu : public QQmlDataTest
{
Q_OBJECT