diff options
-rw-r--r-- | src/quicktemplates2/qquickapplicationwindow.cpp | 3 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay.cpp | 28 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay_p.h | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 19 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p.h | 1 | ||||
-rw-r--r-- | tests/auto/popup/data/window.qml | 84 | ||||
-rw-r--r-- | tests/auto/popup/tst_popup.cpp | 96 |
7 files changed, 186 insertions, 47 deletions
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index bf903b8a..28095aa6 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -476,6 +476,9 @@ QQuickItem *QQuickApplicationWindow::activeFocusControl() const QQuickOverlay *QQuickApplicationWindow::overlay() const { QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); + if (!d) // being deleted + return nullptr; + if (!d->overlay) { d->overlay = new QQuickOverlay(QQuickWindow::contentItem()); d->overlay->stackAfter(QQuickApplicationWindow::contentItem()); diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index c5818b90..0395ed41 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -37,6 +37,7 @@ #include "qquickoverlay_p.h" #include "qquickpopup_p_p.h" #include "qquickdrawer_p.h" +#include "qquickapplicationwindow_p.h" #include <QtQml/qqmlinfo.h> #include <QtQml/qqmlproperty.h> #include <QtQml/qqmlcomponent.h> @@ -204,8 +205,10 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent) setFiltersChildMouseEvents(true); setVisible(false); - if (parent) + if (parent) { + setSize(QSizeF(parent->width(), parent->height())); QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry); + } } QQuickOverlay::~QQuickOverlay() @@ -249,6 +252,29 @@ void QQuickOverlay::setModeless(QQmlComponent *modeless) emit modelessChanged(); } +QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window) +{ + if (!window) + return nullptr; + + QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow *>(window); + if (applicationWindow) + return applicationWindow->overlay(); + + const char *name = "_q_QQuickOverlay"; + QQuickOverlay *overlay = window->property(name).value<QQuickOverlay *>(); + if (!overlay) { + QQuickItem *content = window->contentItem(); + // Do not re-create the overlay if the window is being destroyed + // and thus, its content item no longer has a window associated. + if (content->window()) { + overlay = new QQuickOverlay(window->contentItem()); + window->setProperty(name, QVariant::fromValue(overlay)); + } + } + return overlay; +} + void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data) { Q_D(QQuickOverlay); diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h index 480a5a6a..ecb0e20a 100644 --- a/src/quicktemplates2/qquickoverlay_p.h +++ b/src/quicktemplates2/qquickoverlay_p.h @@ -72,6 +72,8 @@ public: QQmlComponent *modeless() const; void setModeless(QQmlComponent *modeless); + static QQuickOverlay *overlay(QQuickWindow *window); + Q_SIGNALS: void modalChanged(); void modelessChanged(); diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index b4022247..fa5864df 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -188,15 +188,7 @@ void QQuickPopupPrivate::prepareEnterTransition(bool notify) return; } - QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window); - if (!applicationWindow) { - window->installEventFilter(q); - popupItem->setZ(1000001); // DefaultWindowDecoration+1 - popupItem->setParentItem(window->contentItem()); - } else { - popupItem->setParentItem(applicationWindow->overlay()); - } - + popupItem->setParentItem(QQuickOverlay::overlay(window)); if (notify) emit q->aboutToShow(); visible = notify; @@ -208,8 +200,6 @@ void QQuickPopupPrivate::prepareEnterTransition(bool notify) void QQuickPopupPrivate::prepareExitTransition() { Q_Q(QQuickPopup); - if (window && !qobject_cast<QQuickApplicationWindow *>(window)) - window->removeEventFilter(q); if (focus) { // The setFocus(false) call below removes any active focus before we're // able to check it in finalizeExitTransition. @@ -1837,13 +1827,6 @@ bool QQuickPopup::isComponentComplete() const return d->complete; } -bool QQuickPopup::eventFilter(QObject *object, QEvent *event) -{ - if (QQuickWindow *window = qobject_cast<QQuickWindow *>(object)) - return overlayEvent(window->contentItem(), event); - return false; -} - bool QQuickPopup::childMouseEventFilter(QQuickItem *child, QEvent *event) { Q_UNUSED(child); diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index be6a8e22..9ef5c64b 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -334,7 +334,6 @@ protected: void componentComplete() override; bool isComponentComplete() const; - bool eventFilter(QObject *object, QEvent *event) override; virtual bool childMouseEventFilter(QQuickItem *child, QEvent *event); virtual void focusInEvent(QFocusEvent *event); virtual void focusOutEvent(QFocusEvent *event); diff --git a/tests/auto/popup/data/window.qml b/tests/auto/popup/data/window.qml new file mode 100644 index 00000000..92bfbd70 --- /dev/null +++ b/tests/auto/popup/data/window.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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.6 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + width: 400 + height: 400 + + property alias popup: popup + property alias popup2: popup2 + property alias button: button + + Button { + id: button + text: "Open" + anchors.centerIn: parent + anchors.verticalCenterOffset: -height + + Popup { + id: popup + y: parent.height + + Text { + color: "white" + text: "Hello, world!" + + MouseArea { + anchors.fill: parent + onClicked: popup.close() + } + } + } + } + + Popup { + id: popup2 + y: popup.y + z: 1 + contentItem: Text { + text: "Popup2" + font.pixelSize: 36 + } + } +} diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp index abd20df0..ef649187 100644 --- a/tests/auto/popup/tst_popup.cpp +++ b/tests/auto/popup/tst_popup.cpp @@ -51,8 +51,11 @@ class tst_popup : public QQmlDataTest Q_OBJECT private slots: + void visible_data(); void visible(); + void overlay_data(); void overlay(); + void zOrder_data(); void zOrder(); void windowChange(); void closePolicy_data(); @@ -64,46 +67,67 @@ private slots: void parentDestroyed(); }; +void tst_popup::visible_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + void tst_popup::visible() { - QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QFETCH(QString, source); + QQuickApplicationHelper helper(this, source); - QQuickApplicationWindow *window = helper.appWindow; + QQuickWindow *window = helper.window; window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QQuickPopup *popup = helper.appWindow->property("popup").value<QQuickPopup*>(); + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); QVERIFY(popup); QQuickItem *popupItem = popup->popupItem(); popup->open(); QVERIFY(popup->isVisible()); - QVERIFY(window->overlay()->childItems().contains(popupItem)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + QVERIFY(overlay->childItems().contains(popupItem)); popup->close(); QVERIFY(!popup->isVisible()); - QVERIFY(!window->overlay()->childItems().contains(popupItem)); + QVERIFY(!overlay->childItems().contains(popupItem)); popup->setVisible(true); QVERIFY(popup->isVisible()); - QVERIFY(window->overlay()->childItems().contains(popupItem)); + QVERIFY(overlay->childItems().contains(popupItem)); popup->setVisible(false); QVERIFY(!popup->isVisible()); - QVERIFY(!window->overlay()->childItems().contains(popupItem)); + QVERIFY(!overlay->childItems().contains(popupItem)); +} + +void tst_popup::overlay_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; } void tst_popup::overlay() { - QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QFETCH(QString, source); + QQuickApplicationHelper helper(this, source); - QQuickApplicationWindow *window = helper.appWindow; + QQuickWindow *window = helper.window; window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QQuickItem *overlay = window->overlay(); + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + QSignalSpy overlayPressedSignal(overlay, SIGNAL(pressed())); QSignalSpy overlayReleasedSignal(overlay, SIGNAL(released())); QVERIFY(overlayPressedSignal.isValid()); @@ -115,10 +139,10 @@ void tst_popup::overlay() QCOMPARE(overlayPressedSignal.count(), 0); QCOMPARE(overlayReleasedSignal.count(), 0); - QQuickPopup *popup = helper.appWindow->property("popup").value<QQuickPopup*>(); + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); QVERIFY(popup); - QQuickButton *button = helper.appWindow->property("button").value<QQuickButton*>(); + QQuickButton *button = window->property("button").value<QQuickButton*>(); QVERIFY(button); popup->open(); @@ -156,20 +180,28 @@ void tst_popup::overlay() QVERIFY(!overlay->isVisible()); } +void tst_popup::zOrder_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + void tst_popup::zOrder() { - QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QFETCH(QString, source); + QQuickApplicationHelper helper(this, source); - QQuickApplicationWindow *window = helper.appWindow; + QQuickWindow *window = helper.window; window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QQuickPopup *popup = helper.appWindow->property("popup").value<QQuickPopup*>(); + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); QVERIFY(popup); popup->setModal(true); - QQuickPopup *popup2 = helper.appWindow->property("popup2").value<QQuickPopup*>(); + QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup*>(); QVERIFY(popup2); popup2->setModal(true); @@ -220,32 +252,42 @@ void tst_popup::closePolicy_data() { qRegisterMetaType<QQuickPopup::ClosePolicy>(); + QTest::addColumn<QString>("source"); QTest::addColumn<QQuickPopup::ClosePolicy>("closePolicy"); - QTest::newRow("NoAutoClose") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose); - QTest::newRow("CloseOnPressOutside") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside); - QTest::newRow("CloseOnPressOutsideParent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent); - QTest::newRow("CloseOnPressOutside|Parent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); - QTest::newRow("CloseOnReleaseOutside") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); - QTest::newRow("CloseOnReleaseOutside|Parent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); - QTest::newRow("CloseOnEscape") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape); + QTest::newRow("Window:NoAutoClose") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose); + QTest::newRow("Window:CloseOnPressOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside); + QTest::newRow("Window:CloseOnPressOutsideParent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("Window:CloseOnPressOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("Window:CloseOnReleaseOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("Window:CloseOnReleaseOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + QTest::newRow("Window:CloseOnEscape") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape); + + QTest::newRow("ApplicationWindow:NoAutoClose") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose); + QTest::newRow("ApplicationWindow:CloseOnPressOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside); + QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnEscape") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape); } void tst_popup::closePolicy() { + QFETCH(QString, source); QFETCH(QQuickPopup::ClosePolicy, closePolicy); - QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QQuickApplicationHelper helper(this, source); - QQuickApplicationWindow *window = helper.appWindow; + QQuickWindow *window = helper.window; window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QQuickPopup *popup = helper.appWindow->property("popup").value<QQuickPopup*>(); + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); QVERIFY(popup); - QQuickButton *button = helper.appWindow->property("button").value<QQuickButton*>(); + QQuickButton *button = window->property("button").value<QQuickButton*>(); QVERIFY(button); popup->setModal(true); |