diff options
Diffstat (limited to 'src')
29 files changed, 190 insertions, 101 deletions
diff --git a/src/3rdparty/masm/wtf/PageBlock.cpp b/src/3rdparty/masm/wtf/PageBlock.cpp index e715ed262a..bc0e8d6f2d 100644 --- a/src/3rdparty/masm/wtf/PageBlock.cpp +++ b/src/3rdparty/masm/wtf/PageBlock.cpp @@ -64,6 +64,7 @@ inline size_t systemPageSize() #endif +inline namespace hidden { size_t pageSize() { if (!s_pageSize) @@ -78,5 +79,6 @@ size_t pageMask() s_pageMask = ~(pageSize() - 1); return s_pageMask; } +} } // namespace WTF diff --git a/src/3rdparty/masm/wtf/PageBlock.h b/src/3rdparty/masm/wtf/PageBlock.h index 09e4048239..d85c39cb33 100644 --- a/src/3rdparty/masm/wtf/PageBlock.h +++ b/src/3rdparty/masm/wtf/PageBlock.h @@ -28,8 +28,13 @@ namespace WTF { +// avoid false positive detection by apple +// by putting the function inside an inline namespace +// to obtain different name mangling +inline namespace hidden { WTF_EXPORT_PRIVATE size_t pageSize(); WTF_EXPORT_PRIVATE size_t pageMask(); +} inline bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); } inline bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); } inline bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp index 506ecb64bb..b50490e831 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp @@ -216,7 +216,8 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) return false; QV4::ScopedObject scopeObject(scope, engine()->newObject()); - if (ctxt->d()->type == QV4::Heap::ExecutionContext::Type_CallContext) { + if (ctxt->d()->type == QV4::Heap::ExecutionContext::Type_CallContext || + ctxt->d()->type == QV4::Heap::ExecutionContext::Type_BlockContext) { QStringList names; Refs collectedRefs; diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp index 71645579c5..499f060c9c 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp @@ -163,7 +163,7 @@ int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, boo for (QV4Debugger *debugger : qAsConst(m_debuggers)) debugger->addBreakPoint(fileName, lineNumber, condition); - int id = m_breakPoints.size(); + const int id = ++m_lastBreakPointId; m_breakPoints.insert(id, BreakPoint(fileName, lineNumber, enabled, condition)); return id; } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h index 39ac4d4dcb..43baec32d7 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h @@ -93,6 +93,7 @@ private: }; QHash<int, BreakPoint> m_breakPoints; + int m_lastBreakPointId = 0; bool m_breakOnThrow; QV4DebugServiceImpl *m_debugService; }; diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 89f99e21cd..2ad85ab910 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -448,7 +448,9 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen errors << m; } - return false; + + if (!errors.isEmpty() || !parseResult) + return false; } program = parser.ast(); Q_ASSERT(program); diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc index ece2fd5fd7..ffe0ec9737 100644 --- a/src/qml/doc/src/cppintegration/definetypes.qdoc +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -69,6 +69,21 @@ exposed to QML but the type itself should not be instantiable. For a quick guide to choosing the correct approach to expose C++ types to QML, see \l {Choosing the Correct Integration Method Between C++ and QML}. +\section2 Preconditions + +All the macros mentioned below are available from the \c qqml.h +header. You need to add the following code to the files using them in order to +make the macros available: + +\code +#include <QtQml/qqml.h> +\endcode + +Furthermore, your class declarations have to live in headers reachable via your +project's include path. The declarations are used to generate registration code +at compile time, and the registration code needs to include the headers that +contain the declarations. + \section2 Registering an Instantiable Object Type \b{Any QObject-derived C++ class can be registered as the definition of a diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 4e531ceb61..6f5a0c4196 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -159,11 +159,11 @@ \relates QQmlEngine Declares the enclosing type to be a singleton in QML. This only takes effect - if the type is available in QML, by having a \l QML_ELEMENT or - \l QML_NAMED_ELEMENT() macro. By default, each QQmlEngine will try to create a - singleton instance using the type's default constructor when the type is first - accessed. If there is no default constructor the singleton is initially - inaccessible. This behavior can be overridden by calling + if the type is a \l Q_OBJECT and is available in QML (by having a + \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro). By default, each QQmlEngine + will try to create a singleton instance using the type's default constructor + when the type is first accessed. If there is no default constructor the + singleton is initially inaccessible. This behavior can be overridden by calling \l qmlRegisterSingletonType() with a specific factory function or \l qmlRegisterSingletonInstance() with a specific instance for the same class and the same type namespace and version. diff --git a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc index 075b3a7646..0e06cbec8a 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc @@ -133,7 +133,7 @@ Rectangle { Connections { target: button - function onClicked(): { + function onClicked() { rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1); } } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 9ee4fdbe41..c785f8ef51 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -375,10 +375,15 @@ bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& { QQmlProperty prop = QQmlComponentPrivate::removePropertyFromRequired(component, name, requiredProperties()); QQmlPropertyPrivate *privProp = QQmlPropertyPrivate::get(prop); - if (!prop.isValid() || !privProp->writeValueProperty(value, {})) { + const bool isValid = prop.isValid(); + if (!isValid || !privProp->writeValueProperty(value, {})) { QQmlError error{}; error.setUrl(url); - error.setDescription(QLatin1String("Could not set property %1").arg(name)); + if (isValid) + error.setDescription(QLatin1String("Could not set initial property %1").arg(name)); + else + error.setDescription(QLatin1String("Setting initial properties failed: %2 does not have a property called %1").arg(name, + QQmlMetaType::prettyTypeName(component))); state.errors.push_back(error); return false; } else @@ -830,6 +835,14 @@ QObject *QQmlComponent::create(QQmlContext *context) properties with \a initialProperties. \a context specifies the context where the object instance is to be created. + \omit + TODO: also mention errorString() when QTBUG-93239 is fixed + \endomit + + If any of the \c initialProperties cannot be set, \l isError() will return + \c true, and the \l errors() function can be used to + get detailed information about the error(s). + \sa QQmlComponent::create \since 5.14 */ diff --git a/src/qmldebug/qqmlprofilerevent_p.h b/src/qmldebug/qqmlprofilerevent_p.h index a7e37d1964..01b2f58f16 100644 --- a/src/qmldebug/qqmlprofilerevent_p.h +++ b/src/qmldebug/qqmlprofilerevent_p.h @@ -48,6 +48,7 @@ #include <QtCore/qmetatype.h> #include <initializer_list> +#include <limits> #include <type_traits> // diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 26ded63c41..312a621029 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -1343,6 +1343,8 @@ QObject *QQmlDelegateModel::object(int index, QQmlIncubator::IncubationMode incu QQmlIncubator::Status QQmlDelegateModel::incubationStatus(int index) { Q_D(QQmlDelegateModel); + if (d->m_compositor.count(d->m_compositorGroup) <= index) + return QQmlIncubator::Null; Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index); if (!it->inCache()) return QQmlIncubator::Null; diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index adb753e000..03f8d8918c 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -503,8 +503,11 @@ bool QQuickPointerHandler::parentContains(const QQuickEventPoint *point) const return false; if (QQuickItem *par = parentItem()) { if (par->window()) { + QRect windowGeometry = par->window()->geometry(); + if (!par->window()->isTopLevel()) + windowGeometry = QRect(QWindowPrivate::get(par->window())->globalPosition(), par->window()->size()); QPoint screenPosition = par->window()->mapToGlobal(point->scenePosition().toPoint()); - if (!par->window()->geometry().contains(screenPosition)) + if (!windowGeometry.contains(screenPosition)) return false; } QPointF p = par->mapFromScene(point->scenePosition()); diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 950afaed52..7e673b3fe4 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -813,7 +813,7 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event \readonly \qmlproperty int QtQuick::EventPoint::pointId - This property holds the ID of the event, if any. + This property holds the ID of the point, if any. Touchpoints have automatically-incrementing IDs: each time the user presses a finger against the touchscreen, it will be a larger number. @@ -826,12 +826,8 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event \readonly \qmlproperty bool QtQuick::EventPoint::accepted - Setting \a accepted to true prevents the event from being propagated to - Items below the PointerHandler's Item. - - Generally, if the handler acts on the mouse event, then it should be - accepted so that items lower in the stacking order do not also respond to - the same event. + Indicates whether this point has been accepted during delivery thus far. + This flag cannot be usefully set from QML. */ /*! diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 497672b497..3df899d63d 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2095,7 +2095,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) /*! \class QQuickItem::ItemChangeData \inmodule QtQuick - \brief Adds supplimentary information to the QQuickItem::itemChange() + \brief Adds supplementary information to the QQuickItem::itemChange() function. The meaning of each member of this class is defined by the change type. @@ -2125,25 +2125,31 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) /*! \variable QQuickItem::ItemChangeData::realValue - Contains supplimentary information to the QQuickItem::itemChange() function. + The numeric value that has changed: \l {QQuickItem::opacity()}{opacity}, + \l {QQuickItem::rotation()}{rotation} or + \l {QScreen::devicePixelRatio}{device pixel ratio}. \sa QQuickItem::ItemChange */ /*! \variable QQuickItem::ItemChangeData::boolValue - Contains supplimentary information to the QQuickItem::itemChange() function. + The boolean value that has changed: \l {QQuickItem::visible()}{visible}, + \l {QQuickItem::enabled()}{enabled}, \l {QQuickItem::activeFocus()}{activeFocus} + or \l {QQuickItem::antialiasing()}{antialiasing}. \sa QQuickItem::ItemChange */ /*! \variable QQuickItem::ItemChangeData::item - Contains supplimentary information to the QQuickItem::itemChange() function. + The item that has been added or removed as a \l{QQuickItem::childItems()}{child}, + or the new \l{QQuickItem::parentItem()}{parent}. \sa QQuickItem::ItemChange */ /*! \variable QQuickItem::ItemChangeData::window - Contains supplimentary information to the QQuickItem::itemChange() function. + The \l{QQuickWindow}{window} in which the item has been shown, or \c nullptr + if the item has been removed from a window. \sa QQuickItem::ItemChange */ diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp index dfb56ccc00..63359a7683 100644 --- a/src/quick/items/qquickitemanimation.cpp +++ b/src/quick/items/qquickitemanimation.cpp @@ -529,8 +529,8 @@ QAbstractAnimationJob* QQuickAnchorAnimation::transition(QQuickStateActions &act data->interpolatorType = QMetaType::QReal; data->interpolator = d->interpolator; data->reverse = direction == Backward ? true : false; - data->fromSourced = false; - data->fromDefined = false; + data->fromIsSourced = false; + data->fromIsDefined = false; for (int ii = 0; ii < actions.count(); ++ii) { QQuickStateAction &action = actions[ii]; @@ -543,7 +543,7 @@ QAbstractAnimationJob* QQuickAnchorAnimation::transition(QQuickStateActions &act QQuickBulkValueAnimator *animator = new QQuickBulkValueAnimator; if (data->actions.count()) { animator->setAnimValue(data); - animator->setFromSourcedValue(&data->fromSourced); + animator->setFromIsSourcedValue(&data->fromIsSourced); } else { delete data; } @@ -864,9 +864,9 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio data->exitInterval = d->duration ? qreal(d->exitDuration) / d->duration : qreal(0); data->endRotation = d->endRotation; data->reverse = direction == Backward ? true : false; - data->fromSourced = false; - data->fromDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false; - data->toDefined = d->path ? true : false; + data->fromIsSourced = false; + data->fromIsDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false; + data->toIsDefined = d->path ? true : false; int origModifiedSize = modified.count(); for (int i = 0; i < actions.count(); ++i) { @@ -885,8 +885,7 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio } } - if (target && d->path && - (modified.count() > origModifiedSize || data->toDefined)) { + if (target && d->path && (modified.count() > origModifiedSize || data->toIsDefined)) { data->target = target; data->path = d->path; data->path->invalidateSequentialHistory(); @@ -897,13 +896,13 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio // treat interruptions specially, otherwise we end up with strange paths if ((data->reverse || prevData.reverse) && prevData.currentV > 0 && prevData.currentV < 1) { - if (!data->fromDefined && !data->toDefined && !prevData.painterPath.isEmpty()) { + if (!data->fromIsDefined && !data->toIsDefined && !prevData.painterPath.isEmpty()) { QPointF pathPos = QQuickPath::sequentialPointAt(prevData.painterPath, prevData.pathLength, prevData.attributePoints, prevData.prevBez, prevData.currentV); if (!prevData.anchorPoint.isNull()) pathPos -= prevData.anchorPoint; if (pathPos == data->target->position()) { //only treat as interruption if we interrupted ourself data->painterPath = prevData.painterPath; - data->toDefined = data->fromDefined = data->fromSourced = true; + data->toIsDefined = data->fromIsDefined = data->fromIsSourced = true; data->prevBez.isValid = false; data->interruptStart = prevData.currentV; data->startRotation = prevData.startRotation; @@ -913,13 +912,13 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio } } } - pa->setFromSourcedValue(&data->fromSourced); + pa->setFromIsSourcedValue(&data->fromIsSourced); pa->setAnimValue(data); pa->setDuration(d->duration); pa->setEasingCurve(d->easingCurve); return initInstance(pa); } else { - pa->setFromSourcedValue(nullptr); + pa->setFromIsSourcedValue(nullptr); pa->setAnimValue(nullptr); delete pa; delete data; @@ -939,7 +938,7 @@ void QQuickPathAnimationUpdater::setValue(qreal v) } currentV = v; bool atStart = ((reverse && v == 1.0) || (!reverse && v == 0.0)); - if (!fromSourced && (!fromDefined || !toDefined)) { + if (!fromIsSourced && (!fromIsDefined || !toIsDefined)) { qreal startX = reverse ? toX + anchorPoint.x() : target->x() + anchorPoint.x(); qreal startY = reverse ? toY + anchorPoint.y() : target->y() + anchorPoint.y(); qreal endX = reverse ? target->x() + anchorPoint.x() : toX + anchorPoint.x(); @@ -947,7 +946,7 @@ void QQuickPathAnimationUpdater::setValue(qreal v) prevBez.isValid = false; painterPath = path->createPath(QPointF(startX, startY), QPointF(endX, endY), QStringList(), pathLength, attributePoints); - fromSourced = true; + fromIsSourced = true; } qreal angle; diff --git a/src/quick/items/qquickitemanimation_p_p.h b/src/quick/items/qquickitemanimation_p_p.h index 83b9899197..351a0cb2bc 100644 --- a/src/quick/items/qquickitemanimation_p_p.h +++ b/src/quick/items/qquickitemanimation_p_p.h @@ -92,7 +92,7 @@ class QQuickPathAnimationUpdater : public QQuickBulkValueUpdater { public: QQuickPathAnimationUpdater() : path(nullptr), pathLength(0), target(nullptr), reverse(false), - fromSourced(false), fromDefined(false), toDefined(false), + fromIsSourced(false), fromIsDefined(false), toIsDefined(false), toX(0), toY(0), currentV(0), orientation(QQuickPathAnimation::Fixed), entryInterval(0), exitInterval(0) {} ~QQuickPathAnimationUpdater() {} @@ -108,9 +108,9 @@ public: QQuickItem *target; bool reverse; - bool fromSourced; - bool fromDefined; - bool toDefined; + bool fromIsSourced; + bool fromIsDefined; + bool toIsDefined; qreal toX; qreal toY; qreal currentV; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 2b4ca9e256..010a0152e1 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -2346,7 +2346,9 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::Inc inRequest = true; - QObject* object = model->object(modelIndex, incubationMode); + // The model will run this same range check internally but produce a warning and return nullptr. + // Since we handle this result graciously in our code, we preempt this warning by checking the range ourselves. + QObject* object = modelIndex < model->count() ? model->object(modelIndex, incubationMode) : nullptr; QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (!item) { diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index 0692a1da42..1a07eb5923 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -556,7 +556,10 @@ void QQuickPinchArea::updatePinch() d->inPinch = true; d->stealMouse = true; if (d->pinch && d->pinch->target()) { - d->pinchStartPos = pinch()->target()->position(); + auto targetParent = pinch()->target()->parentItem(); + d->pinchStartPos = targetParent ? + targetParent->mapToScene(pinch()->target()->position()) : + pinch()->target()->position(); d->pinchStartScale = d->pinch->target()->scale(); d->pinchStartRotation = d->pinch->target()->rotation(); d->pinch->setActive(true); @@ -604,6 +607,9 @@ void QQuickPinchArea::updatePinchTarget() s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); pinch()->target()->setScale(s); QPointF pos = d->sceneLastCenter - d->sceneStartCenter + d->pinchStartPos; + if (auto targetParent = pinch()->target()->parentItem()) + pos = targetParent->mapFromScene(pos); + if (pinch()->axis() & QQuickPinch::XAxis) { qreal x = pos.x(); if (x < pinch()->xmin()) diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index f9454fc5cb..5feec60874 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -958,43 +958,61 @@ QQuickTableViewPrivate::RebuildOptions QQuickTableViewPrivate::checkForVisibilit return RebuildOption::None; } - // Go through all columns from first to last, find the columns that used - // to be hidden and not loaded, and check if they should become visible - // (and vice versa). If there is a change, we need to rebuild. RebuildOptions rebuildOptions = RebuildOption::None; - for (int column = leftColumn(); column <= rightColumn(); ++column) { - const bool wasVisibleFromBefore = loadedColumns.contains(column); - const bool isVisibleNow = !qFuzzyIsNull(getColumnWidth(column)); - if (wasVisibleFromBefore == isVisibleNow) - continue; - - // A column changed visibility. This means that it should - // either be loaded or unloaded. So we need a rebuild. - qCDebug(lcTableViewDelegateLifecycle) << "Column" << column << "changed visibility to" << isVisibleNow; + if (loadedTableOuterRect.x() == origin.x() && leftColumn() != 0) { + // Since the left column is at the origin of the viewport, but still not the first + // column in the model, we need to calculate a new left column since there might be + // columns in front of it that used to be hidden, but should now be visible (QTBUG-93264). rebuildOptions.setFlag(RebuildOption::ViewportOnly); - if (column == leftColumn()) { - // The first loaded column should now be hidden. This means that we - // need to calculate which column should now be first instead. - rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + } else { + // Go through all loaded columns from first to last, find the columns that used + // to be hidden and not loaded, and check if they should become visible + // (and vice versa). If there is a change, we need to rebuild. + for (int column = leftColumn(); column <= rightColumn(); ++column) { + const bool wasVisibleFromBefore = loadedColumns.contains(column); + const bool isVisibleNow = !qFuzzyIsNull(getColumnWidth(column)); + if (wasVisibleFromBefore == isVisibleNow) + continue; + + // A column changed visibility. This means that it should + // either be loaded or unloaded. So we need a rebuild. + qCDebug(lcTableViewDelegateLifecycle) << "Column" << column << "changed visibility to" << isVisibleNow; + rebuildOptions.setFlag(RebuildOption::ViewportOnly); + if (column == leftColumn()) { + // The first loaded column should now be hidden. This means that we + // need to calculate which column should now be first instead. + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + } + break; } - break; } - // Go through all rows from first to last, and do the same as above - for (int row = topRow(); row <= bottomRow(); ++row) { - const bool wasVisibleFromBefore = loadedRows.contains(row); - const bool isVisibleNow = !qFuzzyIsNull(getRowHeight(row)); - if (wasVisibleFromBefore == isVisibleNow) - continue; - - // A row changed visibility. This means that it should - // either be loaded or unloaded. So we need a rebuild. - qCDebug(lcTableViewDelegateLifecycle) << "Row" << row << "changed visibility to" << isVisibleNow; + if (loadedTableOuterRect.y() == origin.y() && topRow() != 0) { + // Since the top row is at the origin of the viewport, but still not the first + // row in the model, we need to calculate a new top row since there might be + // rows in front of it that used to be hidden, but should now be visible (QTBUG-93264). rebuildOptions.setFlag(RebuildOption::ViewportOnly); - if (row == topRow()) - rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); - break; + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); + } else { + // Go through all loaded rows from first to last, find the rows that used + // to be hidden and not loaded, and check if they should become visible + // (and vice versa). If there is a change, we need to rebuild. + for (int row = topRow(); row <= bottomRow(); ++row) { + const bool wasVisibleFromBefore = loadedRows.contains(row); + const bool isVisibleNow = !qFuzzyIsNull(getRowHeight(row)); + if (wasVisibleFromBefore == isVisibleNow) + continue; + + // A row changed visibility. This means that it should + // either be loaded or unloaded. So we need a rebuild. + qCDebug(lcTableViewDelegateLifecycle) << "Row" << row << "changed visibility to" << isVisibleNow; + rebuildOptions.setFlag(RebuildOption::ViewportOnly); + if (row == topRow()) + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); + break; + } } return rebuildOptions; diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 5df5e5adcf..1d9e3761a2 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2359,6 +2359,14 @@ void QQuickTextEdit::q_textChanged() d->determineHorizontalAlignment(); d->updateDefaultTextOption(); updateSize(); + + markDirtyNodesForRange(0, d->document->characterCount(), 0); + polish(); + if (isComponentComplete()) { + d->updateType = QQuickTextEditPrivate::UpdatePaintNode; + update(); + } + emit textChanged(); } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h index b80bacbaa0..af912e1a3f 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h @@ -54,6 +54,8 @@ #include <private/qsgadaptationlayer_p.h> #include <private/qsgtexturematerial_p.h> +#include <QtCore/QPointer> + QT_BEGIN_NAMESPACE namespace QSGSoftwareHelpers { @@ -132,7 +134,7 @@ private: QRectF m_innerSourceRect; QRectF m_subSourceRect; - QSGTexture *m_texture; + QPointer<QSGTexture> m_texture; QPixmap m_cachedMirroredPixmap; bool m_mirror; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 31671c8639..a0a97c779a 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1878,7 +1878,7 @@ bool Renderer::checkOverlap(int first, int last, const Rect &bounds) { for (int i=first; i<=last; ++i) { Element *e = m_alphaRenderList.at(i); - if (!e || e->batch) + if (!e) continue; Q_ASSERT(e->boundsComputed); if (e->bounds.intersects(bounds)) @@ -1949,8 +1949,10 @@ void Renderer::prepareAlphaBatches() continue; if (ej->root != ei->root || ej->isRenderNode) break; - if (ej->batch) + if (ej->batch) { + overlapBounds |= ej->bounds; continue; + } QSGGeometryNode *gnj = ej->node; if (gnj->geometry()->vertexCount() == 0) diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index e5e25d141b..4cf019c7f0 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1996,7 +1996,7 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) } QQuickBulkValueAnimator::QQuickBulkValueAnimator() - : QAbstractAnimationJob(), animValue(nullptr), fromSourced(nullptr), m_duration(250) + : QAbstractAnimationJob(), animValue(nullptr), fromIsSourced(nullptr), m_duration(250) { } @@ -2026,8 +2026,8 @@ void QQuickBulkValueAnimator::updateCurrentTime(int currentTime) void QQuickBulkValueAnimator::topLevelAnimationLoopChanged() { //check for new from every top-level loop (when the top level animation is started and all subsequent loops) - if (fromSourced) - *fromSourced = false; + if (fromIsSourced) + *fromIsSourced = false; QAbstractAnimationJob::topLevelAnimationLoopChanged(); } @@ -2596,7 +2596,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v) if (v == 1.) { QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); } else { - if (!fromSourced && !fromDefined) { + if (!fromIsSourced && !fromIsDefined) { action.fromValue = action.property.read(); if (interpolatorType) { QQuickPropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); @@ -2616,7 +2616,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v) return; } wasDeleted = nullptr; - fromSourced = true; + fromIsSourced = true; } void QQuickAnimationPropertyUpdater::debugUpdater(QDebug d, int indentLevel) const @@ -2760,11 +2760,11 @@ QAbstractAnimationJob* QQuickPropertyAnimation::transition(QQuickStateActions &a data->interpolatorType = d->interpolatorType; data->interpolator = d->interpolator; data->reverse = direction == Backward ? true : false; - data->fromSourced = false; - data->fromDefined = d->fromIsDefined; + data->fromIsSourced = false; + data->fromIsDefined = d->fromIsDefined; data->actions = dataActions; animator->setAnimValue(data); - animator->setFromSourcedValue(&data->fromSourced); + animator->setFromIsSourcedValue(&data->fromIsSourced); d->actions = &data->actions; //remove this? } diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index 8d23242b68..f785bf6623 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -135,7 +135,7 @@ public: void setAnimValue(QQuickBulkValueUpdater *value); QQuickBulkValueUpdater *getAnimValue() const { return animValue; } - void setFromSourcedValue(bool *value) { fromSourced = value; } + void setFromIsSourcedValue(bool *value) { fromIsSourced = value; } int duration() const override { return m_duration; } void setDuration(int msecs) { m_duration = msecs; } @@ -150,7 +150,7 @@ protected: private: QQuickBulkValueUpdater *animValue; - bool *fromSourced; + bool *fromIsSourced; int m_duration; QEasingCurve easing; }; @@ -311,7 +311,7 @@ public: class Q_AUTOTEST_EXPORT QQuickAnimationPropertyUpdater : public QQuickBulkValueUpdater { public: - QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(nullptr), prevInterpolatorType(0), reverse(false), fromSourced(false), fromDefined(false), wasDeleted(nullptr) {} + QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(nullptr), prevInterpolatorType(0), reverse(false), fromIsSourced(false), fromIsDefined(false), wasDeleted(nullptr) {} ~QQuickAnimationPropertyUpdater() override; void setValue(qreal v) override; @@ -323,8 +323,8 @@ public: QVariantAnimation::Interpolator interpolator; int prevInterpolatorType; //for generic bool reverse; - bool fromSourced; - bool fromDefined; + bool fromIsSourced; + bool fromIsDefined; bool *wasDeleted; }; diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index d1ff78f8bc..e2a9c33adf 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -176,7 +176,7 @@ void QQuickAnimator::setTo(qreal to) Q_D(QQuickAnimator); if (to == d->to) return; - d->isToDefined = true; + d->toIsDefined = true; d->to = to; Q_EMIT toChanged(d->to); } @@ -204,7 +204,7 @@ void QQuickAnimator::setFrom(qreal from) Q_D(QQuickAnimator); if (from == d->from) return; - d->isFromDefined = true; + d->fromIsDefined = true; d->from = from; Q_EMIT fromChanged(d->from); } @@ -231,14 +231,14 @@ void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job, job->setTarget(qobject_cast<QQuickItem *>(action.property.object())); - if (isFromDefined) + if (fromIsDefined) job->setFrom(from); else if (action.fromValue.isValid()) job->setFrom(action.fromValue.toReal()); else job->setFrom(action.property.read().toReal()); - if (isToDefined) + if (toIsDefined) job->setTo(to); else if (action.toValue.isValid()) job->setTo(action.toValue.toReal()); diff --git a/src/quick/util/qquickanimator_p_p.h b/src/quick/util/qquickanimator_p_p.h index b176119c70..33e202c522 100644 --- a/src/quick/util/qquickanimator_p_p.h +++ b/src/quick/util/qquickanimator_p_p.h @@ -68,8 +68,8 @@ public: , duration(250) , from(0) , to(0) - , isFromDefined(false) - , isToDefined(false) + , fromIsDefined(false) + , toIsDefined(false) { } @@ -79,8 +79,8 @@ public: qreal from; qreal to; - uint isFromDefined : 1; - uint isToDefined : 1; + uint fromIsDefined : 1; + uint toIsDefined : 1; void apply(QQuickAnimatorJob *job, const QString &propertyName, QQuickStateActions &actions, QQmlProperties &modified, QObject *defaultTarget); }; diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index 74ee52b1d3..c39e1f5b8b 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -107,12 +107,13 @@ QT_BEGIN_NAMESPACE \li PathPolyline \li Yes \li Yes + \li No \li Yes - \li Yes - \li PathMultiLine - \li Yes + \row + \li PathMultiLine \li Yes \li Yes + \li No \li Yes \row \li PathQuad diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp index 660852ba83..d531fc9205 100644 --- a/src/quick/util/qquickstyledtext.cpp +++ b/src/quick/util/qquickstyledtext.cpp @@ -46,6 +46,8 @@ #include "qquickstyledtext_p.h" #include <QQmlContext> +Q_LOGGING_CATEGORY(lcStyledText, "qt.quick.styledtext") + /* QQuickStyledText supports few tags: @@ -566,6 +568,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI textOut += QChar(34); else if (entity == QLatin1String("nbsp")) textOut += QChar(QChar::Nbsp); + else + qCWarning(lcStyledText) << "StyledText doesn't support entity" << entity; return; } else if (*ch == QLatin1Char(' ')) { QStringRef entity(&textIn, entityStart - 1, entityLength + 1); |