aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/particles/qquickparticlesystem.cpp7
-rw-r--r--src/particles/shaders_ng/imageparticle.frag3
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp7
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp7
-rw-r--r--src/qml/common/qv4compileddata_p.h29
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp8
-rw-r--r--src/qml/jsapi/qjsmanagedvalue.cpp7
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper_unix.cpp10
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper_win.cpp17
-rw-r--r--src/qml/jsruntime/qv4context.cpp18
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp9
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h1
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp12
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h4
-rw-r--r--src/qml/jsruntime/qv4module.cpp9
-rw-r--r--src/qml/qml/qqml.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp26
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h89
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h9
-rw-r--r--src/qml/qml/qqmltypedata.cpp11
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp21
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp26
-rw-r--r--src/qmltest/SignalSpy.qml10
-rw-r--r--src/qmltest/TestCase.qml99
-rw-r--r--src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt36
-rw-r--r--src/qmltest/doc/snippets/modules_MyModule_MyButton.qml60
-rw-r--r--src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt30
-rw-r--r--src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml79
-rw-r--r--src/qmltest/doc/snippets/tests_main.cpp56
-rw-r--r--src/qmltest/doc/snippets/tests_setup.cpp69
-rw-r--r--src/qmltest/doc/snippets/tests_setup.h71
-rw-r--r--src/quick/doc/snippets/qml/pathview/pathview.qml9
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler.cpp2
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp7
-rw-r--r--src/quick/items/qquickloader.cpp6
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp7
-rw-r--r--src/quick/items/qquicktableview.cpp42
-rw-r--r--src/quick/items/qquicktableview_p_p.h3
-rw-r--r--src/quick/items/qquickwindow.cpp5
-rw-r--r--src/quick/scenegraph/shaders_ng/24bittextmask.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/32bitcolortext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext_a.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.frag3
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.frag3
-rw-r--r--src/quick/util/qquickdeliveryagent.cpp10
-rw-r--r--src/quickcontrols2/basic/Menu.qml4
-rw-r--r--src/quickcontrols2/fusion/Menu.qml4
-rw-r--r--src/quickcontrols2/imagine/Menu.qml4
-rw-r--r--src/quickcontrols2/material/Menu.qml4
-rw-r--r--src/quickcontrols2/universal/Menu.qml4
-rw-r--r--src/quickshapes/shaders_ng/conicalgradient.frag3
-rw-r--r--src/quickshapes/shaders_ng/lineargradient.frag3
-rw-r--r--src/quickshapes/shaders_ng/radialgradient.frag3
-rw-r--r--src/quicktemplates2/qquickstackview.cpp6
86 files changed, 944 insertions, 138 deletions
diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp
index 5806d7914c..5744c61849 100644
--- a/src/particles/qquickparticlesystem.cpp
+++ b/src/particles/qquickparticlesystem.cpp
@@ -767,10 +767,9 @@ void QQuickParticleSystem::reset()
timeInt = 0;
//Clear guarded pointers which have been deleted
- int cleared = 0;
- cleared += m_emitters.removeAll(nullptr);
- cleared += m_painters.removeAll(nullptr);
- cleared += m_affectors.removeAll(nullptr);
+ m_emitters.removeAll(nullptr);
+ m_painters.removeAll(nullptr);
+ m_affectors.removeAll(nullptr);
bySysIdx.resize(0);
initGroups();//Also clears all logical particles
diff --git a/src/particles/shaders_ng/imageparticle.frag b/src/particles/shaders_ng/imageparticle.frag
index 90b79e6ea9..074771f4fd 100644
--- a/src/particles/shaders_ng/imageparticle.frag
+++ b/src/particles/shaders_ng/imageparticle.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
#if defined(TABLE)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index ae50225035..9c83f8c1fd 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -224,9 +224,10 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
QV4::ScopedValue v(scope);
QV4::Heap::InternalClass *ic = ctxt->internalClass();
for (uint i = 0; i < ic->size; ++i) {
- QString name = ic->keyAt(i);
- names.append(name);
- v = static_cast<QV4::Heap::CallContext *>(ctxt->d())->locals[i];
+ QV4::ScopedValue stringOrSymbol(scope, ic->keyAt(i));
+ QV4::ScopedString propName(scope, stringOrSymbol->toString(scope.engine));
+ names.append(propName->toQString());
+ v = ctxt->getProperty(propName);
collectedRefs.append(addValueRef(v));
}
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index 85b6bac203..ca8f3e3145 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -493,9 +493,10 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a
QV4::Heap::InternalClass *ic = callContext->internalClass();
QV4::ScopedValue v(scope);
for (uint i = 0; i < ic->size; ++i) {
- QString name = ic->keyAt(i);
- v = callContext->d()->locals[i];
- collector.collect(&output, QString(), name, v);
+ QV4::ScopedValue stringOrSymbol(scope, ic->keyAt(i));
+ QV4::ScopedString propName(scope, stringOrSymbol->toString(scope.engine));
+ v = callContext->getProperty(propName);
+ collector.collect(&output, QString(), propName->toQString(), v);
}
}
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index 8b2d5066c6..9453120eb6 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -1322,6 +1322,28 @@ struct TypeReferenceMap : QHash<int, TypeReference>
return *insert(nameIndex, loc);
}
+ template <typename Iterator>
+ void collectFromFunctions(Iterator it, Iterator end)
+ {
+ for (; it != end; ++it) {
+ auto formal = it->formalsBegin();
+ auto formalEnd = it->formalsEnd();
+ for ( ; formal != formalEnd; ++formal) {
+ if (!formal->type.indexIsBuiltinType()) {
+ TypeReference &r
+ = this->add(formal->type.typeNameIndexOrBuiltinType(), it->location);
+ r.errorWhenNotFound = true;
+ }
+ }
+
+ if (!it->returnType.indexIsBuiltinType()) {
+ TypeReference &r
+ = this->add(it->returnType.typeNameIndexOrBuiltinType(), it->location);
+ r.errorWhenNotFound = true;
+ }
+ }
+ }
+
template <typename CompiledObject>
void collectFromObject(const CompiledObject *obj)
{
@@ -1353,13 +1375,6 @@ struct TypeReferenceMap : QHash<int, TypeReference>
this->add(ic->nameIndex, ic->location);
}
}
-
- template <typename Iterator>
- void collectFromObjects(Iterator it, Iterator end)
- {
- for (; it != end; ++it)
- collectFromObject(*it);
- }
};
using DependentTypesHasher = std::function<QByteArray()>;
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 9739c936da..814a5e8c65 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -109,10 +109,14 @@ bool Parameter::initType(QV4::CompiledData::ParameterType *paramType, const QV4:
const QString typeName = stringGenerator->stringForIndex(typeNameIndex);
auto builtinType = stringToBuiltinType(typeName);
if (builtinType == QV4::CompiledData::BuiltinType::InvalidBuiltin) {
- if (typeName.isEmpty() || !typeName.at(0).isUpper()) {
+ if (typeName.isEmpty() || typeName == QLatin1String("void")) {
+ paramType->set(true, quint32(builtinType));
+ return false;
+ } else if (!typeName.at(0).isUpper()) {
paramType->set(false, 0);
return false;
}
+
Q_ASSERT(quint32(typeNameIndex) < (1u << 31));
paramType->set(false, typeNameIndex);
} else {
@@ -1805,7 +1809,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
nextOffset += signalTableSize;
quint32_le *enumOffsetTable = reinterpret_cast<quint32_le*>(objectPtr + objectToWrite->offsetToEnums);
- quint32 enumTableSize = 0;
char *enumPtr = objectPtr + nextOffset;
for (const Enum *e = o->firstEnum(); e; e = e->next) {
*enumOffsetTable++ = enumPtr - objectPtr;
@@ -1820,7 +1823,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
*enumValueToWrite = *enumValue;
int size = QV4::CompiledData::Enum::calculateSize(e->enumValues->count);
- enumTableSize += size;
enumPtr += size;
}
diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp
index ce43b958cf..85406c21b2 100644
--- a/src/qml/jsapi/qjsmanagedvalue.cpp
+++ b/src/qml/jsapi/qjsmanagedvalue.cpp
@@ -1123,8 +1123,11 @@ QStringList QJSManagedValue::jsMetaMembers() const
const int size = heapClass->size;
QStringList result;
result.reserve(size);
- for (int i = 0; i < size; ++i)
- result.append(heapClass->keyAt(i));
+ QV4::Scope scope(c->engine());
+ for (int i = 0; i < size; ++i) {
+ QV4::ScopedValue key(scope, heapClass->keyAt(i));
+ result.append(key->toQString());
+ }
return result;
}
diff --git a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp
index a9ab2f5ccb..b66e6b9467 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp
+++ b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp
@@ -79,6 +79,16 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
// Data structure and qt version matched, so now we can access the rest of the file safely.
length = static_cast<size_t>(lseek(fd, 0, SEEK_END));
+ /* Error out early on file corruption. We assume we can read header.unitSize bytes
+ later (even before verifying the checksum), potentially causing out-of-bound
+ reads
+ Also, no need to wait until checksum verification if we know beforehand
+ that the cached unit is bogus
+ */
+ if (length != header.unitSize) {
+ *errorString = QStringLiteral("Potential file corruption, file too small");
+ return nullptr;
+ }
void *ptr = mmap(nullptr, length, PROT_READ, MAP_SHARED, fd, /*offset*/0);
if (ptr == MAP_FAILED) {
diff --git a/src/qml/jsruntime/qv4compilationunitmapper_win.cpp b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp
index b4f0a6ff4d..de950ece05 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper_win.cpp
+++ b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp
@@ -86,6 +86,23 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
// Data structure and qt version matched, so now we can access the rest of the file safely.
+ /* Error out early on file corruption. We assume we can read header.unitSize bytes
+ later (even before verifying the checksum), potentially causing out-of-bound
+ reads
+ Also, no need to wait until checksum verification if we know beforehand
+ that the cached unit is bogus
+ */
+ LARGE_INTEGER fileSize;
+ if (!GetFileSizeEx(handle, &fileSize)) {
+ *errorString = QStringLiteral("Could not determine file size");
+ return nullptr;
+ }
+ if (header.unitSize != fileSize.QuadPart) {
+ *errorString = QStringLiteral("Potential file corruption, file too small");
+ return nullptr;
+ }
+
+
HANDLE fileMappingHandle = CreateFileMapping(handle, 0, PAGE_READONLY, 0, 0, 0);
if (!fileMappingHandle) {
*errorString = qt_error_string(GetLastError());
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 282046f3fa..c3df66f67e 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -334,9 +334,14 @@ ReturnedValue ExecutionContext::getProperty(String *name)
case Heap::ExecutionContext::Type_CallContext: {
Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
- uint index = c->internalClass->indexOfValueOrGetter(id);
- if (index < UINT_MAX)
+ const uint index = c->internalClass->indexOfValueOrGetter(id);
+ if (index < c->locals.alloc)
return c->locals[index].asReturnedValue();
+
+ // TODO: We should look up the module imports here, but those are part of the CU:
+ // imports[index - c->locals.size];
+ // See QTBUG-118478
+
Q_FALLTHROUGH();
}
case Heap::ExecutionContext::Type_WithContext:
@@ -384,9 +389,14 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
case Heap::ExecutionContext::Type_CallContext: {
Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
- uint index = c->internalClass->indexOfValueOrGetter(id);
- if (index < UINT_MAX)
+ const uint index = c->internalClass->indexOfValueOrGetter(id);
+ if (index < c->locals.alloc)
return c->locals[index].asReturnedValue();
+
+ // TODO: We should look up the module imports here, but those are part of the CU:
+ // imports[index - c->locals.size];
+ // See QTBUG-118478
+
Q_FALLTHROUGH();
}
case Heap::ExecutionContext::Type_GlobalContext: {
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 0927687578..b303dd497a 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -2503,6 +2503,13 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi
return true;
}
}
+
+ if (metaType == QMetaType::fromType<QQmlListProperty<QObject>>()) {
+ if (const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) {
+ *reinterpret_cast<QQmlListProperty<QObject> *>(data) = wrapper->d()->property();
+ return true;
+ }
+ }
}
{
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 7fe3862172..ba10d29d51 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -517,6 +517,15 @@ int ExecutableCompilationUnit::totalObjectCount() const {
return inlineComponentData[icRoot].totalObjectCount;
}
+ResolvedTypeReference *ExecutableCompilationUnit::resolvedType(QMetaType type) const
+{
+ for (ResolvedTypeReference *ref : std::as_const(resolvedTypes)) {
+ if (ref->type().typeId() == type)
+ return ref;
+ }
+ return nullptr;
+}
+
int ExecutableCompilationUnit::totalParserStatusCount() const {
if (icRoot == -1)
return m_totalParserStatusCount;
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index 9ceec1fbf7..38d35baf3f 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -175,6 +175,7 @@ public:
QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
ResolvedTypeReferenceMap resolvedTypes;
ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
+ ResolvedTypeReference *resolvedType(QMetaType type) const;
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index eabb220c50..fdaa8cbaa4 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -329,9 +329,15 @@ void InternalClass::destroy()
Base::destroy();
}
-QString InternalClass::keyAt(uint index) const
-{
- return nameMap.at(index).toQString();
+ReturnedValue InternalClass::keyAt(uint index) const
+{
+ PropertyKey key = nameMap.at(index);
+ if (!key.isValid())
+ return Encode::undefined();
+ if (key.isArrayIndex())
+ return Encode(key.asArrayIndex());
+ Q_ASSERT(key.isStringOrSymbol());
+ return key.asStringOrSymbol()->asReturnedValue();
}
void InternalClass::changeMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry)
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 37dbeded6f..a80ec2e957 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -343,7 +343,7 @@ struct InternalClass : Base {
void init(InternalClass *other);
void destroy();
- Q_QML_PRIVATE_EXPORT QString keyAt(uint index) const;
+ Q_QML_PRIVATE_EXPORT ReturnedValue keyAt(uint index) const;
Q_REQUIRED_RESULT InternalClass *nonExtensible();
static void addMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry);
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 301dad38fd..382f6c684a 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -230,10 +230,6 @@ struct Q_QML_PRIVATE_EXPORT Lookup {
markDef.h2->mark(stack);
}
- void clear() {
- memset(&markDef, 0, sizeof(markDef));
- }
-
void releasePropertyCache()
{
if (getter == getterQObject
diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp
index 26bef9cd37..548dd7be25 100644
--- a/src/qml/jsruntime/qv4module.cpp
+++ b/src/qml/jsruntime/qv4module.cpp
@@ -258,9 +258,12 @@ OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *t
if (module->d()->unit->isESModule()) {
names = module->d()->unit->exportedNames();
} else {
- Heap::InternalClass *scopeClass = module->d()->scope->internalClass;
- for (uint i = 0; i < scopeClass->size; ++i)
- names << scopeClass->keyAt(i);
+ QV4::Scope scope(module->engine());
+ QV4::Scoped<InternalClass> scopeClass(scope, module->d()->scope->internalClass);
+ for (uint i = 0, end = scopeClass->d()->size; i < end; ++i) {
+ QV4::ScopedValue key(scope, scopeClass->d()->keyAt(i));
+ names << key->toQString();
+ }
}
return new ModuleNamespaceIterator(names);
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 1b737ee308..c5ec43bbb7 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -1059,7 +1059,7 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
// the property cache we store a value into the property.
QV4::Lookup l;
- l.clear();
+ memset(&l, 0, sizeof(QV4::Lookup));
l.nameIndex = nameIndex;
ObjectPropertyResult storeResult = ObjectPropertyResult::NeedsInit;
switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType())) {
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index fc629bc060..b544852953 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -901,10 +901,13 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
&& !(bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver)
&& !_valueTypeProperty;
- if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && allowedToRemoveBinding) {
- QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()));
- } else if (bindingProperty->isBindable() && allowedToRemoveBinding) {
- removePendingBinding(_bindingTarget, bindingProperty->coreIndex());
+ if (allowedToRemoveBinding) {
+ if (bindingProperty->isBindable()) {
+ removePendingBinding(_bindingTarget, bindingProperty->coreIndex());
+ } else {
+ QQmlPropertyPrivate::removeBinding(
+ _bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()));
+ }
}
if (bindingType == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) {
@@ -950,6 +953,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index);
}
sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding });
+
+ QQmlData *data = QQmlData::get(_bindingTarget, true);
+ data->setBindingBit(_bindingTarget, bindingProperty->coreIndex());
} else {
// When writing bindings to grouped properties implemented as value types,
// such as point.x: { someExpression; }, then the binding is installed on
@@ -1467,17 +1473,27 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
while (!sharedState->allQPropertyBindings.isEmpty()) {
auto& [target, index, qmlBinding] = sharedState->allQPropertyBindings.first();
+
+ QQmlData *data = QQmlData::get(target);
+ if (!data || !data->hasBindingBit(index)) {
+ // The target property has been overwritten since we stashed the binding.
+ sharedState->allQPropertyBindings.pop_front();
+ continue;
+ }
+
QUntypedBindable bindable;
void *argv[] = { &bindable };
// allow interception
target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv);
const bool success = bindable.setBinding(qmlBinding);
+ const auto bindingPrivateRefCount = QPropertyBindingPrivate::get(qmlBinding)->ref;
+
// Only pop_front after setting the binding as the bindings are refcounted.
sharedState->allQPropertyBindings.pop_front();
// If the binding was actually not set, it's deleted now.
- if (success) {
+ if (success && bindingPrivateRefCount > 1) {
if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv);
auto jsExpression = qmlBindingPriv->jsExpression();
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index c415b5f33a..3ce665c24f 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -932,53 +932,74 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
QQmlPropertyData *targetProperty = targetCache->property(coreIndex);
Q_ASSERT(targetProperty);
+ const QMetaType targetPropType = targetProperty->propType();
+
+ const auto resolveType = [](QMetaType targetPropType) {
+ if (targetPropType.flags() & QMetaType::IsEnumeration)
+ return QMetaType::fromType<int>();
+ else
+ return targetPropType;
+ };
+
+ const auto populateWithPropertyData = [&](const QQmlPropertyData *property) {
+ *type = resolveType(property->propType());
+ writable = property->isWritable();
+ resettable = property->isResettable();
+ bindable = property->isBindable();
+
+ // Copy type flags
+ propertyFlags->copyPropertyTypeFlags(property->flags());
+ if (property->isVarProperty())
+ propertyFlags->type = QQmlPropertyData::Flags::QVariantType;
+ };
+
// for deep aliases, valueTypeIndex is always set
- if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) {
+ if (!QQmlMetaType::isValueType(targetPropType) && valueTypeIndex != -1) {
// deep alias property
- *type = targetProperty->propType();
- targetCache = enginePriv->propertyCacheForType(type->id());
- Q_ASSERT(targetCache);
- targetProperty = targetCache->property(valueTypeIndex);
- if (targetProperty == nullptr) {
- return qQmlCompileError(alias.referenceLocation,
- QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ QQmlRefPointer<QQmlPropertyCache> typeCache
+ = enginePriv->propertyCacheForType(targetPropType.id());
+
+ if (!typeCache) {
+ // See if it's a half-resolved composite type
+ if (const QV4::ResolvedTypeReference *typeRef
+ = objectContainer->resolvedType(targetPropType)) {
+ typeCache = typeRef->typePropertyCache();
+ }
}
- *type = targetProperty->propType();
- writable = targetProperty->isWritable();
- resettable = targetProperty->isResettable();
- bindable = targetProperty->isBindable();
+ const QQmlPropertyData *typeProperty = typeCache
+ ? typeCache->property(valueTypeIndex)
+ : nullptr;
+ if (typeProperty == nullptr) {
+ return qQmlCompileError(
+ alias.referenceLocation,
+ QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ }
+ populateWithPropertyData(typeProperty);
} else {
// value type or primitive type or enum
- *type = targetProperty->propType();
-
- writable = targetProperty->isWritable();
- resettable = targetProperty->isResettable();
- bindable = targetProperty->isBindable();
+ populateWithPropertyData(targetProperty);
if (valueTypeIndex != -1) {
- const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(*type);
- if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
- *type = QMetaType::fromType<int>();
- else
- *type = valueTypeMetaObject->property(valueTypeIndex).metaType();
- } else {
- if (targetProperty->isEnum()) {
- *type = QMetaType::fromType<int>();
- } else {
- // Copy type flags
- propertyFlags->copyPropertyTypeFlags(targetProperty->flags());
-
- if (targetProperty->isVarProperty())
- propertyFlags->type = QQmlPropertyData::Flags::QVariantType;
- }
+ const QMetaObject *valueTypeMetaObject
+ = QQmlMetaType::metaObjectForValueType(*type);
+ const QMetaProperty valueTypeMetaProperty
+ = valueTypeMetaObject->property(valueTypeIndex);
+ *type = resolveType(valueTypeMetaProperty.metaType());
+
+ // We can only write or reset the value type property if we can write
+ // the value type itself.
+ resettable = writable && valueTypeMetaProperty.isResettable();
+ writable = writable && valueTypeMetaProperty.isWritable();
+
+ bindable = valueTypeMetaProperty.isBindable();
}
}
}
- propertyFlags->setIsWritable(!(alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly))
- && writable);
+ propertyFlags->setIsWritable(
+ writable && !alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly));
propertyFlags->setIsResettable(resettable);
propertyFlags->setIsBindable(bindable);
return QQmlError();
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index 1a100828f8..5b92b8de4a 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -132,6 +132,15 @@ public:
return resolvedTypes->value(id);
}
+ QV4::ResolvedTypeReference *resolvedType(QMetaType type) const
+ {
+ for (QV4::ResolvedTypeReference *ref : std::as_const(*resolvedTypes)) {
+ if (ref->type().typeId() == type)
+ return ref;
+ }
+ return nullptr;
+ }
+
CompositeMetaTypeIds typeIdsForComponent(int objectId = 0) const;
private:
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index fe9729cf75..a244bdd0ba 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -160,6 +160,9 @@ bool QQmlTypeData::tryLoadFromDiskCache()
for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) {
auto object = m_compiledData->objectAt(i);
m_typeReferences.collectFromObject(object);
+ m_typeReferences.collectFromFunctions(
+ m_compiledData->objectFunctionsBegin(object),
+ m_compiledData->objectFunctionsEnd(object));
const auto inlineComponentTable = object->inlineComponentTable();
for (auto i = 0; i != object->nInlineComponents; ++i) {
ics.push_back(inlineComponentTable[i]);
@@ -660,7 +663,13 @@ void QQmlTypeData::continueLoadFromIR()
}
}
- m_typeReferences.collectFromObjects(m_document->objects.constBegin(), m_document->objects.constEnd());
+ for (auto it = m_document->objects.constBegin(), end = m_document->objects.constEnd();
+ it != end; ++it) {
+ const QmlIR::Object *object = *it;
+ m_typeReferences.collectFromObject(object);
+ m_typeReferences.collectFromFunctions(object->functionsBegin(), object->functionsEnd());
+ }
+
m_importCache.setBaseUrl(finalUrl(), finalUrlString());
// For remote URLs, we don't delay the loading of the implicit import
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 93736b0002..ce245ea6ce 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -91,8 +91,25 @@ const QMetaObject *QQmlTypeWrapper::metaObject() const
if (!type.isValid())
return nullptr;
- if (type.isSingleton())
- return type.metaObject();
+ if (type.isSingleton()) {
+ auto metaObjectCandidate = type.metaObject();
+ // if the candidate is the same as te baseMetaObject, we know that
+ // we don't have an extended singleton; in that case the
+ // actual instance might be subclass of type instead of type itself
+ // so we need to query the actual object for it's meta-object
+ if (metaObjectCandidate == type.baseMetaObject()) {
+ QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine()->qmlEngine());
+ auto object = qmlEngine->singletonInstance<QObject *>(type);
+ if (object)
+ return object->metaObject();
+ }
+ /* if we instead have an extended singleton, the dynamic proxy
+ meta-object must alreday be set up correctly
+ ### TODO: it isn't, as QQmlTypePrivate::init has no way to
+ query the object
+ */
+ return metaObjectCandidate;
+ }
return type.attachedPropertiesType(QQmlEnginePrivate::get(engine()->qmlEngine()));
}
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index b6f68536ca..053058341a 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -925,15 +925,20 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
int coreIndex = encodedIndex.coreIndex();
const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
- // Remove binding (if any) on write
- if(c == QMetaObject::WriteProperty) {
- int flags = *reinterpret_cast<int*>(a[3]);
- if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
- QQmlData *targetData = QQmlData::get(target);
- if (targetData && targetData->hasBindingBit(coreIndex))
- QQmlPropertyPrivate::removeBinding(target, encodedIndex);
+ const auto removePendingBinding
+ = [c, a](QObject *target, int coreIndex, QQmlPropertyIndex encodedIndex) {
+ // Remove binding (if any) on write
+ if (c == QMetaObject::WriteProperty) {
+ int flags = *reinterpret_cast<int*>(a[3]);
+ if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
+ QQmlData *targetData = QQmlData::get(target);
+ if (targetData && targetData->hasBindingBit(coreIndex)) {
+ QQmlPropertyPrivate::removeBinding(target, encodedIndex);
+ targetData->clearBindingBit(coreIndex);
+ }
+ }
}
- }
+ };
if (valueTypePropertyIndex != -1) {
if (!targetDData->propertyCache)
@@ -943,6 +948,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
ctxt->engine(), pd->propType());
if (valueType) {
+ removePendingBinding(target, coreIndex, encodedIndex);
valueType->read(target, coreIndex);
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
@@ -954,10 +960,14 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
// deep alias
void *argv[1] = { &target };
QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
+ removePendingBinding(
+ target, valueTypePropertyIndex,
+ QQmlPropertyIndex(valueTypePropertyIndex));
return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
}
} else {
+ removePendingBinding(target, coreIndex, encodedIndex);
return QMetaObject::metacall(target, c, coreIndex, a);
}
diff --git a/src/qmltest/SignalSpy.qml b/src/qmltest/SignalSpy.qml
index 7257e4f3f3..641f8642c6 100644
--- a/src/qmltest/SignalSpy.qml
+++ b/src/qmltest/SignalSpy.qml
@@ -81,6 +81,16 @@ Item {
id: spy
visible: false
+ Component.onDestruction: {
+ // We are potentially destroyed before the target object,
+ // and since only the sender (target) being destroyed destroys a connection
+ // in QML, and not the receiver (us/"spy"), we need to manually disconnect.
+ // When QTBUG-118166 is implemented, we can remove this.
+ let signalFunc = target ? target[signalName] : null
+ if (signalFunc)
+ signalFunc.disconnect(spy.qtest_activated)
+ }
+
TestUtil {
id: util
}
diff --git a/src/qmltest/TestCase.qml b/src/qmltest/TestCase.qml
index 5a2cd1d5c4..2b817ad7dd 100644
--- a/src/qmltest/TestCase.qml
+++ b/src/qmltest/TestCase.qml
@@ -260,6 +260,105 @@ import "testlogger.js" as TestLogger
of \l Component, the \l createTemporaryObject() function can be used.
\sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test}
+
+ \section1 Separating tests from application logic
+
+ In most cases, you would want to separate your tests from the application
+ logic by splitting them into different projects and linking them.
+
+ For example, you could have the following project structure:
+
+ \badcode
+ .
+ | — CMakeLists.txt
+ | — src
+ | | — main.cpp
+ | — qml
+ | | — main.qml
+ | — modules
+ | | — MyModule
+ | | — MyButton.qml
+ | | — CMakeLists.txt
+ | — tests
+ | — UnitQMLTests
+ | — tst_testqml.qml
+ | — tests_main.cpp
+ | — tests_setup.cpp
+ | — tests_setup.h
+ \endcode
+
+ Now, to test \c modules/MyModule/MyButton.qml, create a library for
+ \c MyModule in \c modules/MyModule/CMakeLists.txt and link it to your
+ test project, \c tests/UnitQMLTests/CMakeLists.txt:
+
+ \if defined(onlinedocs)
+ \tab {build-qt-app}{tab-cmake-add-library}{modules/MyModule/CMakeLists.txt}{checked}
+ \tab {build-qt-app}{tab-cmake-link-against-library}{tests/UnitQMLTests/CMakeLists.txt}{}
+ \tab {build-qt-app}{tab-tests_main}{tests/UnitQMLTests/tests_main.cpp}{}
+ \tab {build-qt-app}{tab-tests-setup-cpp}{tests/UnitQMLTests/tests_setup.cpp}{}
+ \tab {build-qt-app}{tab-tests-setup-h}{tests/UnitQMLTests/tests_setup.h}{}
+ \tabcontent {tab-cmake-add-library}
+ \else
+ \section1 Add library
+ \endif
+ \dots
+ \snippet modules_MyModule_CMakeLists.txt add library
+ \dots
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-cmake-link-against-library}
+ \else
+ \section1 Link against library
+ \endif
+ \dots
+ \snippet tests_UnitQMLTests_CMakeLists.txt link against library
+ \dots
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-tests_main}
+ \else
+ \section1 main.cpp
+ \endif
+ \snippet tests_main.cpp main
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-tests-setup-cpp}
+ \else
+ \section1 setup c++
+ \endif
+ \snippet tests_setup.cpp setup
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-tests-setup-h}
+ \else
+ \section1 setup header
+ \endif
+ \snippet tests_setup.h setup
+ \if defined(onlinedocs)
+ \endtabcontent
+ \endif
+
+ Then, in \c tests/UnitQMLTests/tst_testqml.qml, you can import
+ \c modules/MyModule/MyButton.qml:
+
+ \if defined(onlinedocs)
+ \tab {test-qml}{tab-qml-import}{tests/UnitQMLTests/tst_testqml.qml}{checked}
+ \tab {test-qml}{tab-qml-my-button}{modules/MyModule/MyButton.qml}{}
+ \tabcontent {tab-qml-import}
+ \else
+ \section1 Import QML
+ \endif
+ \snippet tests_UnitQMLTests_tst_testqml.qml import
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-qml-my-button}
+ \else
+ \section1 Define QML button
+ \endif
+ \snippet modules_MyModule_MyButton.qml define
+ \if defined(onlinedocs)
+ \endtabcontent
+ \endif
*/
diff --git a/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt
new file mode 100644
index 0000000000..37ac70aaa2
--- /dev/null
+++ b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.20)
+
+set(MODULE_NAME "MyModule")
+project(${MODULE_NAME} LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick)
+
+file(GLOB QML_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
+source_group("Qml Files" FILES ${QML_SOURCES})
+
+//! [add library]
+qt_add_library(MyModule STATIC)
+
+qt6_add_qml_module(MyModule
+ URI MyModule
+ VERSION 1.0
+ QML_FILES ${QML_SOURCES}
+)
+//! [add library]
+
+set_target_properties(MyModule PROPERTIES
+ MACOSX_BUNDLE TRUE
+ WIN32_EXECUTABLE FALSE
+)
+
+target_link_libraries(MyModule PRIVATE
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+)
+
+target_include_directories(MyModule PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml
new file mode 100644
index 0000000000..5d7dd9c7dd
--- /dev/null
+++ b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [define]
+import QtQuick
+import QtQuick.Controls
+
+Button {
+ width: 50
+ height: 50
+ onClicked: width = 100
+}
+//! [define]
diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt
new file mode 100644
index 0000000000..ba444c2cd6
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.2)
+
+project(TestQML LANGUAGES CXX)
+
+enable_testing()
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTest Qml)
+find_package(Qt6 REQUIRED COMPONENTS QuickTest Qml)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+# no need to copy around qml test files for shadow builds - just set the respective define
+add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
+
+//! [link against library]
+add_executable(TestQML tests_main.cpp
+ tests_setup.cpp tests_setup.h)
+
+add_test(NAME TestQML COMMAND TestQML)
+
+target_link_libraries(
+ TestQML
+ PRIVATE Qt6::QuickTest
+ PRIVATE Qt6::Qml
+ PRIVATE MyModule
+ PRIVATE MyModuleplugin
+)
+//! [link against library]
diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml
new file mode 100644
index 0000000000..432d20d762
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [import]
+import QtQuick
+import QtQuick.Controls
+
+import QtTest
+import MyModule
+
+Item {
+ width: 800
+ height: 600
+
+ MyButton {
+ id: myButton
+ anchors.centerIn: parent
+ }
+
+ TestCase {
+ name: "MyButton"
+ when: windowShown
+
+ function test_clickToExpand() {
+ const widthBeforeClick = myButton.width;
+ mouseClick(myButton);
+ const widthAfterClick = myButton.width;
+ verify(widthBeforeClick < widthAfterClick);
+ }
+ }
+}
+//! [import]
diff --git a/src/qmltest/doc/snippets/tests_main.cpp b/src/qmltest/doc/snippets/tests_main.cpp
new file mode 100644
index 0000000000..983f932acd
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [main]
+#include <QtQuickTest/quicktest.h>
+#include "tests_setup.h"
+
+QUICK_TEST_MAIN_WITH_SETUP(TestQML, Setup)
+//! [main]
diff --git a/src/qmltest/doc/snippets/tests_setup.cpp b/src/qmltest/doc/snippets/tests_setup.cpp
new file mode 100644
index 0000000000..f7914dda87
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_setup.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [setup]
+#include "tests_setup.h"
+
+void Setup::applicationAvailable()
+{
+ // custom code that doesn't require QQmlEngine
+}
+
+void Setup::qmlEngineAvailable(QQmlEngine *engine)
+{
+ // add import paths
+ engine->addImportPath("../../");
+}
+
+void Setup::cleanupTestCase()
+{
+ // custom code to clean up before destruction starts
+}
+//! [setup]
diff --git a/src/qmltest/doc/snippets/tests_setup.h b/src/qmltest/doc/snippets/tests_setup.h
new file mode 100644
index 0000000000..f5baa04eeb
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_setup.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [setup]
+#ifndef SETUP_H
+#define SETUP_H
+
+#include <QObject>
+#include <QQmlEngine>
+
+class Setup : public QObject
+{
+ Q_OBJECT
+public:
+ Setup() = default;
+
+public slots:
+ void applicationAvailable();
+ void qmlEngineAvailable(QQmlEngine *engine);
+ void cleanupTestCase();
+};
+
+#endif // SETUP_H
+//! [setup]
diff --git a/src/quick/doc/snippets/qml/pathview/pathview.qml b/src/quick/doc/snippets/qml/pathview/pathview.qml
index 58d19b1a0c..0c3b96bb26 100644
--- a/src/quick/doc/snippets/qml/pathview/pathview.qml
+++ b/src/quick/doc/snippets/qml/pathview/pathview.qml
@@ -59,15 +59,20 @@ Rectangle {
id: delegate
Column {
id: wrapper
+
+ required property url icon
+ required property string name
+
opacity: PathView.isCurrentItem ? 1 : 0.5
+
Image {
anchors.horizontalCenter: nameText.horizontalCenter
width: 64; height: 64
- source: icon
+ source: wrapper.icon
}
Text {
id: nameText
- text: name
+ text: wrapper.name
font.pointSize: 16
}
}
diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp
index 69080b2027..a016ba5f12 100644
--- a/src/quick/handlers/qquickpointerdevicehandler.cpp
+++ b/src/quick/handlers/qquickpointerdevicehandler.cpp
@@ -306,7 +306,7 @@ bool QQuickPointerDeviceHandler::wantsPointerEvent(QPointerEvent *event)
if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers)
return false;
// Some handlers (HoverHandler, PinchHandler) set acceptedButtons to Qt::NoButton to indicate that button state is irrelevant.
- if (event->pointingDevice()->pointerType() != QPointingDevice::PointerType::Finger &&
+ if (event->pointingDevice()->type() != QPointingDevice::DeviceType::TouchScreen &&
acceptedButtons() != Qt::NoButton && event->type() != QEvent::Wheel &&
(static_cast<QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == 0 &&
(static_cast<QSinglePointEvent *>(event)->button() & acceptedButtons()) == 0)
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index 3abb366676..2b907d3805 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -121,15 +121,16 @@ bool QQuickTapHandler::wantsEventPoint(const QPointerEvent *event, const QEventP
ret = parentContains(point);
break;
case QEventPoint::Updated:
+ ret = point.id() == this->point().id();
switch (m_gesturePolicy) {
case DragThreshold:
- ret = !overThreshold && parentContains(point);
+ ret = ret && !overThreshold && parentContains(point);
break;
case WithinBounds:
- ret = parentContains(point);
+ ret = ret && parentContains(point);
break;
case ReleaseWithinBounds:
- ret = point.id() == this->point().id();
+ // no change to ret: depends only whether it's the already-tracking point ID
break;
}
break;
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 1f5c55cffe..b1733b1791 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -197,9 +197,7 @@ qreal QQuickLoaderPrivate::getImplicitHeight() const
\section2 Loader Sizing Behavior
- If the source component is not an Item type, Loader does not
- apply any special sizing rules. When used to load visual types,
- Loader applies the following sizing rules:
+ When used to load visual types, Loader applies the following sizing rules:
\list
\li If an explicit size is not specified for the Loader, the Loader
@@ -226,6 +224,8 @@ qreal QQuickLoaderPrivate::getImplicitHeight() const
\li The red rectangle will be 50x50, centered in the root item.
\endtable
+ If the source component is not an Item type, Loader does not apply any
+ special sizing rules.
\section2 Receiving Signals from Loaded Objects
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 8687de8f43..d4b6e4c963 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -687,7 +687,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints
emit released(_releasedTouchPoints);
if (moved)
emit updated(_movedTouchPoints);
- if (started)
+ if (started && !_pressedTouchPoints.isEmpty())
emit pressed(_pressedTouchPoints);
if (ended || moved || started) emit touchUpdated(_touchPoints.values());
}
@@ -732,12 +732,15 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QEventPoint *p)
void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e)
{
QQuickTouchPoint *dtp = nullptr;
- for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes))
+ for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) {
if (!tp->inUse()) {
tp->setInUse(true);
dtp = tp;
break;
+ } else if (_mouseTouchPoint == tp) {
+ return; // do not allow more than one touchpoint to react to the mouse (QTBUG-83662)
}
+ }
if (dtp == nullptr)
dtp = new QQuickTouchPoint(false);
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 9f259166df..f8f56557ae 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1593,21 +1593,22 @@ void QQuickTableViewPrivate::forceLayout()
const QSize actualTableSize = calculateTableSize();
if (tableSize != actualTableSize) {
- // This can happen if the app is calling forceLayout while
- // the model is updated, but before we're notified about it.
- rebuildOptions = RebuildOption::All;
- } else {
- // Resizing a column (or row) can result in the table going from being
- // e.g completely inside the viewport to go outside. And in the latter
- // case, the user needs to be able to scroll the viewport, also if
- // flags such as Flickable.StopAtBounds is in use. So we need to
- // update contentWidth/Height to support that case.
- rebuildOptions = RebuildOption::LayoutOnly
- | RebuildOption::CalculateNewContentWidth
- | RebuildOption::CalculateNewContentHeight
- | checkForVisibilityChanges();
+ // The table size will have changed if forceLayout is called after
+ // the row count in the model has changed, but before we received
+ // a rowsInsertedCallback about it (and vice versa for columns).
+ rebuildOptions |= RebuildOption::ViewportOnly;
}
+ // Resizing a column (or row) can result in the table going from being
+ // e.g completely inside the viewport to go outside. And in the latter
+ // case, the user needs to be able to scroll the viewport, also if
+ // flags such as Flickable.StopAtBounds is in use. So we need to
+ // update contentWidth/Height to support that case.
+ rebuildOptions |= RebuildOption::LayoutOnly
+ | RebuildOption::CalculateNewContentWidth
+ | RebuildOption::CalculateNewContentHeight
+ | checkForVisibilityChanges();
+
scheduleRebuildTable(rebuildOptions);
auto rootView = rootSyncView();
@@ -3232,9 +3233,6 @@ QVariant QQuickTableViewPrivate::modelImpl() const
void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel)
{
- if (newModel == assignedModel)
- return;
-
assignedModel = newModel;
scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
emit q_func()->modelChanged();
@@ -3242,7 +3240,7 @@ void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel)
void QQuickTableViewPrivate::syncModel()
{
- if (modelVariant == assignedModel)
+ if (compareModel(modelVariant, assignedModel))
return;
if (model) {
@@ -3498,6 +3496,13 @@ void QQuickTableViewPrivate::modelResetCallback()
scheduleRebuildTable(RebuildOption::All);
}
+bool QQuickTableViewPrivate::compareModel(const QVariant& model1, const QVariant& model2) const
+{
+ return (model1 == model2 ||
+ (model1.userType() == qMetaTypeId<QJSValue>() && model2.userType() == qMetaTypeId<QJSValue>() &&
+ model1.value<QJSValue>().strictlyEquals(model2.value<QJSValue>())));
+}
+
void QQuickTableViewPrivate::scheduleRebuildIfFastFlick()
{
Q_Q(QQuickTableView);
@@ -3727,6 +3732,9 @@ QVariant QQuickTableView::model() const
void QQuickTableView::setModel(const QVariant &newModel)
{
+ if (d_func()->compareModel(newModel, d_func()->assignedModel))
+ return;
+
return d_func()->setModelImpl(newModel);
}
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 9893cd97e7..3f969ab195 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -249,7 +249,7 @@ public:
// When the applications assignes a new model or delegate to the view, we keep them
// around until we're ready to take them into use (syncWithPendingChanges).
QVariant assignedModel = QVariant(int(0));
- QQmlComponent *assignedDelegate = nullptr;
+ QQmlGuard<QQmlComponent> assignedDelegate;
// loadedRows/Columns describes the rows and columns that are currently loaded (from top left
// row/column to bottom right row/column). loadedTableOuterRect describes the actual
@@ -477,6 +477,7 @@ public:
void columnsRemovedCallback(const QModelIndex &parent, int begin, int end);
void layoutChangedCallback(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
void modelResetCallback();
+ bool compareModel(const QVariant& model1, const QVariant& model2) const;
void scheduleRebuildIfFastFlick();
void setLocalViewportX(qreal contentX);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 597cd300df..a08f46a1b4 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -3305,6 +3305,11 @@ void QQuickWindow::endExternalCommands()
The (x,y) position is relative to the \l Screen if there is only one,
or to the virtual desktop (arrangement of multiple screens).
+ \note Not all windowing systems support setting or querying top level
+ window positions. On such a system, programmatically moving windows
+ may not have any effect, and artificial values may be returned for
+ the current positions, such as \c QPoint(0, 0).
+
\qml
Window { x: 100; y: 100; width: 100; height: 100 }
\endqml
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
index ed8da4cd30..49023666ce 100644
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
index 4198a4d339..000adb619e 100644
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
index a06743876d..9507728803 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
index f725cbc5e7..9c0f36b81f 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
index b1551d8ef4..9e89d17219 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
index 7c6bd9a493..4fe30b69ee 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag
index 30ec465791..4dc7432e44 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag
index 511bffb09a..44aea6b979 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag
index aa3390094b..320c19973b 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag
index ab3a5f63ff..0ddd1b40d1 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag
index 8f528fea1e..8b124213a4 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag
index a71cc1d9b0..40f519636e 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag
index d594207567..a86f68c8cb 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag
index bb807d86d8..449647561f 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag
index 1aa1175b57..534ec9208c 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag
index a698c19550..04886d6b12 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag b/src/quick/scenegraph/shaders_ng/flatcolor.frag
index 3a677b7c93..cac8f1fb17 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.frag
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) out vec4 fragColor;
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag
index 723227a04d..19dce21aa4 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag
index a9d56f6380..0cfe63edbf 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag
index 08b2ce5187..343e93f54f 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec3 sampleNearLeft;
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag
index ef9407491b..e5aef90fda 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec3 sampleNearLeft;
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag b/src/quick/scenegraph/shaders_ng/opaquetexture.frag
index 2cd2175f87..18dd7e0fcb 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 qt_TexCoord;
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
index e2f82d3845..6a5e1aa28b 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
index 274d891a3c..853f08e8ee 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag b/src/quick/scenegraph/shaders_ng/shadereffect.frag
index bde493f6ce..ef4bbe78f3 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.frag
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag b/src/quick/scenegraph/shaders_ng/smoothcolor.frag
index ede283be0c..314a387922 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec4 color;
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag b/src/quick/scenegraph/shaders_ng/smoothtexture.frag
index b06764ad95..a7ddc57535 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 texCoord;
diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag b/src/quick/scenegraph/shaders_ng/sprite.frag
index 338f5e957e..846958c71c 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.frag
+++ b/src/quick/scenegraph/shaders_ng/sprite.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec4 fTexS;
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag b/src/quick/scenegraph/shaders_ng/stencilclip.frag
index 3f6222389d..ec4d3a05b1 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.frag
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) out vec4 fragColor;
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag b/src/quick/scenegraph/shaders_ng/styledtext.frag
index 2e380dfeae..df14c09aed 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
index 62e162c851..eda1062f2d 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag b/src/quick/scenegraph/shaders_ng/textmask.frag
index ed8da4cd30..49023666ce 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.frag
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 sampleCoord;
diff --git a/src/quick/scenegraph/shaders_ng/texture.frag b/src/quick/scenegraph/shaders_ng/texture.frag
index bd22f817e0..d4be87ec29 100644
--- a/src/quick/scenegraph/shaders_ng/texture.frag
+++ b/src/quick/scenegraph/shaders_ng/texture.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 qt_TexCoord;
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag b/src/quick/scenegraph/shaders_ng/vertexcolor.frag
index ede283be0c..314a387922 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec4 color;
diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag b/src/quick/scenegraph/shaders_ng/visualization.frag
index 29f718fe5d..378afc2088 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.frag
+++ b/src/quick/scenegraph/shaders_ng/visualization.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 pos;
diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp
index a1f3fc64fd..7a6905b5de 100644
--- a/src/quick/util/qquickdeliveryagent.cpp
+++ b/src/quick/util/qquickdeliveryagent.cpp
@@ -1712,17 +1712,19 @@ void QQuickDeliveryAgentPrivate::onGrabChanged(QObject *grabber, QPointingDevice
}
if (currentEventDeliveryAgent == q && event && event->device()) {
- auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
- Q_ASSERT(epd);
switch (transition) {
case QPointingDevice::GrabPassive: {
+ auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
+ Q_ASSERT(epd);
QPointingDevicePrivate::setPassiveGrabberContext(epd, grabber, q);
qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition;
} break;
- case QPointingDevice::GrabExclusive:
+ case QPointingDevice::GrabExclusive: {
+ auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
+ Q_ASSERT(epd);
epd->exclusiveGrabberContext = q;
qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition;
- break;
+ } break;
case QPointingDevice::CancelGrabExclusive:
case QPointingDevice::UngrabExclusive:
// taken care of in QPointingDevicePrivate::setExclusiveGrabber(,,nullptr), removeExclusiveGrabber()
diff --git a/src/quickcontrols2/basic/Menu.qml b/src/quickcontrols2/basic/Menu.qml
index 475e58ccb8..bee89f94bb 100644
--- a/src/quickcontrols2/basic/Menu.qml
+++ b/src/quickcontrols2/basic/Menu.qml
@@ -54,9 +54,7 @@ T.Menu {
contentItem: ListView {
implicitHeight: contentHeight
model: control.contentModel
- interactive: Window.window
- ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
- : false
+ interactive: contentHeight + control.topPadding + control.bottomPadding > control.height
clip: true
currentIndex: control.currentIndex
diff --git a/src/quickcontrols2/fusion/Menu.qml b/src/quickcontrols2/fusion/Menu.qml
index 7808850ce4..d56860d43e 100644
--- a/src/quickcontrols2/fusion/Menu.qml
+++ b/src/quickcontrols2/fusion/Menu.qml
@@ -58,9 +58,7 @@ T.Menu {
contentItem: ListView {
implicitHeight: contentHeight
model: control.contentModel
- interactive: Window.window
- ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
- : false
+ interactive: contentHeight + control.topPadding + control.bottomPadding > control.height
clip: true
currentIndex: control.currentIndex
diff --git a/src/quickcontrols2/imagine/Menu.qml b/src/quickcontrols2/imagine/Menu.qml
index 346c649021..ec73df6afd 100644
--- a/src/quickcontrols2/imagine/Menu.qml
+++ b/src/quickcontrols2/imagine/Menu.qml
@@ -68,9 +68,7 @@ T.Menu {
contentItem: ListView {
implicitHeight: contentHeight
model: control.contentModel
- interactive: Window.window
- ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
- : false
+ interactive: contentHeight + control.topPadding + control.bottomPadding > control.height
clip: true
currentIndex: control.currentIndex
diff --git a/src/quickcontrols2/material/Menu.qml b/src/quickcontrols2/material/Menu.qml
index b7e80c92ef..df11e0ebf0 100644
--- a/src/quickcontrols2/material/Menu.qml
+++ b/src/quickcontrols2/material/Menu.qml
@@ -73,9 +73,7 @@ T.Menu {
implicitHeight: contentHeight
model: control.contentModel
- interactive: Window.window
- ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
- : false
+ interactive: contentHeight + control.topPadding + control.bottomPadding > control.height
clip: true
currentIndex: control.currentIndex
diff --git a/src/quickcontrols2/universal/Menu.qml b/src/quickcontrols2/universal/Menu.qml
index c4723f32aa..5d5a1a5650 100644
--- a/src/quickcontrols2/universal/Menu.qml
+++ b/src/quickcontrols2/universal/Menu.qml
@@ -55,9 +55,7 @@ T.Menu {
contentItem: ListView {
implicitHeight: contentHeight
model: control.contentModel
- interactive: Window.window
- ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
- : false
+ interactive: contentHeight + control.topPadding + control.bottomPadding > control.height
clip: true
currentIndex: control.currentIndex
diff --git a/src/quickshapes/shaders_ng/conicalgradient.frag b/src/quickshapes/shaders_ng/conicalgradient.frag
index 0b1e01bae2..99592e14e4 100644
--- a/src/quickshapes/shaders_ng/conicalgradient.frag
+++ b/src/quickshapes/shaders_ng/conicalgradient.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 coord;
diff --git a/src/quickshapes/shaders_ng/lineargradient.frag b/src/quickshapes/shaders_ng/lineargradient.frag
index 16894fc764..26fa540154 100644
--- a/src/quickshapes/shaders_ng/lineargradient.frag
+++ b/src/quickshapes/shaders_ng/lineargradient.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in float gradTabIndex;
diff --git a/src/quickshapes/shaders_ng/radialgradient.frag b/src/quickshapes/shaders_ng/radialgradient.frag
index 411e589295..743cc2a8cb 100644
--- a/src/quickshapes/shaders_ng/radialgradient.frag
+++ b/src/quickshapes/shaders_ng/radialgradient.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#version 440
layout(location = 0) in vec2 coord;
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index 5b859adba1..77b674a22a 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -550,7 +550,8 @@ QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavio
\value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1).
\value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1).
- If no operation is provided, \c PushTransition will be used.
+ If no operation is provided, \c Immediate will be used if the stack is
+ empty, and \c PushTransition otherwise.
\note Items that already exist in the stack are not pushed.
@@ -792,7 +793,8 @@ void QQuickStackView::pop(QQmlV4Function *args)
\value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1).
\value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1).
- If no operation is provided, \c ReplaceTransition will be used.
+ If no operation is provided, \c Immediate will be used if the stack is
+ empty, and \c ReplaceTransition otherwise.
The following example illustrates the use of push and pop transitions with replace().