aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quickwidgets/qquickwidget.cpp33
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/resizeOverlay.qml15
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp70
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"