ApplicationWindow: respect explicitly set background size
4a2466ea07
made ApplicationWindow
explicitly set the background's width and height if they hadn't
already been explicitly set. However, in certain cases widthValid()
and heightValid() were checked before background's deferred execution
had completed. This meant that the user's width and height bindings
hadn't been evaluated yet, and hence widthValid and heightValid were
false.
Fix this by waiting until execution has finished before checking.
Fixes: QTBUG-124744
Pick-to: 6.5 6.6 6.7
Change-Id: I1007f638a60c1ae4e0b07dbf91d5583bbfdcf8fb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
f8b97e5af5
commit
a9e6cbb06e
|
@ -105,6 +105,7 @@ public:
|
|||
|
||||
QQmlListProperty<QObject> contentData();
|
||||
|
||||
void updateHasBackgroundFlags();
|
||||
void relayout();
|
||||
|
||||
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
|
||||
|
@ -172,6 +173,16 @@ static void layoutItem(QQuickItem *item, qreal y, qreal width)
|
|||
}
|
||||
}
|
||||
|
||||
void QQuickApplicationWindowPrivate::updateHasBackgroundFlags()
|
||||
{
|
||||
if (!background)
|
||||
return;
|
||||
|
||||
QQuickItemPrivate *backgroundPrivate = QQuickItemPrivate::get(background);
|
||||
hasBackgroundWidth = backgroundPrivate->widthValid();
|
||||
hasBackgroundHeight = backgroundPrivate->heightValid();
|
||||
}
|
||||
|
||||
void QQuickApplicationWindowPrivate::relayout()
|
||||
{
|
||||
Q_Q(QQuickApplicationWindow);
|
||||
|
@ -207,9 +218,7 @@ void QQuickApplicationWindowPrivate::itemGeometryChanged(QQuickItem *item, QQuic
|
|||
if (!insideRelayout && item == background && change.sizeChange()) {
|
||||
// Any time the background is resized (excluding our own resizing),
|
||||
// we should respect it if it's explicit by storing the values of the flags.
|
||||
QQuickItemPrivate *backgroundPrivate = QQuickItemPrivate::get(background);
|
||||
hasBackgroundWidth = backgroundPrivate->widthValid();
|
||||
hasBackgroundHeight = backgroundPrivate->heightValid();
|
||||
updateHasBackgroundFlags();
|
||||
}
|
||||
|
||||
relayout();
|
||||
|
@ -304,8 +313,12 @@ void QQuickApplicationWindowPrivate::executeBackground(bool complete)
|
|||
|
||||
if (!background || complete)
|
||||
quickBeginDeferred(q, backgroundName(), background);
|
||||
if (complete)
|
||||
if (complete) {
|
||||
quickCompleteDeferred(q, backgroundName(), background);
|
||||
// See comment in setBackground for why we do this here.
|
||||
updateHasBackgroundFlags();
|
||||
relayout();
|
||||
}
|
||||
}
|
||||
|
||||
QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent)
|
||||
|
@ -381,12 +394,15 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background)
|
|||
if (qFuzzyIsNull(background->z()))
|
||||
background->setZ(-1);
|
||||
|
||||
QQuickItemPrivate *backgroundPrivate = QQuickItemPrivate::get(background);
|
||||
d->hasBackgroundWidth = backgroundPrivate->widthValid();
|
||||
d->hasBackgroundHeight = backgroundPrivate->heightValid();
|
||||
// If the background hasn't finished executing then we don't know if its width and height
|
||||
// are valid or not, and so relayout would see that they haven't been set yet and override
|
||||
// any bindings the user might have.
|
||||
if (!d->background.isExecuting()) {
|
||||
d->updateHasBackgroundFlags();
|
||||
|
||||
if (isComponentComplete())
|
||||
d->relayout();
|
||||
if (isComponentComplete())
|
||||
d->relayout();
|
||||
}
|
||||
}
|
||||
if (!d->background.isExecuting())
|
||||
emit backgroundChanged();
|
||||
|
|
|
@ -9,6 +9,7 @@ ApplicationWindow {
|
|||
height: 400
|
||||
|
||||
background: Item {
|
||||
objectName: "background"
|
||||
implicitWidth: 123
|
||||
implicitHeight: 456
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
property real scaleFactor: 1
|
||||
|
||||
background: Rectangle {
|
||||
objectName: "background"
|
||||
color: "green"
|
||||
width: window.width * window.scaleFactor
|
||||
height: window.height * window.scaleFactor
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
#include <QtQuickTestUtils/private/qmlutils_p.h>
|
||||
#include <QtQuickTestUtils/private/visualtestutils_p.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickoverlay_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
|
||||
|
@ -53,6 +54,7 @@ private slots:
|
|||
void componentComplete();
|
||||
void opacity();
|
||||
void backgroundSize();
|
||||
void explicitBackgroundSizeBinding();
|
||||
};
|
||||
|
||||
tst_QQuickApplicationWindow::tst_QQuickApplicationWindow()
|
||||
|
@ -984,6 +986,23 @@ void tst_QQuickApplicationWindow::backgroundSize()
|
|||
QCOMPARE(background->height(), 678);
|
||||
}
|
||||
|
||||
void tst_QQuickApplicationWindow::explicitBackgroundSizeBinding()
|
||||
{
|
||||
QQuickControlsApplicationHelper helper(this, QLatin1String("explicitBackgroundSizeBinding.qml"));
|
||||
QVERIFY2(helper.ready, helper.failureMessage());
|
||||
QQuickApplicationWindow *window = helper.appWindow;
|
||||
window->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(window));
|
||||
|
||||
auto *background = window->background();
|
||||
QCOMPARE(background->width(), window->width());
|
||||
QCOMPARE(background->height(), window->height());
|
||||
|
||||
window->setProperty("scaleFactor", 0.5);
|
||||
QCOMPARE(background->width(), window->width() / 2);
|
||||
QCOMPARE(background->height(), window->height() / 2);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QQuickApplicationWindow)
|
||||
|
||||
#include "tst_qquickapplicationwindow.moc"
|
||||
|
|
Loading…
Reference in New Issue