diff options
-rw-r--r-- | src/quickwidgets/qquickwidget.cpp | 33 | ||||
-rw-r--r-- | tests/auto/quickwidgets/qquickwidget/data/resizeOverlay.qml | 15 | ||||
-rw-r--r-- | tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp | 70 |
3 files changed, 109 insertions, 9 deletions
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 8ecfbf65dd..35cf06927a 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -107,6 +107,7 @@ void QQuickWidgetPrivate::init(QQmlEngine* e) renderControl = new QQuickWidgetRenderControl(q); offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl); offscreenWindow->setTitle(QString::fromLatin1("Offscreen")); + offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow")); // Do not call create() on offscreenWindow. // Check if the Software Adaptation is being used @@ -802,15 +803,29 @@ void QQuickWidgetPrivate::updateSize() q->updateGeometry(); } } else if (resizeMode == QQuickWidget::SizeRootObjectToView) { - bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width()); - bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height()); - - if (needToUpdateWidth && needToUpdateHeight) - root->setSize(QSizeF(q->width(), q->height())); - else if (needToUpdateWidth) - root->setWidth(q->width()); - else if (needToUpdateHeight) - root->setHeight(q->height()); + const bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width()); + const bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height()); + + if (needToUpdateWidth && needToUpdateHeight) { + // Make sure that we have realistic sizing behavior by following + // what on-screen windows would do and resize everything, not just + // the root item. We do this because other types may be relying on + // us to behave correctly. + const QSizeF newSize(q->width(), q->height()); + offscreenWindow->resize(newSize.toSize()); + offscreenWindow->contentItem()->setSize(newSize); + root->setSize(newSize); + } else if (needToUpdateWidth) { + const int newWidth = q->width(); + offscreenWindow->setWidth(newWidth); + offscreenWindow->contentItem()->setWidth(newWidth); + root->setWidth(newWidth); + } else if (needToUpdateHeight) { + const int newHeight = q->height(); + offscreenWindow->setHeight(newHeight); + offscreenWindow->contentItem()->setHeight(newHeight); + root->setHeight(newHeight); + } } } diff --git a/tests/auto/quickwidgets/qquickwidget/data/resizeOverlay.qml b/tests/auto/quickwidgets/qquickwidget/data/resizeOverlay.qml new file mode 100644 index 0000000000..5547856941 --- /dev/null +++ b/tests/auto/quickwidgets/qquickwidget/data/resizeOverlay.qml @@ -0,0 +1,15 @@ +import QtQuick 2.15 + +import Test 1.0 + +Item { + id: root + + property alias overlay: overlay + + Overlay { + id: overlay + // Parent it to the contentItem of the underlying QQuickWindow. + parent: root.parent + } +} diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 691dfd1bc6..12c51caa75 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -33,6 +33,7 @@ #include <QtQml/qqmlcontext.h> #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickitem_p.h> #include "../../shared/util.h" #include <QtGui/QWindow> #include <QtGui/QScreen> @@ -142,6 +143,7 @@ private slots: void synthMouseFromTouch_data(); void synthMouseFromTouch(); void tabKey(); + void resizeOverlay(); private: QTouchDevice *device = QTest::createTouchDevice(); @@ -662,6 +664,74 @@ void tst_qquickwidget::tabKey() QVERIFY(middleItem->property("activeFocus").toBool()); } +class Overlay : public QQuickItem, public QQuickItemChangeListener +{ + Q_OBJECT + +public: + Overlay() = default; + + ~Overlay() + { + QQuickItemPrivate::get(parentItem())->removeItemChangeListener(this, QQuickItemPrivate::Geometry); + } + + // componentCompleted() is too early to add the listener, as parentItem() + // is still null by that stage, so we use this function instead. + void startListening() + { + QQuickItemPrivate::get(parentItem())->addItemChangeListener(this, QQuickItemPrivate::Geometry); + } + +private: + virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &/*oldGeometry*/) override + { + auto window = QQuickItemPrivate::get(this)->window; + if (!window) + return; + + setSize(window->size()); + } +}; + +// Test that an item that resizes itself based on the window size can use a +// Geometry item change listener to respond to changes in size. This is a +// simplified test to mimic a use case involving Overlay from Qt Quick Controls 2. +void tst_qquickwidget::resizeOverlay() +{ + QWidget widget; + auto contentVerticalLayout = new QVBoxLayout(&widget); + contentVerticalLayout->setMargin(0); + + qmlRegisterType<Overlay>("Test", 1, 0, "Overlay"); + + auto quickWidget = new QQuickWidget(testFileUrl("resizeOverlay.qml"), &widget); + QCOMPARE(quickWidget->status(), QQuickWidget::Ready); + quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + contentVerticalLayout->addWidget(quickWidget); + + auto rootItem = qobject_cast<QQuickItem*>(quickWidget->rootObject()); + QVERIFY(rootItem); + + auto overlay = rootItem->property("overlay").value<Overlay*>(); + QVERIFY(overlay); + QVERIFY(overlay->parentItem()); + overlay->startListening(); + + widget.resize(200, 200); + widget.show(); + QCOMPARE(rootItem->width(), 200); + QCOMPARE(rootItem->height(), 200); + QCOMPARE(overlay->width(), rootItem->width()); + QCOMPARE(overlay->height(), rootItem->height()); + + widget.resize(300, 300); + QCOMPARE(rootItem->width(), 300); + QCOMPARE(rootItem->height(), 300); + QCOMPARE(overlay->width(), rootItem->width()); + QCOMPARE(overlay->height(), rootItem->height()); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" |