diff options
-rw-r--r-- | examples/quickcontrols2/texteditor/texteditor.html | 15 | ||||
-rw-r--r-- | src/imports/controls/doc/src/qtquickcontrols2-qmltypes.qdoc | 2 | ||||
-rw-r--r-- | src/imports/controls/universal/TabBar.qml | 23 | ||||
-rw-r--r-- | src/imports/templates/doc/src/qtquicktemplates2-qmltypes.qdoc | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontainer.cpp | 4 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenubar.cpp | 8 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenubar_p_p.h | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquicksplitview.cpp | 39 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_splitview.qml | 102 | ||||
-rw-r--r-- | tests/auto/qquickmenubar/data/checkHighlightWhenDismissed.qml | 93 | ||||
-rw-r--r-- | tests/auto/qquickmenubar/tst_qquickmenubar.cpp | 58 | ||||
-rw-r--r-- | tests/auto/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml | 16 | ||||
-rw-r--r-- | tests/auto/qquickpopup/tst_qquickpopup.cpp | 32 |
15 files changed, 333 insertions, 73 deletions
diff --git a/examples/quickcontrols2/texteditor/texteditor.html b/examples/quickcontrols2/texteditor/texteditor.html index 1310da42..41705f85 100644 --- a/examples/quickcontrols2/texteditor/texteditor.html +++ b/examples/quickcontrols2/texteditor/texteditor.html @@ -31,14 +31,13 @@ </p> <ul> - <!-- TODO: update the links before the 5.8 release --> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menu.html">Menu</a> - provides a QML API for native platform menu popups.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menubar.html">MenuBar</a> - provides a QML API for native platform menubars.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menuitem.html">MenuItem</a> - provides a QML API for native platform menu items.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-filedialog.html">FileDialog</a> - provides a QML API for native platform file dialogs.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-fontdialog.html">FontDialog</a> - provides a QML API for native platform font dialogs.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-colordialog.html">ColorDialog</a> - provides a QML API for native platform color dialogs.</li> - <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-messagedialog.html">MessageDialog</a> - provides a QML API for native platform message dialogs.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-menu.html">Menu</a> - provides a QML API for native platform menu popups.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-menubar.html">MenuBar</a> - provides a QML API for native platform menubars.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-menuitem.html">MenuItem</a> - provides a QML API for native platform menu items.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-filedialog.html">FileDialog</a> - provides a QML API for native platform file dialogs.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-fontdialog.html">FontDialog</a> - provides a QML API for native platform font dialogs.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-colordialog.html">ColorDialog</a> - provides a QML API for native platform color dialogs.</li> + <li><a href="https://doc.qt.io/qt-5/qml-qt-labs-platform-messagedialog.html">MessageDialog</a> - provides a QML API for native platform message dialogs.</li> </ul> </body> </html> diff --git a/src/imports/controls/doc/src/qtquickcontrols2-qmltypes.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-qmltypes.qdoc index c8c44264..360d2059 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-qmltypes.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-qmltypes.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQuick.Controls 2.5 + \qmlmodule QtQuick.Controls 2.\QtMinorVersion \keyword Qt Quick Controls QML Types \title Qt Quick Controls QML Types \keyword Qt Quick Controls 2 QML Types diff --git a/src/imports/controls/universal/TabBar.qml b/src/imports/controls/universal/TabBar.qml index ab660c93..c7d27cbd 100644 --- a/src/imports/controls/universal/TabBar.qml +++ b/src/imports/controls/universal/TabBar.qml @@ -46,23 +46,20 @@ T.TabBar { implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) - contentItem: PathView { + contentItem: ListView { model: control.contentModel currentIndex: control.currentIndex - interactive: false - snapMode: PathView.SnapToItem - movementDirection: PathView.Positive - highlightMoveDuration: 100 + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem - path: Path { - startX: control.count ? control.availableWidth / control.count / 2 : 0 - startY: control.availableHeight / 2 - PathLine { - x: control.count ? control.availableWidth + (control.availableWidth / control.count / 2) : 0 - y: control.availableHeight / 2 - } - } + highlightMoveDuration: 100 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 48 + preferredHighlightEnd: width - 48 } background: Rectangle { diff --git a/src/imports/templates/doc/src/qtquicktemplates2-qmltypes.qdoc b/src/imports/templates/doc/src/qtquicktemplates2-qmltypes.qdoc index 1288e937..f93d6a37 100644 --- a/src/imports/templates/doc/src/qtquicktemplates2-qmltypes.qdoc +++ b/src/imports/templates/doc/src/qtquicktemplates2-qmltypes.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQuick.Templates 2.5 + \qmlmodule QtQuick.Templates 2.\QtMinorVersion \title Qt Quick Templates 2 QML Types \ingroup qmlmodules \brief Provides QML types for templates (Qt Quick Templates). diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 609c2079..5f38c5b9 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -241,7 +241,7 @@ void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) updatingCurrent = true; - item->setParentItem(effectiveContentItem(getContentItem())); + item->setParentItem(effectiveContentItem(q->contentItem())); QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes); contentModel->insert(index, item); @@ -383,7 +383,7 @@ void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, QQuickItem *item = qobject_cast<QQuickItem *>(obj); if (item) { if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) - item->setParentItem(effectiveContentItem(p->contentItem)); + item->setParentItem(effectiveContentItem(q->contentItem())); else if (p->contentModel->indexOf(item, nullptr) == -1) q->addItem(item); } else { diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp index 1761d999..f909193f 100644 --- a/src/quicktemplates2/qquickmenubar.cpp +++ b/src/quicktemplates2/qquickmenubar.cpp @@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls} */ -QQuickItem *QQuickMenuBarPrivate::beginCreateItem() +QQuickItem *QQuickMenuBarPrivate::beginCreateItem(QQuickMenu *menu) { Q_Q(QQuickMenuBar); if (!delegate) @@ -96,6 +96,8 @@ QQuickItem *QQuickMenuBarPrivate::beginCreateItem() return nullptr; } + if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) + menuBarItem->setMenu(menu); item->setParentItem(q); QQml_setParent_noEvent(item, q); @@ -112,9 +114,7 @@ void QQuickMenuBarPrivate::completeCreateItem() QQuickItem *QQuickMenuBarPrivate::createItem(QQuickMenu *menu) { - QQuickItem *item = beginCreateItem(); - if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) - menuBarItem->setMenu(menu); + QQuickItem *item = beginCreateItem(menu); completeCreateItem(); return item; } diff --git a/src/quicktemplates2/qquickmenubar_p_p.h b/src/quicktemplates2/qquickmenubar_p_p.h index 75fbed73..c214962b 100644 --- a/src/quicktemplates2/qquickmenubar_p_p.h +++ b/src/quicktemplates2/qquickmenubar_p_p.h @@ -69,7 +69,7 @@ public: QQmlListProperty<QQuickMenu> menus(); QQmlListProperty<QObject> contentData(); - QQuickItem *beginCreateItem(); + QQuickItem *beginCreateItem(QQuickMenu *menu); void completeCreateItem(); QQuickItem *createItem(QQuickMenu *menu); diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index f0cf1869..f272c5cf 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -2409,6 +2409,13 @@ void QQuickPopup::componentComplete() d->complete = true; d->popupItem->componentComplete(); + + if (isVisible()) { + if (d->closePolicy & QQuickPopup::CloseOnEscape) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } } bool QQuickPopup::isComponentComplete() const diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp index 75cd9674..56392e9a 100644 --- a/src/quicktemplates2/qquicksplitview.cpp +++ b/src/quicktemplates2/qquicksplitview.cpp @@ -849,6 +849,8 @@ QQuickSplitViewPrivate::EffectiveSizeData QQuickSplitViewPrivate::effectiveSizeD int QQuickSplitViewPrivate::handleIndexForSplitIndex(int splitIndex) const { + // If it's the first and only item in the view, it doesn't have a handle, + // so return -1: splitIndex (0) - 1. // If it's the last item in the view, it doesn't have a handle, so use // the handle for the previous item. return splitIndex == contentModel->count() - 1 ? splitIndex - 1 : splitIndex; @@ -928,7 +930,6 @@ QQuickItem *QQuickSplitViewPrivate::getContentItem() if (QQuickItem *item = QQuickContainerPrivate::getContentItem()) return item; - // TODO: why are several created? return new QQuickContentItem(q); } @@ -1016,11 +1017,13 @@ void QQuickSplitViewPrivate::itemVisibilityChanged(QQuickItem *item) // of the corresponding handle (if one exists). const int handleIndex = handleIndexForSplitIndex(itemIndex); - QQuickItem *handleItem = m_handleItems.at(handleIndex); - handleItem->setVisible(item->isVisible()); + if (handleIndex != -1) { + QQuickItem *handleItem = m_handleItems.at(handleIndex); + handleItem->setVisible(item->isVisible()); - qCDebug(qlcQQuickSplitView) << "set visible property of handle item" - << handleItem << "at index" << handleIndex << "to" << item->isVisible(); + qCDebug(qlcQQuickSplitView) << "set visible property of handle item" + << handleItem << "at index" << handleIndex << "to" << item->isVisible(); + } updateHandleVisibilities(); updateFillIndex(); @@ -1337,10 +1340,6 @@ void QQuickSplitView::hoverMoveEvent(QHoverEvent *event) qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << d->m_hoveredHandleIndex << "is no longer hovered"; d->m_hoveredHandleIndex = -1; - -#if QT_CONFIG(cursor) - setCursor(Qt::ArrowCursor); -#endif } else { // A child item of ours is hovered. @@ -1353,23 +1352,23 @@ void QQuickSplitView::hoverMoveEvent(QHoverEvent *event) } // Now check if the newly hovered item is actually a handle. - const int hoveredHandleIndex = d->m_handleItems.indexOf(hoveredItem); - if (hoveredHandleIndex == -1) - return; + d->m_hoveredHandleIndex = d->m_handleItems.indexOf(hoveredItem); - // It's a handle, so it's now hovered. - d->m_hoveredHandleIndex = hoveredHandleIndex; + if (d->m_hoveredHandleIndex != -1) { + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true); - QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( - qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true)); - QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true); + qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << d->m_hoveredHandleIndex << "is now hovered"; + } + } #if QT_CONFIG(cursor) + if (d->m_hoveredHandleIndex != -1) setCursor(d->m_orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); + else + setCursor(Qt::ArrowCursor); #endif - - qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << d->m_hoveredHandleIndex << "is now hovered"; - } } void QQuickSplitView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index d528b848..8612e2c1 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -30,3 +30,6 @@ SUBDIRS += \ revisions \ sanity \ snippets + +# Requires lrelease, which isn't always available in CI. +qtHaveModule(tools): translation diff --git a/tests/auto/controls/data/tst_splitview.qml b/tests/auto/controls/data/tst_splitview.qml index a03c09a0..c125b99e 100644 --- a/tests/auto/controls/data/tst_splitview.qml +++ b/tests/auto/controls/data/tst_splitview.qml @@ -146,24 +146,14 @@ TestCase { implicitWidth: defaultHorizontalHandleWidth implicitHeight: defaultVerticalHandleHeight color: "#444" - } - } - - SplitView { - id: dummyHorizontalSplitView - handle: handleComponent - - Item { objectName: "dummyItem" } - Item { objectName: "dummyItem" } - } - - SplitView { - id: dummyVerticalSplitView - orientation: Qt.Vertical - handle: handleComponent - Item { objectName: "dummyItem" } - Item { objectName: "dummyItem" } + Text { + text: parent.x + "," + parent.y + " " + parent.width + "x" + parent.height + color: "white" + anchors.centerIn: parent + rotation: 90 + } + } } Component { @@ -851,6 +841,36 @@ TestCase { } } + Component { + id: repeaterSplitViewComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + property alias repeater: repeater + + Repeater { + id: repeater + model: 3 + delegate: Rectangle { + objectName: "rectDelegate" + index + + SplitView.preferredWidth: 25 + + color: "#aaff0000" + + Text { + text: parent.x + "," + parent.y + " " + parent.width + "x" + parent.height + color: "white" + rotation: 90 + anchors.centerIn: parent + } + } + } + } + } + function test_dragHandle_data() { var splitViewWidth = testCase.width - splitViewMargins * 2 var splitViewHeight = testCase.height - splitViewMargins * 2 @@ -1109,6 +1129,28 @@ TestCase { { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 100, height: splitViewHeight } ] + }, + { + tag: "repeater", + component: repeaterSplitViewComponent, + orientation: Qt.Horizontal, + fillIndex: 2, + handleIndex: 1, + newHandlePos: Qt.point(200, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 25, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 70 , height: splitViewHeight } + ], + expectedGeometriesAfterDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 105, height: splitViewHeight }, + { x: 140, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 150, y: 0, width: 150, height: splitViewHeight } + ] } ] return data @@ -1139,6 +1181,7 @@ TestCase { var targetHandle = handles[data.handleIndex] mousePress(targetHandle) verify(control.resizing) + // newHandlePos is in scene coordinates, so map it to coordinates local to the handle. var localPos = testCase.mapToItem(targetHandle, data.newHandlePos.x, data.newHandlePos.y) mouseMove(targetHandle, localPos.x - targetHandle.width / 2, localPos.y - targetHandle.height / 2) verify(control.resizing) @@ -1958,4 +2001,29 @@ TestCase { mouseRelease(targetHandle, -100, targetHandle.height / 2, Qt.LeftButton) verify(!control.resizing) } + + Component { + id: oneItemComponent + + SplitView { + Item {} + } + } + + // QTBUG-79270 + function test_hideSplitViewWithOneItem() { + var control = createTemporaryObject(oneItemComponent, testCase) + verify(control) + // Shouldn't be an assertion failure. + control.visible = false + } + + // QTBUG-79302: ensure that the Repeater's items are actually generated. + // test_dragHandle:repeater tests dragging behavior with a Repeater. + function test_repeater(data) { + var control = createTemporaryObject(repeaterSplitViewComponent, testCase) + verify(control) + compare(control.repeater.count, 3) + compare(control.contentChildren.length, 3) + } } diff --git a/tests/auto/qquickmenubar/data/checkHighlightWhenDismissed.qml b/tests/auto/qquickmenubar/data/checkHighlightWhenDismissed.qml new file mode 100644 index 00000000..072fa6b1 --- /dev/null +++ b/tests/auto/qquickmenubar/data/checkHighlightWhenDismissed.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.13 +import QtQuick.Controls 2.13 + +ApplicationWindow { + width: 300 + height: 300 + visible: true + MenuBar { + id: mb + objectName: "menuBar" + width: parent.width + Menu { + title: "StaticMenu" + MenuItem { + text: "Cut" + } + MenuItem { + text: "Copy" + } + MenuItem { + text: "Paste" + } + } + } + Component { + id: cmp + Menu { + title: "DynamicMenu" + MenuItem { + text: "Cut" + } + MenuItem { + text: "Copy" + } + MenuItem { + text: "Paste" + } + } + } + Component.onCompleted: { + mb.addMenu(cmp.createObject(mb)) + } +} diff --git a/tests/auto/qquickmenubar/tst_qquickmenubar.cpp b/tests/auto/qquickmenubar/tst_qquickmenubar.cpp index 9a22d26f..2fb1a02b 100644 --- a/tests/auto/qquickmenubar/tst_qquickmenubar.cpp +++ b/tests/auto/qquickmenubar/tst_qquickmenubar.cpp @@ -60,6 +60,7 @@ private slots: void keys(); void mnemonics(); void addRemove(); + void checkHighlightWhenMenuDismissed(); }; void tst_qquickmenubar::delegate() @@ -564,6 +565,63 @@ void tst_qquickmenubar::addRemove() QVERIFY(menuBarItem1.isNull()); } +void tst_qquickmenubar::checkHighlightWhenMenuDismissed() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse highlight not functional on offscreen/minimal platforms"); + + QQmlApplicationEngine engine(testFileUrl("checkHighlightWhenDismissed.qml")); + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(engine.rootObjects().value(0))); + QVERIFY(window); + + centerOnScreen(window.data()); + moveMouseAway(window.data()); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickMenuBar *menuBar = window->findChild<QQuickMenuBar *>("menuBar"); + QVERIFY(menuBar); + + QQuickMenu *staticMenu = menuBar->menuAt(0); + QQuickMenu *dynamicMenu = menuBar->menuAt(1); + QVERIFY(staticMenu && dynamicMenu); + QQuickMenuBarItem *staticMenuBarItem = qobject_cast<QQuickMenuBarItem *>(staticMenu->parentItem()); + QQuickMenuBarItem *dynamicMenuBarItem = qobject_cast<QQuickMenuBarItem *>(dynamicMenu->parentItem()); + QVERIFY(staticMenuBarItem && dynamicMenuBarItem); + + // highlight the static MenuBarItem and open the menu + QTest::mouseMove(window.data(), staticMenuBarItem->mapToScene( + QPointF(staticMenuBarItem->width() / 2, staticMenuBarItem->height() / 2)).toPoint()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + staticMenuBarItem->mapToScene(QPointF(staticMenuBarItem->width() / 2, staticMenuBarItem->height() / 2)).toPoint()); + QCOMPARE(staticMenuBarItem->isHighlighted(), true); + QCOMPARE(staticMenu->isVisible(), true); + QTRY_COMPARE(staticMenu->isOpened(), true); + + // click a menu item to dismiss the menu and unhighlight the static MenuBarItem + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(staticMenu->itemAt(0)); + QVERIFY(menuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QCOMPARE(staticMenuBarItem->isHighlighted(), false); + + // highlight the dynamic MenuBarItem and open the menu + QTest::mouseMove(window.data(), dynamicMenuBarItem->mapToScene( + QPointF(dynamicMenuBarItem->width() / 2, dynamicMenuBarItem->height() / 2)).toPoint()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + dynamicMenuBarItem->mapToScene(QPointF(dynamicMenuBarItem->width() / 2, dynamicMenuBarItem->height() / 2)).toPoint()); + QCOMPARE(dynamicMenuBarItem->isHighlighted(), true); + QCOMPARE(dynamicMenu->isVisible(), true); + QTRY_COMPARE(dynamicMenu->isOpened(), true); + + // click a menu item to dismiss the menu and unhighlight the dynamic MenuBarItem + menuItem = qobject_cast<QQuickMenuItem *>(dynamicMenu->itemAt(0)); + QVERIFY(menuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QCOMPARE(dynamicMenuBarItem->isHighlighted(), false); +} + QTEST_QUICKCONTROLS_MAIN(tst_qquickmenubar) #include "tst_qquickmenubar.moc" diff --git a/tests/auto/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml b/tests/auto/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml new file mode 100644 index 00000000..b9606eb2 --- /dev/null +++ b/tests/auto/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml @@ -0,0 +1,16 @@ +import QtQuick 2.13 +import QtQuick.Window 2.13 +import QtQuick.Controls 2.13 + +Window { + width: 400 + height: 400 + Popup { + objectName: "popup" + visible: true + width: 200 + height: 200 + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + } +} diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp index 4d238663..7da20c37 100644 --- a/tests/auto/qquickpopup/tst_qquickpopup.cpp +++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp @@ -82,6 +82,7 @@ private slots: void cursorShape(); void componentComplete(); void closeOnEscapeWithNestedPopups(); + void closeOnEscapeWithVisiblePopup(); void enabled(); void orientation_data(); void orientation(); @@ -904,6 +905,8 @@ void tst_QQuickPopup::cursorShape() // which is itself over an item with a different shape. QQuickApplicationHelper helper(this, QStringLiteral("cursor.qml")); QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); @@ -1018,6 +1021,21 @@ void tst_QQuickPopup::closeOnEscapeWithNestedPopups() QCOMPARE(stackView->depth(), 1); } +void tst_QQuickPopup::closeOnEscapeWithVisiblePopup() +{ + QQuickApplicationHelper helper(this, QStringLiteral("closeOnEscapeWithVisiblePopup.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->findChild<QQuickPopup *>("popup"); + QVERIFY(popup); + QTRY_VERIFY(popup->isOpened()); + + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!popup->isVisible()); +} + void tst_QQuickPopup::enabled() { QQuickPopup popup; @@ -1197,9 +1215,11 @@ void tst_QQuickPopup::toolTipCrashOnClose() QQuickWindow *window = helper.window; window->show(); - // TODO: Using ignoreMessage() fails in CI with macOS for release builds, - // so for now we let the warning through. -// QTest::ignoreMessage(QtWarningMsg, "ShaderEffectSource: 'recursive' must be set to true when rendering recursively."); + // The warning only occurs with debug builds for some reason. + // In any case, the warning is irrelevant, but using ShaderEffectSource is important, so we ignore it. +#ifdef QT_DEBUG + QTest::ignoreMessage(QtWarningMsg, "ShaderEffectSource: 'recursive' must be set to true when rendering recursively."); +#endif QVERIFY(QTest::qWaitForWindowActive(window)); QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); @@ -1215,9 +1235,9 @@ void tst_QQuickPopup::setOverlayParentToNull() QQuickWindow *window = helper.window; window->show(); - // TODO: Using ignoreMessage() fails in CI with macOS for release builds, - // so for now we let the warning through. -// QTest::ignoreMessage(QtWarningMsg, "ShaderEffectSource: 'recursive' must be set to true when rendering recursively."); +#ifdef QT_DEBUG + QTest::ignoreMessage(QtWarningMsg, "ShaderEffectSource: 'recursive' must be set to true when rendering recursively."); +#endif QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(QMetaObject::invokeMethod(window, "nullifyOverlayParent")); |