Merge remote-tracking branch 'origin/5.12' into 5.13

Change-Id: I081bcb9cc238e6cff5f8a23b684c5d6f76dba047
This commit is contained in:
Qt Forward Merge Bot 2019-07-24 01:00:26 +02:00
commit 45023ae342
15 changed files with 178 additions and 12 deletions

View File

@ -471,7 +471,7 @@ will be accessible to the \e attachee:
class MessageBoardAttachedType : public QObject class MessageBoardAttachedType : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool expired READ expired WRITE expired NOTIFY expiredChanged) Q_PROPERTY(bool expired READ expired WRITE setExpired NOTIFY expiredChanged)
public: public:
MessageBoardAttachedType(QObject *parent); MessageBoardAttachedType(QObject *parent);
bool expired() const; bool expired() const;
@ -493,7 +493,7 @@ class MessageBoard : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static MessageBoard *qmlAttachedProperties(QObject *object) static MessageBoardAttachedType *qmlAttachedProperties(QObject *object)
{ {
return new MessageBoardAttachedType(object); return new MessageBoardAttachedType(object);
} }

View File

@ -465,9 +465,18 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports::
const QQmlDirComponents &components = import->qmlDirComponents; const QQmlDirComponents &components = import->qmlDirComponents;
const int importMajorVersion = import->majversion;
const int importMinorVersion = import->minversion;
auto shouldSkipSingleton = [importMajorVersion, importMinorVersion](int singletonMajorVersion, int singletonMinorVersion) -> bool {
return importMajorVersion != -1 &&
(singletonMajorVersion > importMajorVersion || (singletonMajorVersion == importMajorVersion && singletonMinorVersion > importMinorVersion));
};
ConstIterator cend = components.constEnd(); ConstIterator cend = components.constEnd();
for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) {
if (cit->singleton && excludeBaseUrl(import->url, cit->fileName, baseUrl.toString())) { if (cit->singleton && excludeBaseUrl(import->url, cit->fileName, baseUrl.toString())) {
if (shouldSkipSingleton(cit->majorVersion, cit->minorVersion))
continue;
QQmlImports::CompositeSingletonReference ref; QQmlImports::CompositeSingletonReference ref;
ref.typeName = cit->typeName; ref.typeName = cit->typeName;
ref.prefix = set.prefix; ref.prefix = set.prefix;
@ -478,7 +487,9 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports::
} }
if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) { if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) {
module->walkCompositeSingletons([&resultList, &set](const QQmlType &singleton) { module->walkCompositeSingletons([&resultList, &set, &shouldSkipSingleton](const QQmlType &singleton) {
if (shouldSkipSingleton(singleton.majorVersion(), singleton.minorVersion()))
return;
QQmlImports::CompositeSingletonReference ref; QQmlImports::CompositeSingletonReference ref;
ref.typeName = singleton.elementName(); ref.typeName = singleton.elementName();
ref.prefix = set.prefix; ref.prefix = set.prefix;

View File

@ -75,7 +75,7 @@ void QSGDefaultGlyphNode::update()
QMargins margins(0, 0, 0, 0); QMargins margins(0, 0, 0, 0);
if (m_style == QQuickText::Normal) { if (m_style == QQuickText::Normal) {
m_material = new QSGTextMaskMaterial(font); m_material = new QSGTextMaskMaterial(QVector4D(m_color.redF(), m_color.greenF(), m_color.blueF(), m_color.alphaF()), font);
} else if (m_style == QQuickText::Outline) { } else if (m_style == QQuickText::Outline) {
QSGOutlinedTextMaterial *material = new QSGOutlinedTextMaterial(font); QSGOutlinedTextMaterial *material = new QSGOutlinedTextMaterial(font);
material->setStyleColor(m_styleColor); material->setStyleColor(m_styleColor);

View File

@ -399,10 +399,11 @@ public:
} }
}; };
QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font, QFontEngine::GlyphFormat glyphFormat) QSGTextMaskMaterial::QSGTextMaskMaterial(const QVector4D &color, const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
: m_texture(nullptr) : m_texture(nullptr)
, m_glyphCache(nullptr) , m_glyphCache(nullptr)
, m_font(font) , m_font(font)
, m_color(color)
{ {
init(glyphFormat); init(glyphFormat);
} }
@ -412,12 +413,30 @@ QSGTextMaskMaterial::~QSGTextMaskMaterial()
delete m_texture; delete m_texture;
} }
void QSGTextMaskMaterial::setColor(const QVector4D &color)
{
if (m_color == color)
return;
m_color = color;
// If it is an RGB cache, then the pen color is actually part of the cache key
// so it has to be updated
if (m_glyphCache != nullptr && m_glyphCache->glyphFormat() == QFontEngine::Format_ARGB)
updateCache(QFontEngine::Format_ARGB);
}
void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat) void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat)
{ {
Q_ASSERT(m_font.isValid()); Q_ASSERT(m_font.isValid());
setFlag(Blending, true); setFlag(Blending, true);
updateCache(glyphFormat);
}
void QSGTextMaskMaterial::updateCache(QFontEngine::GlyphFormat glyphFormat)
{
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
Q_ASSERT(ctx != nullptr); Q_ASSERT(ctx != nullptr);
@ -437,20 +456,21 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat)
qreal devicePixelRatio = qsg_device_pixel_ratio(ctx); qreal devicePixelRatio = qsg_device_pixel_ratio(ctx);
QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio); QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio);
if (!fontEngine->supportsTransformation(glyphCacheTransform)) if (!fontEngine->supportsTransformation(glyphCacheTransform))
glyphCacheTransform = QTransform(); glyphCacheTransform = QTransform();
m_glyphCache = fontEngine->glyphCache(ctx, glyphFormat, glyphCacheTransform); QColor color = glyphFormat == QFontEngine::Format_ARGB ? QColor::fromRgbF(m_color.x(), m_color.y(), m_color.z(), m_color.w()) : QColor();
m_glyphCache = fontEngine->glyphCache(ctx, glyphFormat, glyphCacheTransform, color);
if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) {
m_glyphCache = new QOpenGLTextureGlyphCache(glyphFormat, glyphCacheTransform); m_glyphCache = new QOpenGLTextureGlyphCache(glyphFormat, glyphCacheTransform, color);
fontEngine->setGlyphCache(ctx, m_glyphCache.data()); fontEngine->setGlyphCache(ctx, m_glyphCache.data());
auto sg = QSGDefaultRenderContext::from(ctx); auto sg = QSGDefaultRenderContext::from(ctx);
Q_ASSERT(sg); Q_ASSERT(sg);
sg->registerFontengineForCleanup(fontEngine); sg->registerFontengineForCleanup(fontEngine);
} }
} }
} }
void QSGTextMaskMaterial::populate(const QPointF &p, void QSGTextMaskMaterial::populate(const QPointF &p,
@ -629,7 +649,7 @@ int QSGTextMaskMaterial::cacheTextureHeight() const
QSGStyledTextMaterial::QSGStyledTextMaterial(const QRawFont &font) QSGStyledTextMaterial::QSGStyledTextMaterial(const QRawFont &font)
: QSGTextMaskMaterial(font, QFontEngine::Format_A8) : QSGTextMaskMaterial(QVector4D(), font, QFontEngine::Format_A8)
{ {
} }

View File

@ -68,15 +68,15 @@ class Geometry;
class QSGTextMaskMaterial: public QSGMaterial class QSGTextMaskMaterial: public QSGMaterial
{ {
public: public:
QSGTextMaskMaterial(const QRawFont &font, QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None); QSGTextMaskMaterial(const QVector4D &color, const QRawFont &font, QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None);
virtual ~QSGTextMaskMaterial(); virtual ~QSGTextMaskMaterial();
QSGMaterialType *type() const override; QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override; QSGMaterialShader *createShader() const override;
int compare(const QSGMaterial *other) const override; int compare(const QSGMaterial *other) const override;
void setColor(const QColor &c) { m_color = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } void setColor(const QColor &c) { setColor(QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF())); }
void setColor(const QVector4D &color) { m_color = color; } void setColor(const QVector4D &color);
const QVector4D &color() const { return m_color; } const QVector4D &color() const { return m_color; }
QSGTexture *texture() const { return m_texture; } QSGTexture *texture() const { return m_texture; }
@ -94,6 +94,7 @@ public:
private: private:
void init(QFontEngine::GlyphFormat glyphFormat); void init(QFontEngine::GlyphFormat glyphFormat);
void updateCache(QFontEngine::GlyphFormat glyphFormat);
QSGPlainTexture *m_texture; QSGPlainTexture *m_texture;
QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache; QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;

View File

@ -0,0 +1,14 @@
import QtQuick 2.0
Rectangle {
width: 50
height: 50
color: "yellow"
Text {
anchors.centerIn: parent
text: "0.9"
}
}

View File

@ -0,0 +1,15 @@
import QtQuick 2.0
Rectangle {
width: 50
height: 50
color: "orange"
Text {
anchors.centerIn: parent
text: "1.0"
}
}

View File

@ -0,0 +1,7 @@
pragma Singleton
import QtQuick 2.0
Item {
property int baseWidth: 50
}

View File

@ -0,0 +1,6 @@
module MyPlugin
MyComponent 0.9 MyComponent_0_9.qml
MyComponent 1.0 MyComponent_1_0.qml
singleton MySettings 1.0 MySettings_1_0.qml

View File

@ -0,0 +1,11 @@
import QtQuick 2.12
import MyPlugin 0.9
Item {
width: MySettings.baseWidth
height: 100
MyComponent {
anchors.centerIn: parent
}
}

View File

@ -0,0 +1,11 @@
import QtQuick 2.12
import MyPlugin 0.9
Item {
width: 100
height: 100
MyComponent {
anchors.centerIn: parent
}
}

View File

@ -0,0 +1,11 @@
import QtQuick 2.12
import MyPlugin 1.0
Item {
width: MySettings.baseWidth
height: 100
MyComponent {
anchors.centerIn: parent
}
}

View File

@ -0,0 +1,11 @@
import QtQuick 2.12
import "imports/MyPlugin"
Item {
width: MySettings.baseWidth
height: 100
MyComponent {
anchors.centerIn: parent
}
}

View File

@ -45,6 +45,7 @@ private slots:
void completeQmldirPaths_data(); void completeQmldirPaths_data();
void completeQmldirPaths(); void completeQmldirPaths();
void interceptQmldir(); void interceptQmldir();
void singletonVersionResolution();
void cleanup(); void cleanup();
}; };
@ -212,6 +213,50 @@ void tst_QQmlImport::interceptQmldir()
QVERIFY(!obj.isNull()); QVERIFY(!obj.isNull());
} }
// QTBUG-77102
void tst_QQmlImport::singletonVersionResolution()
{
QQmlEngine engine;
engine.addImportPath(testFile("QTBUG-77102/imports"));
{
// Singleton with higher version is simply ignored when importing lower version of plugin
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.qml"));
QVERIFY(component.isReady());
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
}
{
// but the singleton is not accessible
QQmlComponent component(&engine);
QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression {".*ReferenceError: MySettings is not defined$"} );
component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.fail.qml"));
QVERIFY(component.isReady());
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
}
{
// unless a version which is high enough is imported
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("QTBUG-77102/main.1.0.qml"));
QVERIFY(component.isReady());
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
auto item = qobject_cast<QQuickItem*>(obj.get());
QCOMPARE(item->width(), 50);
}
{
// or when there is no number because we are importing from a path
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("QTBUG-77102/main.nonumber.qml"));
QVERIFY(component.isReady());
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
auto item = qobject_cast<QQuickItem*>(obj.get());
QCOMPARE(item->width(), 50);
}
}
QTEST_MAIN(tst_QQmlImport) QTEST_MAIN(tst_QQmlImport)

