diff options
author | Liang Qi <liang.qi@qt.io> | 2018-05-04 09:28:23 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-05-04 10:08:56 +0200 |
commit | 2044d0a03bafa4597863eb2bf3ecb8fa6731ed57 (patch) | |
tree | 5f2c0d44742770dfcc1dabf1efd8021b21cfeba4 /src | |
parent | 7b0cb855edcfdeb04e7d0d1c2545958877481ecc (diff) | |
parent | 717b57a9aae4c6d45cbcf91d390e42af56ab8061 (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts:
src/qml/qml/qqmltypeloader.cpp
src/qml/qml/qqmltypeloader_p.h
Done-with: Simon Hausmann <simon.hausmann@qt.io>
Task-number: QTBUG-68091
Change-Id: I7c0ab3c9446ac50da07b58f54e24eb4587f7f28c
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlcontext.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlcontext_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 28 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 6 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 7 | ||||
-rw-r--r-- | src/qmldebug/qqmlprofilerclientdefinitions_p.h | 11 | ||||
-rw-r--r-- | src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc | 1 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp | 11 |
10 files changed, 68 insertions, 24 deletions
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 5dd3278b4c..3dcfa92416 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -536,7 +536,7 @@ QQmlContextData::QQmlContextData() QQmlContextData::QQmlContextData(QQmlContext *ctxt) : engine(nullptr), isInternal(false), isJSContext(false), isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false), - publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1), + stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1), contextObject(nullptr), nextChild(nullptr), prevChild(nullptr), expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0), componentAttached(nullptr) @@ -577,7 +577,10 @@ void QQmlContextData::invalidate() while (childContexts) { Q_ASSERT(childContexts != this); - childContexts->invalidate(); + if (childContexts->stronglyReferencedByParent && !--childContexts->refCount) + childContexts->destroy(); + else + childContexts->invalidate(); } if (prevChild) { @@ -672,12 +675,16 @@ void QQmlContextData::destroy() delete this; } -void QQmlContextData::setParent(QQmlContextData *p) +void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent) { if (p == parent) return; if (p) { + Q_ASSERT(!parent); parent = p; + this->stronglyReferencedByParent = stronglyReferencedByParent; + if (stronglyReferencedByParent) + ++refCount; // balanced in QQmlContextData::invalidate() engine = p->engine; nextChild = p->childContexts; if (nextChild) nextChild->prevChild = &nextChild; diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index 5dfee48848..290b7fc7ee 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -126,7 +126,7 @@ public: QQmlContextData *parent = nullptr; QQmlEngine *engine; - void setParent(QQmlContextData *); + void setParent(QQmlContextData *, bool stronglyReferencedByParent = false); void refreshExpressions(); void addObject(QObject *); @@ -144,7 +144,8 @@ public: quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name quint32 hasEmittedDestruction:1; quint32 isRootObjectInCreation:1; - quint32 dummy:26; + quint32 stronglyReferencedByParent:1; + quint32 dummy:25; QQmlContext *publicContext; // The incubator that is constructing this context if any diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 6429e06070..60617630d2 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1217,9 +1217,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } ddata = QQmlData::get(instance, /*create*/true); - ddata->lineNumber = obj->location.line; - ddata->columnNumber = obj->location.column; } + ddata->lineNumber = obj->location.line; + ddata->columnNumber = obj->location.column; ddata->setImplicitDestructible(); if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) { diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 29ca10714f..e295c055e7 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1641,14 +1641,24 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const return &QQmlEnginePrivate::get(engine())->importDatabase; } +QUrl QQmlTypeLoader::normalize(const QUrl &unNormalizedUrl) +{ + QUrl normalized(unNormalizedUrl); + if (normalized.scheme() == QLatin1String("qrc")) + normalized.setHost(QString()); // map qrc:///a.qml to qrc:/a.qml + return normalized; +} + /*! Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached. */ -QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &url, Mode mode) +QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &unNormalizedUrl, Mode mode) { - Q_ASSERT(!url.isRelative() && - (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || - !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))); + Q_ASSERT(!unNormalizedUrl.isRelative() && + (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() || + !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl)))); + + QUrl url = normalize(unNormalizedUrl); LockHolder<QQmlTypeLoader> holder(this); @@ -1705,11 +1715,13 @@ QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QByteArray &data, con /*! Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached. */ -QQmlRefPointer<QQmlScriptBlob> QQmlTypeLoader::getScript(const QUrl &url) +QQmlRefPointer<QQmlScriptBlob> QQmlTypeLoader::getScript(const QUrl &unNormalizedUrl) { - Q_ASSERT(!url.isRelative() && - (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || - !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))); + Q_ASSERT(!unNormalizedUrl.isRelative() && + (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() || + !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl)))); + + QUrl url = normalize(unNormalizedUrl); LockHolder<QQmlTypeLoader> holder(this); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 66b1eaf18e..98ac4b1bc1 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -304,10 +304,12 @@ public: QQmlImportDatabase *importDatabase() const; - QQmlRefPointer<QQmlTypeData> getType(const QUrl &url, Mode mode = PreferSynchronous); + static QUrl normalize(const QUrl &unNormalizedUrl); + + QQmlRefPointer<QQmlTypeData> getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous); QQmlRefPointer<QQmlTypeData> getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); - QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &); + QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &unNormalizedUrl); QQmlRefPointer<QQmlQmldirData> getQmldir(const QUrl &); QString absoluteFilePath(const QString &path); diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 2cfb740ebf..3863f9e968 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -903,10 +903,11 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem) void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status) { - Q_Q(QQmlDelegateModel); if (!isDoneIncubating(status)) return; + const QList<QQmlError> incubationTaskErrors = incubationTask->errors(); + QQmlDelegateModelItem *cacheItem = incubationTask->incubating; cacheItem->incubationTask = nullptr; incubationTask->incubating = nullptr; @@ -920,7 +921,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba emitCreatedItem(incubationTask, cacheItem->object); cacheItem->releaseObject(); } else if (status == QQmlIncubator::Error) { - qmlWarning(q, m_delegate->errors()) << "Error creating delegate"; + qmlWarning(m_delegate, incubationTaskErrors + m_delegate->errors()) << "Error creating delegate"; } if (!cacheItem->isObjectReferenced()) { @@ -1017,7 +1018,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ if (QQmlAdaptorModelProxyInterface *proxy = qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) { ctxt = new QQmlContextData; - ctxt->setParent(cacheItem->contextData); + ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true); ctxt->contextObject = proxy->proxiedObject(); } } diff --git a/src/qmldebug/qqmlprofilerclientdefinitions_p.h b/src/qmldebug/qqmlprofilerclientdefinitions_p.h index c8524574f6..be1c6318af 100644 --- a/src/qmldebug/qqmlprofilerclientdefinitions_p.h +++ b/src/qmldebug/qqmlprofilerclientdefinitions_p.h @@ -40,6 +40,17 @@ #ifndef QQMLPROFILERCLIENTDEFINITIONS_P_H #define QQMLPROFILERCLIENTDEFINITIONS_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/qglobal.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc index e70791d1c9..b22b013684 100644 --- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc +++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc @@ -29,6 +29,7 @@ \page qtquick-bestpractices.html \title Best Practices for QML and Qt Quick \brief Lists best practices for working with QML and Qt Quick +\ingroup best-practices Despite all of the benefits that QML and Qt Quick offer, they can be challenging in certain situations. The following sections elaborate on some of diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 23d9cc1219..f02ad24c5b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3134,6 +3134,9 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const */ QTransform QQuickItemPrivate::windowToGlobalTransform() const { + if (Q_UNLIKELY(window == nullptr)) + return QTransform(); + QPoint quickWidgetOffset; QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset); QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset); @@ -3145,6 +3148,9 @@ QTransform QQuickItemPrivate::windowToGlobalTransform() const */ QTransform QQuickItemPrivate::globalToWindowTransform() const { + if (Q_UNLIKELY(window == nullptr)) + return QTransform(); + QPoint quickWidgetOffset; QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset); QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp index aa83709b72..74426c5c4d 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp @@ -68,6 +68,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin QMargins sourceMargins = normalizedMargins(sourceMarginsIn); QMargins targetMargins = normalizedMargins(targetMarginsIn); + const qreal sourceDpr = pixmap.devicePixelRatioF(); + sourceMargins *= sourceDpr; + // source center const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); @@ -89,9 +92,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin int columns = 3; int rows = 3; if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) - columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); + columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth))); if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) - rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); + rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight))); xTarget.resize(columns + 1); yTarget.resize(rows + 1); @@ -121,7 +124,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin dx = targetCenterWidth; break; case Qt::RepeatTile: - dx = sourceCenterWidth; + dx = sourceCenterWidth / sourceDpr; break; case Qt::RoundTile: dx = targetCenterWidth / qreal(columns - 2); @@ -136,7 +139,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin dy = targetCenterHeight; break; case Qt::RepeatTile: - dy = sourceCenterHeight; + dy = sourceCenterHeight / sourceDpr; break; case Qt::RoundTile: dy = targetCenterHeight / qreal(rows - 2); |