diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-21 21:40:24 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-21 21:40:25 +0200 |
commit | 327b489bd7b137aa6bce5e16ba3d47fe3f33f33c (patch) | |
tree | 2bd5d38f28aaefd874943da90b2c2d78543a91dc | |
parent | 152bca765bab4ce55d4a649896c92c3d4a4f1b30 (diff) | |
parent | 6555642db7b3b992335f98dc01863db4beea3fd4 (diff) |
Merge remote-tracking branch 'origin/5.15' into 5.15.0
Change-Id: Iba61fff386b0d76e8d3dbb63e5b86ed8ee79d151
-rw-r--r-- | src/qml/qml/qqml.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlplatform.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltype.cpp | 2 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 23 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypescreator.cpp | 31 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 5 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp | 43 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrhisupport.cpp | 13 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob.cpp | 1 | ||||
-rw-r--r-- | tests/auto/qml/qmltyperegistrar/foreign/foreign.h | 7 | ||||
-rw-r--r-- | tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h | 30 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml | 20 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimations/tst_qquickanimations.cpp | 37 | ||||
-rw-r--r-- | tests/auto/quick/qquicktext/BLACKLIST | 2 |
16 files changed, 200 insertions, 32 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 4adf100a1f..1621e3c02e 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -735,10 +735,15 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } +#ifdef Q_QDOC +template <typename T> +int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback) +#else template <typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value && !std::is_convertible<F, QObject *(*)(QQmlEngine *, QJSEngine *)>::value, void>::type* = nullptr> inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, F&& callback) +#endif { QML_GETTYPENAMES diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 5823ff8963..872a448bfd 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -422,6 +422,7 @@ The following functions are also on the Qt object. \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows \li \c "winrt" - WinRT / UWP + \li \c "wasm" - WebAssembly \endlist \row diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp index 0acf20bbb4..c1ad5c0886 100644 --- a/src/qml/qml/qqmlplatform.cpp +++ b/src/qml/qml/qqmlplatform.cpp @@ -76,6 +76,8 @@ QString QQmlPlatform::os() return QStringLiteral("qnx"); #elif defined(Q_OS_UNIX) return QStringLiteral("unix"); +#elif defined(Q_OS_WASM) + return QStringLiteral("wasm"); #else return QStringLiteral("unknown"); #endif diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 96a35b0fe9..317d3c7ef5 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -276,7 +276,7 @@ void QQmlTypePrivate::initEnums(QQmlEnginePrivate *engine) const ? compositePropertyCache(engine) : nullptr; - const QMetaObject *metaObject = !isEnumFromCacheSetup + const QMetaObject *metaObject = !isEnumFromBaseSetup ? baseMetaObject // beware: It could be a singleton type without metaobject : nullptr; diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 7756fda9e4..9aadd75acc 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -62,6 +62,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &foreign, CollectMode mode) { + const QJsonObject *origClassDef = classDef; // if we find QML.Foreign, classDef changes. if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool()) file = classDef->value(QLatin1String("inputFile")).toString(); const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); @@ -130,21 +131,33 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, collectExtraVersions(classDef, QString::fromLatin1("signals"), revisions); } - const auto supers = classDef->value(QLatin1String("superClasses")).toArray(); - if (!supers.isEmpty()) { - const QJsonObject superObject = supers.first().toObject(); + auto supers = classDef->value(QLatin1String("superClasses")).toArray(); + if (classDef != origClassDef) { + const QJsonArray origSupers = origClassDef->value(QLatin1String("superClasses")).toArray(); + for (const QJsonValue &origSuper : origSupers) + supers.append(origSuper); + } + + for (const QJsonValue &superValue : qAsConst(supers)) { + const QJsonObject superObject = superValue.toObject(); if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) { const QString superName = superObject[QLatin1String("name")].toString(); - if (mode == TopLevel && superClass.isEmpty()) - superClass = superName; if (const QJsonObject *other = findType(types, superName)) collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType); else if (const QJsonObject *other = findType(foreign, superName)) collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType); + else // If we cannot locate a type for it, there is no point in recording the superClass + continue; + + if (mode == TopLevel && superClass.isEmpty()) + superClass = superName; } } + if (mode != TopLevel) + return; + if (addedInRevision == -1) { revisions.append(0); addedInRevision = 0; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 1119f88282..e74550c6c2 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -224,6 +224,19 @@ void QmlTypesCreator::writeEnums(const QJsonArray &enums) } } +static QJsonArray members(const QJsonObject *classDef, const QJsonObject *origClassDef, const QString &key) +{ + QJsonArray classDefMembers = classDef->value(key).toArray(); + + if (classDef != origClassDef) { + const QJsonArray origClassDefMembers = origClassDef->value(key).toArray(); + for (const auto &member : origClassDefMembers) + classDefMembers.append(member); + } + + return classDefMembers; +} + void QmlTypesCreator::writeComponents() { const QLatin1String nameKey("name"); @@ -259,15 +272,15 @@ void QmlTypesCreator::writeComponents() writeClassProperties(collector); const QJsonObject *classDef = collector.resolvedClass; - writeEnums(classDef->value(enumsKey).toArray()); + writeEnums(members(classDef, &component, enumsKey)); QSet<QString> notifySignals; - writeProperties(classDef->value(propertiesKey).toArray(), notifySignals); + writeProperties(members(classDef, &component, propertiesKey), notifySignals); if (collector.isRootClass) { // Hide destroyed() signals - QJsonArray componentSignals = classDef->value(signalsKey).toArray(); + QJsonArray componentSignals = members(classDef, &component, signalsKey); for (auto it = componentSignals.begin(); it != componentSignals.end();) { if (it->toObject().value(nameKey).toString() == destroyedName) it = componentSignals.erase(it); @@ -277,8 +290,10 @@ void QmlTypesCreator::writeComponents() writeMethods(componentSignals, signalElement, notifySignals); // Hide deleteLater() methods - QJsonArray componentMethods = classDef->value(methodsKey).toArray() - + classDef->value(slotsKey).toArray(); + QJsonArray componentMethods = members(classDef, &component, methodsKey); + const QJsonArray componentSlots = members(classDef, &component, slotsKey); + for (const QJsonValue &componentSlot : componentSlots) + componentMethods.append(componentSlot); for (auto it = componentMethods.begin(); it != componentMethods.end();) { if (it->toObject().value(nameKey).toString() == deleteLaterName) it = componentMethods.erase(it); @@ -312,9 +327,9 @@ void QmlTypesCreator::writeComponents() writeMethods(componentMethods, methodElement); } else { - writeMethods(classDef->value(signalsKey).toArray(), signalElement, notifySignals); - writeMethods(classDef->value(slotsKey).toArray(), methodElement); - writeMethods(classDef->value(methodsKey).toArray(), methodElement); + writeMethods(members(classDef, &component, signalsKey), signalElement, notifySignals); + writeMethods(members(classDef, &component, slotsKey), methodElement); + writeMethods(members(classDef, &component, methodsKey), methodElement); } m_qml.writeEndObject(); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 50b166b18f..48ba0ecc28 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -4889,6 +4889,11 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha) \note This function only has an effect when using the default OpenGL scene graph adaptation. + \note This function will only reset the OpenGL context in relation to what has been changed + internally as part of the OpenGL scene graph. It does not reset anything that has been changed + externally such as direct OpenGL calls done inside the application code if those same calls are + not used internally. + \note This function has no effect when running on the RHI graphics abstraction and the underlying RHI backend is not OpenGL. diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp index dd789b78c7..04e9b361ca 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qsgsoftwareglyphnode_p.h" +#include <QtGui/private/qrawfont_p.h> QT_BEGIN_NAMESPACE @@ -52,28 +53,38 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() namespace { QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs) { - qreal minX = 0; - qreal minY = 0; - qreal maxX = 0; - qreal maxY = 0; + QFixed minX; + QFixed minY; + QFixed maxX; + QFixed maxY; - for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) { - QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]); - glyphRect.translate(glyphs.positions()[i]); + QRawFontPrivate *rawFontD = QRawFontPrivate::get(glyphs.rawFont()); + QFontEngine *fontEngine = rawFontD->fontEngine; + + QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32; + + const QVector<uint> glyphIndexes = glyphs.glyphIndexes(); + const QVector<QPointF> glyphPositions = glyphs.positions(); + for (int i = 0, n = qMin(glyphIndexes.size(), glyphPositions.size()); i < n; ++i) { + glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyphIndexes.at(i), QFixed(), QTransform(), glyphFormat); + + gm.x += QFixed::fromReal(glyphPositions.at(i).x()); + gm.y += QFixed::fromReal(glyphPositions.at(i).y()); if (i == 0) { - minX = glyphRect.left(); - minY = glyphRect.top(); - maxX = glyphRect.right(); - maxY = glyphRect.bottom(); + minX = gm.x; + minY = gm.y; + maxX = gm.x + gm.width; + maxY = gm.y + gm.height; } else { - minX = qMin(glyphRect.left(), minX); - minY = qMin(glyphRect.top(), minY); - maxX = qMax(glyphRect.right(),maxX); - maxY = qMax(glyphRect.bottom(), maxY); + minX = qMin(gm.x, minX); + minY = qMin(gm.y, minY); + maxX = qMax(gm.x + gm.width, maxX); + maxY = qMax(gm.y + gm.height, maxY); } } - QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY)); + + QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal())); return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent())); } } diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp index 84a9669365..2bf70ddec6 100644 --- a/src/quick/scenegraph/qsgrhisupport.cpp +++ b/src/quick/scenegraph/qsgrhisupport.cpp @@ -38,7 +38,10 @@ ****************************************************************************/ #include "qsgrhisupport_p.h" -#include "qsgdefaultrendercontext_p.h" +#include "qsgcontext_p.h" +#if QT_CONFIG(opengl) +# include "qsgdefaultrendercontext_p.h" +#endif #include <QtGui/qwindow.h> #if QT_CONFIG(vulkan) @@ -383,9 +386,15 @@ static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, co } #endif -const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const QSGDefaultRenderContext *rc) +const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, + const QSGDefaultRenderContext *rc) { +#if QT_CONFIG(opengl) QRhi *rhi = rc->rhi(); +#else + Q_UNUSED(rc) + QRhi *rhi = nullptr; +#endif if (res == QSGRendererInterface::RhiResource || !rhi) return rhi; diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 0112a4b337..767be96403 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -582,6 +582,7 @@ void QQuickOpacityAnimatorJob::postSync() } d->extra.value().opacityNode = m_opacityNode; + updateCurrentTime(0); } Q_ASSERT(m_opacityNode); } diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h index d5e5a060b4..dc9fbc84a8 100644 --- a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h +++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h @@ -30,6 +30,7 @@ #define FOREIGN_H #include <QtCore/qobject.h> +#include <QtCore/qsize.h> class Foreign : public QObject { @@ -49,4 +50,10 @@ private: int m_things = 0; }; +class SizeGadget : public QSize +{ + Q_GADGET + Q_PROPERTY(int height READ height WRITE setHeight FINAL) +}; + #endif // FOREIGN_H diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp index b3304963d8..1cfcd689c6 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp @@ -65,4 +65,14 @@ void tst_qmltyperegistrar::qmltypesHasFlags() QVERIFY(qmltypesData.contains("isFlag: true")); } +void tst_qmltyperegistrar::superAndForeignTypes() +{ + QVERIFY(qmltypesData.contains("values: [\"Pixel\", \"Centimeter\", \"Inch\", \"Point\"]")); + QVERIFY(qmltypesData.contains("name: \"SizeGadget\"")); + QVERIFY(qmltypesData.contains("prototype: \"SizeEnums\"")); + QVERIFY(qmltypesData.contains("Property { name: \"height\"; type: \"int\" }")); + QVERIFY(qmltypesData.contains("Property { name: \"width\"; type: \"int\" }")); + QVERIFY(qmltypesData.contains("Method { name: \"sizeToString\"; type: \"string\" }")); +} + QTEST_MAIN(tst_qmltyperegistrar) diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h index 07a28e1976..09485ab0b6 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h @@ -33,6 +33,35 @@ #include <QtQml/qqml.h> +class SizeEnums +{ + Q_GADGET + QML_NAMED_ELEMENT(SizeEnums) + QML_UNCREATABLE("Element is not creatable.") + +public: + enum Unit { Pixel, Centimeter, Inch, Point }; + Q_ENUM(Unit) +}; + +class SizeValueType : public SizeEnums +{ + QSize v; + Q_GADGET + Q_PROPERTY(int width READ width WRITE setWidth FINAL) + QML_NAMED_ELEMENT(MySize) + QML_FOREIGN(SizeGadget) + +public: + Q_INVOKABLE QString sizeToString() const + { + return QString::fromLatin1("%1x%2").arg(v.width()).arg(v.height()); + } + + int width() const { return v.width(); } + void setWidth(int width) { v.setWidth(width); } +}; + class Local : public Foreign { Q_OBJECT @@ -58,6 +87,7 @@ private slots: void qmltypesHasHppClassAndNoext(); void qmltypesHasFileNames(); void qmltypesHasFlags(); + void superAndForeignTypes(); private: QByteArray qmltypesData; diff --git a/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml b/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml new file mode 100644 index 0000000000..bfb8211706 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml @@ -0,0 +1,20 @@ +import QtQuick 2.14 +import QtQuick.Window 2.14 + +Window { + width: 640 + height: 480 + Rectangle { + id: rect + width: 200 + height: 200 + color: "black" + OpacityAnimator { + target: rect + from: 0 + to: 1 + duration: 1000 + running: true + } + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index e62d49ed6b..b4eb33eb7a 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -114,6 +114,7 @@ private slots: void replacingTransitions(); void animationJobSelfDestruction(); void fastFlickingBug(); + void opacityAnimationFromZero(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1858,6 +1859,42 @@ void tst_qquickanimations::fastFlickingBug() } } +void tst_qquickanimations::opacityAnimationFromZero() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms"); + + // not easy to verify this in threaded render loop + // since it's difficult to capture the first frame when scene graph + // is renderred in another thread + qputenv("QSG_RENDER_LOOP", "basic"); + auto cleanup = qScopeGuard([]() { qputenv("QSG_RENDER_LOOP", ""); }); + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("opacityAnimationFromZero.qml")); + QScopedPointer<QQuickWindow> win(qobject_cast<QQuickWindow*>(c.create())); + if (!c.errors().isEmpty()) + qDebug() << c.errorString(); + QVERIFY(win); + win->setTitle(QTest::currentTestFunction()); + win->show(); + QVERIFY(QTest::qWaitForWindowExposed(win.data())); + + QImage img; + bool firstFrameSwapped = false; + QObject::connect(win.get(), &QQuickWindow::frameSwapped, win.get(), [&win, &img, &firstFrameSwapped]() { + if (firstFrameSwapped) + return; + else + firstFrameSwapped = true; + img = win->grabWindow(); + if (img.width() < win->width()) + QSKIP("Skipping due to grabWindow not functional"); + }); + QTRY_VERIFY(!img.isNull() && img.pixel(100, 100) > qRgb(10, 10, 10)); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST index 08a5249e2e..f50276a4f1 100644 --- a/tests/auto/quick/qquicktext/BLACKLIST +++ b/tests/auto/quick/qquicktext/BLACKLIST @@ -4,3 +4,5 @@ qemu macos [fontSizeMode] opensuse-42.1 +[hAlignVisual] +sles |