View File

@ -1652,6 +1652,7 @@ void tst_qquickflickable::flickTwiceUsingTouches()
QQuickViewTestUtil::moveMouseAway(window.data()); QQuickViewTestUtil::moveMouseAway(window.data());
window->show(); window->show();
QVERIFY(window->rootObject() != nullptr); QVERIFY(window->rootObject() != nullptr);
QVERIFY(QTest::qWaitForWindowActive(window.data()));
QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
QVERIFY(flickable != nullptr); QVERIFY(flickable != nullptr);
@ -1994,6 +1995,7 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch()
QQuickViewTestUtil::moveMouseAway(window.data()); QQuickViewTestUtil::moveMouseAway(window.data());
window->show(); window->show();
QVERIFY(window->rootObject() != nullptr); QVERIFY(window->rootObject() != nullptr);
QVERIFY(QTest::qWaitForWindowActive(window.data()));
QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
QVERIFY(flickable != nullptr); QVERIFY(flickable != nullptr);
@ -2489,6 +2491,7 @@ void tst_qquickflickable::synchronousDrag()
QQuickViewTestUtil::moveMouseAway(window); QQuickViewTestUtil::moveMouseAway(window);
window->show(); window->show();
QVERIFY(window->rootObject() != nullptr); QVERIFY(window->rootObject() != nullptr);
QVERIFY(QTest::qWaitForWindowActive(window));
QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
QVERIFY(flickable != nullptr); QVERIFY(flickable != nullptr);