qt5-declarative, qt5-wayland rebuild

This commit is contained in:
Rmys
2023-09-08 15:49:58 +03:00
parent 737ea6b4e8
commit 082a47abc2
4 changed files with 625 additions and 132 deletions
@@ -55,10 +55,10 @@ index 45150cfffd..5ad53faf95 100644
+
+ // LOAD_ACC(); <- not needed here since it would be unreachable.
}
void BaselineJIT::generate_GetException() { as->getException(); }
@@ -547,9 +549,11 @@ void BaselineJIT::generate_SetException() { as->setException(); }
void BaselineJIT::generate_CreateCallContext()
{
+ STORE_ACC();
@@ -67,7 +67,7 @@ index 45150cfffd..5ad53faf95 100644
BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore);
+ LOAD_ACC();
}
void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); }
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index aeb4835c40..9082628a1a 100644
@@ -94,7 +94,7 @@ index 39f4f88512..c963e1878e 100644
- return rv;
+ return new (rv) T;
}
template<typename T, int Step>
@@ -139,8 +138,7 @@ template<typename T1>
T *QRecyclePool<T, Step>::New(const T1 &a)
@@ -104,7 +104,7 @@ index 39f4f88512..c963e1878e 100644
- return rv;
+ return new (rv) T(a);
}
template<typename T, int Step>
@@ -148,8 +146,7 @@ template<typename T1>
T *QRecyclePool<T, Step>::New(T1 &a)
@@ -114,8 +114,307 @@ index 39f4f88512..c963e1878e 100644
- return rv;
+ return new (rv) T(a);
}
template<typename T, int Step>
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index ee31cb38d9..187339169b 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -176,24 +176,24 @@ public:
};
struct NotifyList {
- quint64 connectionMask;
-
- quint16 maximumTodoIndex;
- quint16 notifiesSize;
-
- QQmlNotifierEndpoint *todo;
- QQmlNotifierEndpoint**notifies;
+ QAtomicInteger<quint64> connectionMask;
+ QQmlNotifierEndpoint *todo = nullptr;
+ QQmlNotifierEndpoint**notifies = nullptr;
+ quint16 maximumTodoIndex = 0;
+ quint16 notifiesSize = 0;
void layout();
private:
void layout(QQmlNotifierEndpoint*);
};
- NotifyList *notifyList;
+ QAtomicPointer<NotifyList> notifyList;
- inline QQmlNotifierEndpoint *notify(int index);
+ inline QQmlNotifierEndpoint *notify(int index) const;
void addNotify(int index, QQmlNotifierEndpoint *);
int endpointCount(int index);
bool signalHasEndpoint(int index) const;
- void disconnectNotifiers();
+
+ enum class DeleteNotifyList { Yes, No };
+ void disconnectNotifiers(DeleteNotifyList doDelete);
// The context that created the C++ object
QQmlContextData *context = nullptr;
@@ -201,12 +201,12 @@ public:
QQmlContextData *outerContext = nullptr;
QQmlContextDataRef ownContext;
- QQmlAbstractBinding *bindings;
- QQmlBoundSignal *signalHandlers;
+ QQmlAbstractBinding *bindings = nullptr;
+ QQmlBoundSignal *signalHandlers = nullptr;
// Linked list for QQmlContext::contextObjects
- QQmlData *nextContextObject;
- QQmlData**prevContextObject;
+ QQmlData *nextContextObject = nullptr;
+ QQmlData**prevContextObject = nullptr;
inline bool hasBindingBit(int) const;
inline void setBindingBit(QObject *obj, int);
@@ -216,10 +216,10 @@ public:
inline void setPendingBindingBit(QObject *obj, int);
inline void clearPendingBindingBit(int);
- quint16 lineNumber;
- quint16 columnNumber;
+ quint16 lineNumber = 0;
+ quint16 columnNumber = 0;
- quint32 jsEngineId; // id of the engine that created the jsWrapper
+ quint32 jsEngineId = 0; // id of the engine that created the jsWrapper
struct DeferredData {
DeferredData();
@@ -240,7 +240,7 @@ public:
QQmlPropertyCache *propertyCache;
- QQmlGuardImpl *guards;
+ QQmlGuardImpl *guards = nullptr;
static QQmlData *get(const QObject *object, bool create = false) {
QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
@@ -289,7 +289,7 @@ public:
private:
// For attachedProperties
- mutable QQmlDataExtended *extendedData;
+ mutable QQmlDataExtended *extendedData = nullptr;
Q_NEVER_INLINE static QQmlData *createQQmlData(QObjectPrivate *priv);
Q_NEVER_INLINE static QQmlPropertyCache *createPropertyCache(QJSEngine *engine, QObject *object);
@@ -342,23 +342,31 @@ bool QQmlData::wasDeleted(const QObject *object)
return ddata && ddata->isQueuedForDeletion;
}
-QQmlNotifierEndpoint *QQmlData::notify(int index)
+inline bool isIndexInConnectionMask(quint64 connectionMask, int index)
+{
+ return connectionMask & (1ULL << quint64(index % 64));
+}
+
+QQmlNotifierEndpoint *QQmlData::notify(int index) const
{
+ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics.
+
Q_ASSERT(index <= 0xFFFF);
- if (!notifyList || !(notifyList->connectionMask & (1ULL << quint64(index % 64)))) {
+ NotifyList *list = notifyList.loadRelaxed();
+ if (!list || !isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index))
return nullptr;
- } else if (index < notifyList->notifiesSize) {
- return notifyList->notifies[index];
- } else if (index <= notifyList->maximumTodoIndex) {
- notifyList->layout();
- }
- if (index < notifyList->notifiesSize) {
- return notifyList->notifies[index];
- } else {
- return nullptr;
+ if (index < list->notifiesSize)
+ return list->notifies[index];
+
+ if (index <= list->maximumTodoIndex) {
+ list->layout();
+ if (index < list->notifiesSize)
+ return list->notifies[index];
}
+
+ return nullptr;
}
/*
@@ -367,7 +375,19 @@ QQmlNotifierEndpoint *QQmlData::notify(int index)
*/
inline bool QQmlData::signalHasEndpoint(int index) const
{
- return notifyList && (notifyList->connectionMask & (1ULL << quint64(index % 64)));
+ // This can be called from any thread.
+ // We still use relaxed semantics. If we're on a thread different from the "home" thread
+ // of the QQmlData, two interesting things might happen:
+ //
+ // 1. The list might go away while we hold it. In that case we are dealing with an object whose
+ // QObject dtor is being executed concurrently. This is UB already without the notify lists.
+ // Therefore, we don't need to consider it.
+ // 2. The connectionMask may be amended or zeroed while we are looking at it. In that case
+ // we "misreport" the endpoint. Since ordering of events across threads is inherently
+ // nondeterministic, either result is correct in that case. We can accept it.
+
+ NotifyList *list = notifyList.loadRelaxed();
+ return list && isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index);
}
bool QQmlData::hasBindingBit(int coreIndex) const
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 826a1a5ab4..fce8fe987f 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -718,18 +718,15 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
// Disconnect the notifiers now - during object destruction this would be too late, since
// the disconnect call wouldn't be able to call disconnectNotify(), as it isn't possible to
// get the metaobject anymore.
- d->disconnectNotifiers();
+ d->disconnectNotifiers(QQmlData::DeleteNotifyList::No);
}
}
QQmlData::QQmlData()
: ownedByQml1(false), ownMemory(true), indestructible(true), explicitIndestructibleSet(false),
hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
- hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false),
- bindingBitsArraySize(InlineBindingArraySize), notifyList(nullptr),
- bindings(nullptr), signalHandlers(nullptr), nextContextObject(nullptr), prevContextObject(nullptr),
- lineNumber(0), columnNumber(0), jsEngineId(0),
- propertyCache(nullptr), guards(nullptr), extendedData(nullptr)
+ hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), dummy(0),
+ bindingBitsArraySize(InlineBindingArraySize), propertyCache(nullptr)
{
memset(bindingBitsValue, 0, sizeof(bindingBitsValue));
init();
@@ -789,7 +786,10 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
// QQmlEngine to emit signals from a different thread. These signals are then automatically
// marshalled back onto the QObject's thread and handled by QML from there. This is tested
// by the qqmlecmascript::threadSignal() autotest.
- if (!ddata->notifyList)
+
+ // Relaxed semantics here. If we're on a different thread we might schedule a useless event,
+ // but that should be rare.
+ if (!ddata->notifyList.loadRelaxed())
return;
auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed();
@@ -1835,49 +1835,73 @@ void QQmlData::releaseDeferredData()
void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint)
{
- if (!notifyList) {
- notifyList = (NotifyList *)malloc(sizeof(NotifyList));
- notifyList->connectionMask = 0;
- notifyList->maximumTodoIndex = 0;
- notifyList->notifiesSize = 0;
- notifyList->todo = nullptr;
- notifyList->notifies = nullptr;
+ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics.
+
+ NotifyList *list = notifyList.loadRelaxed();
+
+ if (!list) {
+ list = new NotifyList;
+ // We don't really care when this change takes effect on other threads. The notifyList can
+ // only become non-null once in the life time of a QQmlData. It becomes null again when the
+ // underlying QObject is deleted. At that point any interaction with the QQmlData is UB
+ // anyway. So, for all intents and purposese, the list becomes non-null once and then stays
+ // non-null "forever". We can apply relaxed semantics.
+ notifyList.storeRelaxed(list);
}
Q_ASSERT(!endpoint->isConnected());
index = qMin(index, 0xFFFF - 1);
- notifyList->connectionMask |= (1ULL << quint64(index % 64));
- if (index < notifyList->notifiesSize) {
+ // Likewise, we don't really care _when_ the change in the connectionMask is propagated to other
+ // threads. Cross-thread event ordering is inherently nondeterministic. Therefore, when querying
+ // the conenctionMask in the presence of concurrent modification, any result is correct.
+ list->connectionMask.storeRelaxed(
+ list->connectionMask.loadRelaxed() | (1ULL << quint64(index % 64)));
- endpoint->next = notifyList->notifies[index];
+ if (index < list->notifiesSize) {
+ endpoint->next = list->notifies[index];
if (endpoint->next) endpoint->next->prev = &endpoint->next;
- endpoint->prev = &notifyList->notifies[index];
- notifyList->notifies[index] = endpoint;
-
+ endpoint->prev = &list->notifies[index];
+ list->notifies[index] = endpoint;
} else {
- notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index);
+ list->maximumTodoIndex = qMax(int(list->maximumTodoIndex), index);
- endpoint->next = notifyList->todo;
+ endpoint->next = list->todo;
if (endpoint->next) endpoint->next->prev = &endpoint->next;
- endpoint->prev = &notifyList->todo;
- notifyList->todo = endpoint;
+ endpoint->prev = &list->todo;
+ list->todo = endpoint;
}
}
-void QQmlData::disconnectNotifiers()
+void QQmlData::disconnectNotifiers(QQmlData::DeleteNotifyList doDelete)
{
- if (notifyList) {
- while (notifyList->todo)
- notifyList->todo->disconnect();
- for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
- while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii])
+ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics.
+ if (NotifyList *list = notifyList.loadRelaxed()) {
+ while (QQmlNotifierEndpoint *todo = list->todo)
+ todo->disconnect();
+ for (int ii = 0; ii < list->notifiesSize; ++ii) {
+ while (QQmlNotifierEndpoint *ep = list->notifies[ii])
ep->disconnect();
}
- free(notifyList->notifies);
- free(notifyList);
- notifyList = nullptr;
+ free(list->notifies);
+
+ if (doDelete == DeleteNotifyList::Yes) {
+ // We can only get here from QQmlData::destroyed(), and that can only come from the
+ // the QObject dtor. If you're still sending signals at that point you have UB already
+ // without any threads. Therefore, it's enough to apply relaxed semantics.
+ notifyList.storeRelaxed(nullptr);
+ delete list;
+ } else {
+ // We can use relaxed semantics here. The worst thing that can happen is that some
+ // signal is falsely reported as connected. Signal connectedness across threads
+ // is not quite deterministic anyway.
+ list->connectionMask.storeRelaxed(0);
+ list->maximumTodoIndex = 0;
+ list->notifiesSize = 0;
+ list->notifies = nullptr;
+
+ }
}
}
@@ -1961,7 +1985,7 @@ void QQmlData::destroyed(QObject *object)
guard->objectDestroyed(object);
}
- disconnectNotifiers();
+ disconnectNotifiers(DeleteNotifyList::Yes);
if (extendedData)
delete extendedData;
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 10c6c41338..39bfcdc999 100644
--- a/src/qml/qml/qqmlimport.cpp
@@ -123,7 +422,7 @@ index 10c6c41338..39bfcdc999 100644
@@ -2120,9 +2120,12 @@ void QQmlImportDatabase::addImportPath(const QString& path)
cPath.replace(Backslash, Slash);
}
- if (!cPath.isEmpty()
- && !fileImportPath.contains(cPath))
- fileImportPath.prepend(cPath);
@@ -134,7 +433,7 @@ index 10c6c41338..39bfcdc999 100644
+ fileImportPath.prepend(cPath);
+ }
}
/*!
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 175de8b936..a6ba4b8cb3 100644
@@ -142,7 +441,7 @@ index 175de8b936..a6ba4b8cb3 100644
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -419,8 +419,10 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
return Encode(false);
QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
- ExecutableCompilationUnit *cu = td->compilationUnit();
- myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
@@ -160,12 +459,12 @@ index aa9f4bc1bd..09503a7e99 100644
@@ -254,7 +254,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (!pd)
return;
- if (pd->notifyIndex() != -1)
+ if (pd->notifyIndex() != -1 && ctxt->engine)
connect(target, pd->notifyIndex(), ctxt->engine);
}
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 29ed62cd39..aba930dfe1 100644
--- a/src/qml/types/qqmlconnections.cpp
@@ -212,7 +511,7 @@ index 4fcff70de6..5b7e767ae2 100644
@@ -1871,10 +1883,15 @@ void QQmlDelegateModelPrivate::emitChanges()
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
- auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
- for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
- if (cacheItem->attached)
@@ -228,11 +527,11 @@ index 4fcff70de6..5b7e767ae2 100644
+ attached->emitChanges();
}
}
@@ -1974,6 +1991,38 @@ void QQmlDelegateModel::_q_rowsMoved(
}
}
+void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
+{
+ Q_D(QQmlDelegateModel);
@@ -270,7 +569,7 @@ index 4fcff70de6..5b7e767ae2 100644
Q_D(QQmlDelegateModel);
@@ -2663,20 +2712,24 @@ void QQmlDelegateModelAttached::emitChanges()
m_previousGroups = m_cacheItem->groups;
int indexChanges = 0;
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ const int groupCount = m_cacheItem->metaType->groupCount;
@@ -280,7 +579,7 @@ index 4fcff70de6..5b7e767ae2 100644
indexChanges |= (1 << i);
}
}
+ // Don't access m_cacheItem anymore once we've started sending signals.
+ // We don't own it and someone might delete it.
+
@@ -320,10 +619,10 @@ index ae1954ae8d..99e6eff7c3 100644
#include "QtQuick/qquicktextdocument.h"
+#include "QtQuick/qquickrendercontrol.h"
QT_BEGIN_NAMESPACE
#if QT_CONFIG(accessibility)
@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
QWindow *QAccessibleQuickItem::window() const
{
- return item()->window();
@@ -341,7 +640,7 @@ index ae1954ae8d..99e6eff7c3 100644
+
+ return window;
}
int QAccessibleQuickItem::childCount() const
@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
QAccessibleInterface *QAccessibleQuickItem::parent() const
@@ -353,7 +652,7 @@ index ae1954ae8d..99e6eff7c3 100644
+ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
parent = parent->parentItem();
if (parent) {
if (parent == ci) {
- // Jump out to the scene widget if the parent is the root item.
@@ -370,7 +669,7 @@ index ae1954ae8d..99e6eff7c3 100644
@@ -193,7 +202,7 @@ QAccessible::State QAccessibleQuickItem::state() const
QRect viewRect_ = viewRect();
QRect itemRect = rect();
- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
state.invisible = true;
@@ -386,9 +685,9 @@ index ae1954ae8d..99e6eff7c3 100644
+ }
return state;
}
@@ -217,7 +230,7 @@ QAccessible::Role QAccessibleQuickItem::role() const
QAccessible::Role role = QAccessible::NoRole;
if (item())
- role = QQuickItemPrivate::get(item())->accessibleRole();
@@ -401,9 +700,9 @@ index 39ffcaf39c..8baa01330c 100644
--- a/src/quick/accessible/qaccessiblequickview_p.h
+++ b/src/quick/accessible/qaccessiblequickview_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(accessibility)
-class QAccessibleQuickWindow : public QAccessibleObject
+class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
{
@@ -416,18 +715,18 @@ index 8321fcfeed..383078b3b9 100644
@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
\qmlattachedproperty stringlist QtQuick::Drag::mimeData
\since 5.2
- This property holds a map of mimeData that is used during startDrag.
+ This property holds a map from mime type to data that is used during startDrag.
+ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
+ according to the mime type.
*/
QVariantMap QQuickDragAttached::mimeData() const
@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
QDrag *drag = new QDrag(source ? source : q);
QMimeData *mimeData = new QMimeData();
- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
- mimeData->setData(it.key(), it.value().toString().toUtf8());
+ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
@@ -436,7 +735,7 @@ index 8321fcfeed..383078b3b9 100644
+ else
+ mimeData->setData(it.key(), it.value().toString().toUtf8());
+ }
drag->setMimeData(mimeData);
if (pixmapLoader.isReady()) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
@@ -448,7 +747,7 @@ index 33da9762d3..9e8b289376 100644
#include <QtGui/qpa/qplatformtheme.h>
#include <QtCore/qloggingcategory.h>
+#include <QtCore/private/qduplicatetracker_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlengine_p.h>
@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
@@ -456,12 +755,12 @@ index 33da9762d3..9e8b289376 100644
{
Q_D(QQuickItem);
+ d->inDestructor = true;
if (d->windowRefCount > 1)
d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
@@ -2398,7 +2400,7 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
return true;
#if QT_CONFIG(accessibility)
- QAccessible::Role role = QQuickItemPrivate::get(item)->accessibleRole();
+ QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole();
@@ -489,7 +788,7 @@ index 33da9762d3..9e8b289376 100644
if (item == contentItem) {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
const bool wasVisible = isVisible();
op->removeChild(this);
- if (wasVisible) {
@@ -500,9 +799,9 @@ index 33da9762d3..9e8b289376 100644
QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
}
@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
d->itemChange(ItemParentHasChanged, d->parentItem);
- emit parentChanged(d->parentItem);
- if (isVisible() && d->parentItem)
+ if (!d->inDestructor)
@@ -510,16 +809,16 @@ index 33da9762d3..9e8b289376 100644
+ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
emit d->parentItem->visibleChildrenChanged();
}
@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
itemChange(QQuickItem::ItemChildRemovedChange, child);
- emit q->childrenChanged();
+ if (!inDestructor)
+ emit q->childrenChanged();
}
void QQuickItemPrivate::refWindow(QQuickWindow *c)
@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
, touchEnabled(false)
@@ -541,7 +840,7 @@ index 33da9762d3..9e8b289376 100644
+ }
+#endif
}
QQuickStateGroup *QQuickItemPrivate::_states()
@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
QAccessible::updateAccessibility(&ev);
@@ -555,12 +854,12 @@ index 33da9762d3..9e8b289376 100644
+ if (childVisibilityChanged)
+ emit q->visibleChildrenChanged();
+ }
return true; // effective visibility DID change
}
@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
}
itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
+#if QT_CONFIG(accessibility)
+ if (isAccessible) {
@@ -573,10 +872,10 @@ index 33da9762d3..9e8b289376 100644
+#endif
emit q->enabledChanged();
}
@@ -8974,13 +9000,20 @@ QQuickItemPrivate::ExtraData::ExtraData()
#if QT_CONFIG(accessibility)
-QAccessible::Role QQuickItemPrivate::accessibleRole() const
+QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const
@@ -593,7 +892,7 @@ index 33da9762d3..9e8b289376 100644
+ role = accessibleRole();
+ return role;
+}
+QAccessible::Role QQuickItemPrivate::accessibleRole() const
+{
return QAccessible::NoRole;
@@ -608,26 +907,26 @@ index 841d91bb40..6f329bd119 100644
bool touchEnabled:1;
bool hasCursorHandler:1;
+ quint32 inDestructor:1; // has entered ~QQuickItem
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -574,7 +575,10 @@ public:
virtual void implicitHeightChanged();
#if QT_CONFIG(accessibility)
+ QAccessible::Role effectiveAccessibleRole() const;
+private:
virtual QAccessible::Role accessibleRole() const;
+public:
#endif
void setImplicitAntialiasing(bool antialiasing);
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index fba383e268..0d63618622 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
class QQuickMouseEvent;
class QQuickMouseArea;
-class QQuickPointerMask;
@@ -1023,17 +1322,17 @@ index 39780f8de3..9c97b43518 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -39,6 +39,7 @@
#include "qquickwidget.h"
#include "qquickwidget_p.h"
+#include "qaccessiblequickwidgetfactory_p.h"
#include "private/qquickwindow_p.h"
#include "private/qquickitem_p.h"
@@ -75,9 +76,16 @@
QT_BEGIN_NAMESPACE
+QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
+:QQuickWindow(dd, control)
+{
@@ -1050,7 +1349,7 @@ index 39780f8de3..9c97b43518 100644
Q_Q(QWindow);
@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
Q_Q(QQuickWidget);
renderControl = new QQuickWidgetRenderControl(q);
- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
@@ -1058,7 +1357,7 @@ index 39780f8de3..9c97b43518 100644
+ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
+ offscreenWindow->setScreen(q->screen());
// Do not call create() on offscreenWindow.
// Check if the Software Adaptation is being used
@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
@@ -1069,10 +1368,10 @@ index 39780f8de3..9c97b43518 100644
+ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
+#endif
}
void QQuickWidgetPrivate::ensureEngine() const
@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
context = new QOpenGLContext;
context->setFormat(offscreenWindow->requestedFormat());
- const QWindow *win = q->window()->windowHandle();
@@ -1085,7 +1384,7 @@ index 39780f8de3..9c97b43518 100644
@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
d->handleWindowChange();
break;
- case QEvent::ScreenChangeInternal:
- if (QWindow *window = this->window()->windowHandle()) {
- QScreen *newScreen = window->screen();
@@ -1107,7 +1406,7 @@ index 39780f8de3..9c97b43518 100644
+ d->context->setScreen(newScreen);
#endif
- }
if (d->useSoftwareRenderer
#if QT_CONFIG(opengl)
@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
@@ -1126,7 +1425,7 @@ index 881f7f9220..1a946bcc71 100644
@@ -148,6 +148,14 @@ public:
bool forceFullUpdate;
};
+class QQuickWidgetOffscreenWindow: public QQuickWindow
+{
+ Q_OBJECT
@@ -1136,7 +1435,7 @@ index 881f7f9220..1a946bcc71 100644
+};
+
QT_END_NAMESPACE
#endif // QQuickWidget_P_H
diff --git a/src/quickwidgets/quickwidgets.pro b/src/quickwidgets/quickwidgets.pro
index 2438e577ae..85d156b8a3 100644
@@ -1150,13 +1449,13 @@ index 2438e577ae..85d156b8a3 100644
+ qtquickwidgetsglobal.h \
+ qaccessiblequickwidget_p.h \
+ qaccessiblequickwidgetfactory_p.h
SOURCES += \
- qquickwidget.cpp
+ qquickwidget.cpp \
+ qaccessiblequickwidget.cpp \
+ qaccessiblequickwidgetfactory.cpp
load(qt_module)
diff --git a/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml
new file mode 100644
@@ -1237,7 +1536,7 @@ index 35f1e2c94d..f473cff75f 100644
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -27,6 +27,8 @@
****************************************************************************/
#include <QtTest/qtest.h>
+#include <QtCore/QConcatenateTablesProxyModel>
+#include <QtGui/QStandardItemModel>
@@ -1251,12 +1550,12 @@ index 35f1e2c94d..f473cff75f 100644
+ void redrawUponColumnChange();
+ void deleteRace();
};
class AbstractItemModel : public QAbstractItemModel
@@ -186,6 +190,41 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
QVERIFY(root->property("works").toBool());
}
+void tst_QQmlDelegateModel::redrawUponColumnChange()
+{
+ QStandardItemModel m1;
@@ -1293,7 +1592,7 @@ index 35f1e2c94d..f473cff75f 100644
+}
+
QTEST_MAIN(tst_QQmlDelegateModel)
#include "tst_qqmldelegatemodel.moc"
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index 9c865b3f73..1f788f7a7f 100644
@@ -1309,7 +1608,7 @@ index 9c865b3f73..1f788f7a7f 100644
+ expectedImportPaths.move(expectedImportPaths.indexOf(qml2Imports), 0);
+ QCOMPARE(expectedImportPaths, engine.importPathList());
}
Q_DECLARE_METATYPE(QQmlImports::ImportVersion)
diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml
new file mode 100644
@@ -1340,16 +1639,16 @@ index bffb62c59e..97cc64991f 100644
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -336,6 +336,7 @@ private slots:
void bareInlineComponent();
void hangOnWarning();
+ void objectAsBroken();
void ambiguousContainingType();
@@ -5876,6 +5877,21 @@ void tst_qqmllanguage::ambiguousContainingType()
}
}
+void tst_qqmllanguage::objectAsBroken()
+{
+ QQmlEngine engine;
@@ -1366,7 +1665,7 @@ index bffb62c59e..97cc64991f 100644
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/quick/qquickgridview/data/qtbug86255.qml b/tests/auto/quick/qquickgridview/data/qtbug86255.qml
new file mode 100644
@@ -1438,13 +1737,13 @@ index 94ec4f44d5..7d0d9fa7a7 100644
void QTBUG_49218();
void QTBUG_48870_fastModelUpdates();
+ void QTBUG_86255();
void keyNavigationEnabled();
void resizeDynamicCellWidthRtL();
@@ -6814,6 +6815,18 @@ void tst_QQuickGridView::resizeDynamicCellWidthRtL()
QTRY_COMPARE(gridview->contentX(), 0.f);
}
+void tst_QQuickGridView::QTBUG_86255()
+{
+ QScopedPointer<QQuickView> window(createView());
@@ -1488,13 +1787,13 @@ index c8f251dbe1..c8ef36ee68 100644
void activeFocusOnTab_infiniteLoop_data();
void activeFocusOnTab_infiniteLoop();
+ void activeFocusOnTab_infiniteLoopControls();
void nextItemInFocusChain();
void nextItemInFocusChain2();
@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
QCOMPARE(item, window->rootObject());
}
+
+void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
+{
@@ -1548,7 +1847,7 @@ index aa55b42935..26e86672b0 100644
@@ -1734,6 +1735,16 @@ void tst_qquickstates::trivialWhen()
QVERIFY(c.create());
}
+void tst_qquickstates::jsValueWhen()
+{
+ QQmlEngine engine;
@@ -1660,7 +1959,7 @@ index beeec88f07..2cb7653d65 100644
@@ -522,14 +522,7 @@ int main(int argc, char *argv[])
parser.addPositionalArgument("args",
QCoreApplication::translate("main", "Arguments after '--' are ignored, but passed through to the application.arguments variable in QML."), "[-- args...]");
- if (!parser.parse(QCoreApplication::arguments())) {
- qWarning() << parser.errorText();
- exit(1);
@@ -69,6 +69,13 @@
</Package-->
<History>
<Update release="41">
<Date>2023-09-08</Date>
<Version>5.15.10</Version>
<Comment>Rebuild.</Comment>
<Name>Mustafa Cinasal</Name>
<Email>muscnsl@gmail.com</Email>
</Update>
<Update release="40">
<Date>2023-07-07</Date>
<Version>5.15.10</Version>