aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-02-13 01:03:07 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-02-13 13:09:47 +0100
commitd5a5e9dcd594e2d2f3dbb05fdb0baf56cc50774d (patch)
tree4c6979394422c97dc21bc8b6e7852e1998eafb25 /src
parent229e3220ef521dd4389808fd311ea5ae33ab0cae (diff)
parentac0ce38dcfeeded87db0c1dd5d348f5ed6fc1af3 (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
Conflicts: src/qml/jsruntime/qv4engine.cpp Change-Id: I61f41672e2dfe7e542ca30fed5f173d0a9ee3412
Diffstat (limited to 'src')
-rw-r--r--src/imports/layouts/qquicklayout.cpp21
-rw-r--r--src/imports/layouts/qquicklayout_p.h4
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp10
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h4
-rw-r--r--src/qml/jsruntime/qv4engine.cpp40
-rw-r--r--src/qml/qml/qqmlproperty.cpp9
-rw-r--r--src/qml/types/qqmlconnections.cpp3
-rw-r--r--src/quick/accessible/qaccessiblequickview.cpp8
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc1
-rw-r--r--src/quick/items/qquickloader.cpp93
-rw-r--r--src/quick/items/qquickloader_p_p.h7
-rw-r--r--src/quick/items/qquickwindow.cpp2
-rw-r--r--src/quick/quick.pro5
13 files changed, 134 insertions, 73 deletions
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 1ca4056ba9..33c27bd928 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -700,8 +700,10 @@ QQuickItem *QQuickLayoutAttached::item() const
QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
- : QQuickItem(dd, parent),
- m_dirty(false)
+ : QQuickItem(dd, parent)
+ , m_dirty(false)
+ , m_inUpdatePolish(false)
+ , m_polishInsideUpdatePolish(0)
{
}
@@ -728,7 +730,9 @@ QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object)
void QQuickLayout::updatePolish()
{
+ m_inUpdatePolish = true;
rearrange(QSizeF(width(), height()));
+ m_inUpdatePolish = false;
}
void QQuickLayout::componentComplete()
@@ -749,7 +753,18 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
if (!qobject_cast<QQuickLayout *>(parentItem())) {
quickLayoutDebug() << "QQuickLayout::invalidate(), polish()";
- polish();
+
+ if (m_inUpdatePolish)
+ ++m_polishInsideUpdatePolish;
+ else
+ m_polishInsideUpdatePolish = 0;
+
+ if (m_polishInsideUpdatePolish <= 2)
+ // allow at most two consecutive loops in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ polish();
+ else
+ qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations.";
}
}
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index cb46c41e6c..3322d03636 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -123,7 +123,9 @@ protected slots:
void invalidateSenderItem();
private:
- bool m_dirty;
+ unsigned m_dirty : 1;
+ unsigned m_inUpdatePolish : 1;
+ unsigned m_polishInsideUpdatePolish : 2;
Q_DECLARE_PRIVATE(QQuickLayout)
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index d89e575372..1004ed8593 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -469,6 +469,16 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
if (!isReady())
return;
+ const auto refCounter = qScopeGuard([&d] {
+ --(d->m_recurRearrangeCounter);
+ });
+ if (d->m_recurRearrangeCounter++ == 2) {
+ // allow a recursive depth of two in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ qWarning() << "Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.";
+ return;
+ }
+
d->m_rearranging = true;
quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
Qt::LayoutDirection visualDir = effectiveLayoutDirection();
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index 634e51a048..f36f99741d 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -106,7 +106,8 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate
Q_DECLARE_PUBLIC(QQuickGridLayoutBase)
public:
- QQuickGridLayoutBasePrivate() : m_rearranging(false)
+ QQuickGridLayoutBasePrivate() : m_recurRearrangeCounter(0)
+ , m_rearranging(false)
, m_updateAfterRearrange(false)
, m_layoutDirection(Qt::LeftToRight)
{}
@@ -119,6 +120,7 @@ public:
QQuickGridLayoutEngine engine;
Qt::Orientation orientation;
+ unsigned m_recurRearrangeCounter : 2;
unsigned m_rearranging : 1;
unsigned m_updateAfterRearrange : 1;
QVector<QQuickItem *> m_invalidateAfterRearrange;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 0b2d657141..a900e710c2 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1519,27 +1519,29 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (succeeded)
return retn;
#endif
- retn = QVariant(typeHint, QMetaType::create(typeHint));
- auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
- if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
- auto const length = a->getLength();
- QV4::ScopedValue arrayValue(scope);
- for (qint64 i = 0; i < length; ++i) {
- arrayValue = a->get(i);
- QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects);
- auto originalType = asVariant.userType();
- bool couldConvert = asVariant.convert(retnAsIterable._metaType_id);
- if (!couldConvert) {
- qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3")
- .arg(QString::number(i),
- QString::fromUtf8(QMetaType::typeName(originalType)),
- QString::fromUtf8(QMetaType::typeName(retnAsIterable._metaType_id)));
- // create default constructed value
- asVariant = QVariant(retnAsIterable._metaType_id, nullptr);
+ if (typeHint != -1) {
+ retn = QVariant(typeHint, QMetaType::create(typeHint));
+ auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
+ auto const length = a->getLength();
+ QV4::ScopedValue arrayValue(scope);
+ for (qint64 i = 0; i < length; ++i) {
+ arrayValue = a->get(i);
+ QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects);
+ auto originalType = asVariant.userType();
+ bool couldConvert = asVariant.convert(retnAsIterable._metaType_id);
+ if (!couldConvert) {
+ qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3")
+ .arg(QString::number(i),
+ QMetaType::typeName(originalType),
+ QMetaType::typeName(retnAsIterable._metaType_id));
+ // create default constructed value
+ asVariant = QVariant(retnAsIterable._metaType_id, nullptr);
+ }
+ retnAsIterable.append(asVariant.constData());
}
- retnAsIterable.append(asVariant.constData());
+ return retn;
}
- return retn;
}
}
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 92fb6209af..8521de6ab3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -353,10 +353,15 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (terminal.count() >= 3 &&
terminal.at(0) == QLatin1Char('o') &&
terminal.at(1) == QLatin1Char('n') &&
- terminal.at(2).isUpper()) {
+ (terminal.at(2).isUpper() || terminal.at(2) == '_')) {
QString signalName = terminal.mid(2).toString();
- signalName[0] = signalName.at(0).toLower();
+ int firstNon_;
+ int length = signalName.length();
+ for (firstNon_ = 0; firstNon_ < length; ++firstNon_)
+ if (signalName.at(firstNon_) != '_')
+ break;
+ signalName[firstNon_] = signalName.at(firstNon_).toLower();
// XXX - this code treats methods as signals
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 1e801641e5..4c44bba43e 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -238,7 +238,8 @@ void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableC
const QV4::CompiledData::Binding *binding = props.at(ii);
const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);
- if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) {
+ const bool thirdCharacterIsValid = (propName.length() >= 2) && (propName.at(2).isUpper() || propName.at(2) == '_');
+ if (!propName.startsWith(QLatin1String("on")) || !thirdCharacterIsValid) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return;
}
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index 41a02fc09c..b23b0316f5 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -84,8 +84,12 @@ QAccessibleInterface *QAccessibleQuickWindow::child(int index) const
QAccessibleInterface *QAccessibleQuickWindow::focusChild() const
{
QObject *focusObject = window()->focusObject();
- if (focusObject)
- return QAccessible::queryAccessibleInterface(focusObject);
+ if (focusObject) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(focusObject);
+ if (!iface || iface == this || !iface->focusChild())
+ return iface;
+ return iface->focusChild();
+ }
return nullptr;
}
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 418475f100..528444cad3 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -179,6 +179,7 @@ available when you import \c QtQuick.
\li \l bool \c font.kerning
\li \l bool \c font.preferShaping
\li \l enumeration \c font.hintingPreference
+ \li \l string \c font.styleName
\endlist
Example:
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8722a45373..1fb71272b1 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -56,7 +56,7 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges
QQuickLoaderPrivate::QQuickLoaderPrivate()
: item(nullptr), object(nullptr), itemContext(nullptr), incubator(nullptr), updatingSize(false),
- active(true), loadingFromSource(false), asynchronous(false)
+ active(true), loadingFromSource(false), asynchronous(false), status(computeStatus())
{
}
@@ -379,7 +379,7 @@ void QQuickLoader::setActive(bool newVal)
d->object = nullptr;
emit itemChanged();
}
- emit statusChanged();
+ d->updateStatus();
}
emit activeChanged();
}
@@ -432,7 +432,7 @@ void QQuickLoader::loadFromSource()
Q_D(QQuickLoader);
if (d->source.isEmpty()) {
emit sourceChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -503,7 +503,7 @@ void QQuickLoader::loadFromSourceComponent()
Q_D(QQuickLoader);
if (!d->component) {
emit sourceComponentChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -619,7 +619,7 @@ void QQuickLoaderPrivate::load()
q, SLOT(_q_sourceLoaded()));
QObject::connect(component, SIGNAL(progressChanged(qreal)),
q, SIGNAL(progressChanged()));
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (loadingFromSource)
emit q->sourceChanged();
@@ -707,7 +707,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (status == QQmlIncubator::Ready)
emit q->loaded();
@@ -724,7 +724,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
emit q->itemChanged(); //Like clearing source, emit itemChanged even if previous item was also null
disposeInitialPropertyValues(); // cleanup
@@ -742,7 +742,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
component->create(*incubator, itemContext);
if (incubator && incubator->status() == QQmlIncubator::Loading)
- emit q->statusChanged();
+ updateStatus();
}
/*!
@@ -789,37 +789,7 @@ QQuickLoader::Status QQuickLoader::status() const
{
Q_D(const QQuickLoader);
- if (!d->active)
- return Null;
-
- if (d->component) {
- switch (d->component->status()) {
- case QQmlComponent::Loading:
- return Loading;
- case QQmlComponent::Error:
- return Error;
- case QQmlComponent::Null:
- return Null;
- default:
- break;
- }
- }
-
- if (d->incubator) {
- switch (d->incubator->status()) {
- case QQmlIncubator::Loading:
- return Loading;
- case QQmlIncubator::Error:
- return Error;
- default:
- break;
- }
- }
-
- if (d->object)
- return Ready;
-
- return d->source.isEmpty() ? Null : Error;
+ return static_cast<Status>(d->status);
}
void QQuickLoader::componentComplete()
@@ -1020,6 +990,51 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
return valuemap->asReturnedValue();
}
+QQuickLoader::Status QQuickLoaderPrivate::computeStatus() const
+{
+ if (!active)
+ return QQuickLoader::Status::Null;
+
+ if (component) {
+ switch (component->status()) {
+ case QQmlComponent::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlComponent::Error:
+ return QQuickLoader::Status::Error;
+ case QQmlComponent::Null:
+ return QQuickLoader::Status::Null;
+ default:
+ break;
+ }
+ }
+
+ if (incubator) {
+ switch (incubator->status()) {
+ case QQmlIncubator::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlIncubator::Error:
+ return QQuickLoader::Status::Error;
+ default:
+ break;
+ }
+ }
+
+ if (object)
+ return QQuickLoader::Status::Ready;
+
+ return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
+}
+
+void QQuickLoaderPrivate::updateStatus()
+{
+ Q_Q(QQuickLoader);
+ auto newStatus = computeStatus();
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
#include <moc_qquickloader_p.cpp>
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 349b5c6c06..39d50280c5 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -96,6 +96,8 @@ public:
void disposeInitialPropertyValues();
static QUrl resolveSourceUrl(QQmlV4Function *args);
QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error);
+ QQuickLoader::Status computeStatus() const;
+ void updateStatus();
qreal getImplicitWidth() const override;
qreal getImplicitHeight() const override;
@@ -112,6 +114,11 @@ public:
bool active : 1;
bool loadingFromSource : 1;
bool asynchronous : 1;
+ // We need to use char instead of QQuickLoader::Status
+ // as otherwise the size of the class would increase
+ // on 32-bit systems, as sizeof(Status) == sizeof(int)
+ // and sizeof(int) > remaining padding on 32 bit
+ char status;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index dda0cfef3e..fa7c71e43a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -548,7 +548,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
else
context->endNextFrame(renderer);
- if (renderer->hasCustomRenderModeWithContinuousUpdate()) {
+ if (renderer && renderer->hasCustomRenderModeWithContinuousUpdate()) {
// For the overdraw visualizer. This update is not urgent so avoid a
// direct update() call, this is only here to keep the overdraw
// visualization box rotating even when the scene is static.
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 392a235b31..f2d49cf939 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -21,13 +21,10 @@ exists("qqml_enable_gcov") {
QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf
-ANDROID_LIB_DEPENDENCIES = \
- lib/libQt5QuickParticles.so
MODULE_PLUGIN_TYPES += \
scenegraph
ANDROID_BUNDLED_FILES += \
- qml \
- lib/libQt5QuickParticles.so
+ qml
include(util/util.pri)
include(scenegraph/scenegraph.pri)