Merge remote-tracking branch 'origin/5.13' into dev
Conflicts: src/qml/compiler/qv4compilercontext.cpp src/qml/qml/qqmlmetatype.cpp Change-Id: I02e0216961b92ff68a3f91a70edc33fe9e8db147
This commit is contained in:
commit
23f988fe48
|
@ -175,7 +175,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
|
|||
bool ok = false;
|
||||
maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
|
||||
if (!ok || maxCallDepth <= 0) {
|
||||
#ifdef QT_NO_DEBUG
|
||||
#if defined(QT_NO_DEBUG) && !defined(__SANITIZE_ADDRESS__)
|
||||
maxCallDepth = 1234;
|
||||
#else
|
||||
// no (tail call) optimization is done, so there'll be a lot mare stack frames active
|
||||
|
|
|
@ -242,9 +242,6 @@ ReturnedValue Lookup::getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *eng
|
|||
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
|
||||
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
|
||||
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset2)->asReturnedValue();
|
||||
Value obj = Value::fromHeapObject(o);
|
||||
Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return static_cast<Object &>(obj).get(&static_cast<String &>(str));
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, engine, object);
|
||||
|
@ -260,9 +257,6 @@ ReturnedValue Lookup::getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine
|
|||
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
|
||||
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
|
||||
return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
|
||||
Value obj = Value::fromHeapObject(o);
|
||||
Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return static_cast<Object &>(obj).get(&static_cast<String &>(str));
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, engine, object);
|
||||
|
@ -278,9 +272,6 @@ ReturnedValue Lookup::getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEng
|
|||
return o->memberData->values.data()[l->objectLookupTwoClasses.offset].asReturnedValue();
|
||||
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
|
||||
return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
|
||||
Value obj = Value::fromHeapObject(o);
|
||||
Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return static_cast<Object &>(obj).get(&static_cast<String &>(str));
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, engine, object);
|
||||
|
@ -296,9 +287,7 @@ ReturnedValue Lookup::getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine,
|
|||
return l->protoLookupTwoClasses.data->asReturnedValue();
|
||||
if (l->protoLookupTwoClasses.protoId2 == o->internalClass->protoId)
|
||||
return l->protoLookupTwoClasses.data2->asReturnedValue();
|
||||
Value obj = Value::fromHeapObject(o);
|
||||
Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return static_cast<Object &>(obj).get(&static_cast<String &>(str));
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, engine, object);
|
||||
|
|
|
@ -560,9 +560,9 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
|
|||
|
||||
QQmlContextData *callingQmlContext = scope.engine->callingQmlContext();
|
||||
if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
|
||||
const char *valueType = nullptr;
|
||||
if (v.userType() == QVariant::Invalid) valueType = "null";
|
||||
else valueType = QMetaType::typeName(v.userType());
|
||||
const char *valueType = (v.userType() == QMetaType::UnknownType)
|
||||
? "an unknown type"
|
||||
: QMetaType::typeName(v.userType());
|
||||
|
||||
const char *targetTypeName = QMetaType::typeName(property->propType());
|
||||
if (!targetTypeName)
|
||||
|
|
|
@ -76,6 +76,8 @@ public:
|
|||
const QQmlMetaTypeData *operator->() const { return data; }
|
||||
operator const QQmlMetaTypeData *() const { return data; }
|
||||
|
||||
bool isValid() const { return data != nullptr; }
|
||||
|
||||
private:
|
||||
QMutexLocker locker;
|
||||
LockedData *data = nullptr;
|
||||
|
@ -1206,6 +1208,10 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
|
|||
{
|
||||
QQmlMetaTypeDataPtr data;
|
||||
|
||||
// in case this is being called during program exit, `data` might be destructed already
|
||||
if (!data.isValid())
|
||||
return;
|
||||
|
||||
bool deletedAtLeastOneType;
|
||||
do {
|
||||
deletedAtLeastOneType = false;
|
||||
|
|
|
@ -95,9 +95,8 @@ QObject* QQmlTypeWrapper::singletonObject() const
|
|||
|
||||
QVariant QQmlTypeWrapper::toVariant() const
|
||||
{
|
||||
// Only Singleton type wrappers can be converted to a variant.
|
||||
if (!isSingleton())
|
||||
return QVariant();
|
||||
return QVariant::fromValue<QObject *>(d()->object);
|
||||
|
||||
QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine()->qmlEngine());
|
||||
const QQmlType type = d()->type();
|
||||
|
|
|
@ -70,14 +70,15 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
|
|||
if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
|
||||
return false;
|
||||
|
||||
#if QT_CONFIG(gestures)
|
||||
if (event->asPointerNativeGestureEvent())
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (event->asPointerScrollEvent())
|
||||
return false;
|
||||
|
||||
bool ret = false;
|
||||
#if QT_CONFIG(gestures)
|
||||
if (event->asPointerNativeGestureEvent() && event->point(0)->state() != QQuickEventPoint::Released)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
// If points were pressed or released within parentItem, reset stored state
|
||||
// and check eligible points again. This class of handlers is intended to
|
||||
// handle a specific number of points, so a differing number of points will
|
||||
|
@ -97,7 +98,7 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
|
|||
return true;
|
||||
}
|
||||
|
||||
const bool ret = (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
|
||||
ret = ret || (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
|
||||
if (ret) {
|
||||
const int c = candidatePoints.count();
|
||||
d->currentPoints.resize(c);
|
||||
|
|
|
@ -1135,10 +1135,10 @@ void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong times
|
|||
struct PointVelocityData {
|
||||
QVector2D velocity;
|
||||
QPointF pos;
|
||||
ulong timestamp;
|
||||
ulong timestamp = 0;
|
||||
};
|
||||
|
||||
typedef QMap<quint64, PointVelocityData*> PointDataForPointIdMap;
|
||||
typedef QMap<quint64, PointVelocityData> PointDataForPointIdMap;
|
||||
Q_GLOBAL_STATIC(PointDataForPointIdMap, g_previousPointData)
|
||||
static const int PointVelocityAgeLimit = 500; // milliseconds
|
||||
|
||||
|
@ -1149,42 +1149,36 @@ static const int PointVelocityAgeLimit = 500; // milliseconds
|
|||
*/
|
||||
QVector2D QQuickEventPoint::estimatedVelocity() const
|
||||
{
|
||||
PointVelocityData *prevPoint = g_previousPointData->value(m_pointId);
|
||||
if (!prevPoint) {
|
||||
auto prevPointIt = g_previousPointData->find(m_pointId);
|
||||
auto end = g_previousPointData->end();
|
||||
if (prevPointIt == end) {
|
||||
// cleanup events older than PointVelocityAgeLimit
|
||||
auto end = g_previousPointData->end();
|
||||
for (auto it = g_previousPointData->begin(); it != end; ) {
|
||||
PointVelocityData *data = it.value();
|
||||
if (m_timestamp - data->timestamp > PointVelocityAgeLimit) {
|
||||
if (m_timestamp - it->timestamp > PointVelocityAgeLimit)
|
||||
it = g_previousPointData->erase(it);
|
||||
delete data;
|
||||
} else {
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
// TODO optimize: stop this dynamic memory thrashing
|
||||
prevPoint = new PointVelocityData;
|
||||
prevPoint->velocity = QVector2D();
|
||||
prevPoint->timestamp = 0;
|
||||
prevPoint->pos = QPointF();
|
||||
g_previousPointData->insert(m_pointId, prevPoint);
|
||||
prevPointIt = g_previousPointData->insert(m_pointId, PointVelocityData());
|
||||
}
|
||||
const ulong timeElapsed = m_timestamp - prevPoint->timestamp;
|
||||
|
||||
auto &prevPoint = prevPointIt.value();
|
||||
const ulong timeElapsed = m_timestamp - prevPoint.timestamp;
|
||||
if (timeElapsed == 0) // in case we call estimatedVelocity() twice on the same QQuickEventPoint
|
||||
return m_velocity;
|
||||
|
||||
QVector2D newVelocity;
|
||||
if (prevPoint->timestamp != 0)
|
||||
newVelocity = QVector2D(m_scenePos - prevPoint->pos)/timeElapsed;
|
||||
if (prevPoint.timestamp != 0)
|
||||
newVelocity = QVector2D(m_scenePos - prevPoint.pos) / timeElapsed;
|
||||
|
||||
// VERY simple kalman filter: does a weighted average
|
||||
// where the older velocities get less and less significant
|
||||
static const float KalmanGain = 0.7f;
|
||||
QVector2D filteredVelocity = newVelocity * KalmanGain + m_velocity * (1.0f - KalmanGain);
|
||||
|
||||
prevPoint->velocity = filteredVelocity;
|
||||
prevPoint->pos = m_scenePos;
|
||||
prevPoint->timestamp = m_timestamp;
|
||||
prevPoint.velocity = filteredVelocity;
|
||||
prevPoint.pos = m_scenePos;
|
||||
prevPoint.timestamp = m_timestamp;
|
||||
return filteredVelocity;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import QtQml 2.0
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property QtObject target: QtObject {
|
||||
Component.onCompleted: {
|
||||
root.connections.target = root.target.Component
|
||||
}
|
||||
}
|
||||
|
||||
property Connections connections: Connections {
|
||||
ignoreUnknownSignals: true
|
||||
}
|
||||
}
|
|
@ -301,6 +301,8 @@ private slots:
|
|||
void polymorphicFunctionLookup();
|
||||
void anchorsToParentInPropertyChanges();
|
||||
|
||||
void typeWrapperToVariant();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
QStringList defaultImportPathList;
|
||||
|
@ -5087,6 +5089,19 @@ void tst_qqmllanguage::anchorsToParentInPropertyChanges()
|
|||
QTRY_COMPARE(o->property("edgeWidth").toInt(), 200);
|
||||
}
|
||||
|
||||
void tst_qqmllanguage::typeWrapperToVariant()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent component(&engine, testFileUrl("typeWrapperToVariant.qml"));
|
||||
VERIFY_ERRORS(0);
|
||||
QScopedPointer<QObject> o(component.create());
|
||||
QVERIFY(!o.isNull());
|
||||
QObject *connections = qvariant_cast<QObject *>(o->property("connections"));
|
||||
QVERIFY(connections);
|
||||
QObject *target = qvariant_cast<QObject *>(connections->property("target"));
|
||||
QVERIFY(target);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmllanguage)
|
||||
|
||||
#include "tst_qqmllanguage.moc"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
[openglContextCreatedSignal]
|
||||
opensuse-42.3
|
||||
opensuse-leap
|
||||
# QTBUG-62177
|
||||
[attachedProperty]
|
||||
osx
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[tabKey]
|
||||
opensuse-42.3
|
||||
opensuse-leap
|
|
@ -40,7 +40,9 @@ QQmlDataTest::QQmlDataTest() :
|
|||
m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0)),
|
||||
#endif
|
||||
|
||||
m_dataDirectoryUrl(QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')))
|
||||
m_dataDirectoryUrl(m_dataDirectory.startsWith(QLatin1Char(':'))
|
||||
? QUrl(QLatin1String("qrc") + m_dataDirectory)
|
||||
: QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')))
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
|
@ -54,7 +56,8 @@ void QQmlDataTest::initTestCase()
|
|||
{
|
||||
QVERIFY2(!m_dataDirectory.isEmpty(), "'data' directory not found");
|
||||
m_directory = QFileInfo(m_dataDirectory).absolutePath();
|
||||
QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory));
|
||||
if (m_dataDirectoryUrl.scheme() != QLatin1String("qrc"))
|
||||
QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory));
|
||||
}
|
||||
|
||||
QString QQmlDataTest::testFile(const QString &fileName) const
|
||||
|
|
|
@ -3,4 +3,8 @@ INCLUDEPATH += $$PWD
|
|||
HEADERS += $$PWD/util.h
|
||||
SOURCES += $$PWD/util.cpp
|
||||
|
||||
DEFINES += QT_QMLTEST_DATADIR=\\\"$${_PRO_FILE_PWD_}/data\\\"
|
||||
android|ios {
|
||||
DEFINES += QT_QMLTEST_DATADIR=\\\":/data\\\"
|
||||
} else {
|
||||
DEFINES += QT_QMLTEST_DATADIR=\\\"$${_PRO_FILE_PWD_}/data\\\"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue