From b65b6bd5a6d571ad7047d85508f85c62ca9ad8ce Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 6 Jul 2016 11:14:17 +0200 Subject: Fix QQuickDefaultClipNode::updateGeometry() There are segments top + border and for each segment 2 points -> 4. Change-Id: I6df11e557054e4b942de430bd2cad8e2f798b0db Task-number: QTBUG-51894 Reviewed-by: Robin Burchell Reviewed-by: Laszlo Agocs --- src/quick/items/qquickclipnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/items/qquickclipnode.cpp b/src/quick/items/qquickclipnode.cpp index a46f758c3b..3b5933d910 100644 --- a/src/quick/items/qquickclipnode.cpp +++ b/src/quick/items/qquickclipnode.cpp @@ -87,7 +87,7 @@ void QQuickDefaultClipNode::updateGeometry() int segments = qMin(30, qCeil(radius)); // Number of segments per corner. - g->allocate((segments + 1) * 2); + g->allocate((segments + 1) * 4); QVector2D *vertices = (QVector2D *)g->vertexData(); -- cgit v1.2.3 From ebf07c3f68415099132856b2831633c310bc3395 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 14 Apr 2015 14:55:24 +0200 Subject: Flickable: avoid infinite velocity during release after drag It sometimes happens on touchscreens that mouse events occur too close together. We cannot calculate velocity based on zero elapsed time, so just ignore the event. Task-number: QTBUG-45527 Change-Id: I120e73cfa60e2fcc594cb1f3b69f530e746abddd Reviewed-by: Timur Pocheptsov --- src/quick/items/qquickflickable.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index b0980cd2c1..760eeed452 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1224,13 +1224,17 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) return; qint64 currentTimestamp = computeCurrentTime(event); - qreal elapsed = qreal(currentTimestamp - (lastPos.isNull() ? lastPressTime : lastPosTime)) / 1000.; QVector2D deltas = QVector2D(event->localPos() - pressPos); bool overThreshold = false; QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event); // TODO guarantee that events always have velocity so that it never needs to be computed here - if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) + if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) { + qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime); + if (currentTimestamp == lastTimestamp) + return; // events are too close together: velocity would be infinite + qreal elapsed = qreal(currentTimestamp - lastTimestamp) / 1000.; velocity = QVector2D(event->localPos() - (lastPos.isNull() ? pressPos : lastPos)) / elapsed; + } if (q->yflick()) overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, event); -- cgit v1.2.3 From 837c5d6284eeec8adb9b2caa3a0ce82b0da019a1 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Fri, 5 Aug 2016 13:18:44 +0200 Subject: Fix crash when cache property can not be found For some reason if a cache property is not found this cause an application crash instead of just reporting an error. Now instead of a crash we get this kind of error visible: qrc:///the_file.qml line 64 column 30: Cannot assign object to property Change-Id: Ic420713df30603f1d164da439cba30a18af8f2bc Reviewed-by: Simon Hausmann --- src/qml/compiler/qqmltypecompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 7e4ee344ff..82332dfc35 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1414,7 +1414,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI continue; QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType); - const QMetaObject *mo = pc->firstCppMetaObject(); + const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0; while (mo) { if (mo == &QQmlComponent::staticMetaObject) break; -- cgit v1.2.3 From ff645deb25c18eeae3d248a6a60bc2954129ee28 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 2 Aug 2016 11:52:58 +0200 Subject: Remove artifacts in font rendering The distancefield cache did not clear the textures before using them. Hence, random values could leak through in the edges of the distancefields, leading to random pixels at the edges of the rendered glyphs. This issue was rarely visible before, because of the way the glyphs were stacked on the textures. That stacking was changed as a result of 7190aa26f65ab97b4f54c156a107ed7748a11df5, which made the issue happen more often, so it was detected by lancelot. Change-Id: Ibe7a20dd7ba557ab92966e714c25a100e218ed24 Reviewed-by: Yoann Lopes --- src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 728d8b6541..31275b304d 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -253,7 +253,8 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int const GLenum format = GL_ALPHA; #endif - m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, 0); + QByteArray zeroBuf(width * height, 0); + m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, zeroBuf.constData()); texInfo->size = QSize(width, height); -- cgit v1.2.3 From 68bfc9332cd65c1eb88d1ec87164447b0db43237 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 25 Jul 2016 16:07:16 +0200 Subject: Fix crash with Component.onDestruction A call to a handler of Component.onDestruction may end up causing WeakValues such as QQmlData::jsWrapper to be set again, even though they've been set to undefined in an earlier iteration of the loop that walks through the weak references. That in turn may result in invalid object references to objects that are scheduled for destruction by the collector. So after calling all destroy handlers for QObjects, reset all of the weak values again. Task-number: QTBUG-54939 Change-Id: I00ebabb76274e296fb1bd90d8d3e21dbbb920b57 Reviewed-by: Lars Knoll --- src/qml/memory/qv4mm.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 7ab6d15041..4592dd5c9b 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -428,7 +428,7 @@ void MemoryManager::sweep(bool lastSweep) Managed *m = (*it).as(); if (m->markBit()) continue; - // we need to call detroyObject on qobjectwrappers now, so that they can emit the destroyed + // we need to call destroyObject on qobjectwrappers now, so that they can emit the destroyed // signal before we start sweeping the heap if (QObjectWrapper *qobjectWrapper = (*it).as()) qobjectWrapper->destroyObject(lastSweep); @@ -436,6 +436,17 @@ void MemoryManager::sweep(bool lastSweep) (*it) = Primitive::undefinedValue(); } + // onDestruction handlers may have accessed other QObject wrappers and reset their value, so ensure + // that they are all set to undefined. + for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { + if (!(*it).isManaged()) + continue; + Managed *m = (*it).as(); + if (m->markBit()) + continue; + (*it) = Primitive::undefinedValue(); + } + // Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed const int pendingCount = m_pendingFreedObjectWrapperValue.count(); if (pendingCount) { -- cgit v1.2.3 From 13a427475d3638de843f33145378587037841a86 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 5 Aug 2016 12:33:03 +0200 Subject: Clarify doc on modification of the global object in JS imported by QML Currently, reading the documentation for modification of the global object in JavaScript can be confusing. http://doc.qt.io/qt-5/qtqml-javascript-hostenvironment.html says: JavaScript code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. ... Any attempt to modify the global object - either implicitly or explicitly - will cause an exception. If uncaught, this will result in a warning being printed, that includes the file and line number of the offending code. http://doc.qt.io/qt-5/qjsengine.html#globalObject says: Returns this engine's Global Object. By default, the Global Object contains the built-in objects that are part of ECMA-262, such as Math, Date and String. Additionally, you can set properties of the Global Object to make your own extensions available to all script code. Non-local variables in script code will be created as properties of the Global Object, as well as local variables in global code. If QQmlEngine "is-a" QJSEngine, and QJSEngine can have its global object modified, it might seem reasonable to expect that imported JavaScript code should be able to modify the global object. This patch aims to be more explicit about the restrictions and give examples of how libraries should expose their APIs correctly for use by QML code. Change-Id: I11beb894a88d52038be90ffe6baa9337943810db Reviewed-by: Simon Hausmann --- src/qml/doc/src/javascript/hostenvironment.qdoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index de8b967d72..1e33f2f641 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -80,7 +80,10 @@ Note that QML makes the following modifications to native objects: QML implements the following restrictions for JavaScript code: \list -\li JavaScript code cannot modify the global object. +\li JavaScript code written in a \c .qml file cannot modify the global object. + JavaScript code in a .js file can modify the global object, + and those modifications will be visible to the .qml file when + \l {Importing a JavaScript Resource from a QML Document}{imported}. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. -- cgit v1.2.3 From 31ca52cee47f189ee1c80245f7b114c29ac7c675 Mon Sep 17 00:00:00 2001 From: Eike Hein Date: Thu, 4 Jun 2015 21:25:32 +0200 Subject: Don't accept left clicks when text format is plain. Text elements may contain rich text with embedded links, and need to accept left clicks to open them. However, setting the textFormat to PlainText can disable mouse handling entirely, as it is not required. Accepting left clicks if there can be nothing to interact with is unexpected and surprising, and can cause bugs in code that performs child event filtering and doesn't expect Text elements to produce child events. Change-Id: Ibd5b9cf8d06fd30ea26f78b5393cc43e94646e73 Reviewed-by: Marco Martin Reviewed-by: Kai Uwe Broulik Reviewed-by: Robin Burchell Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/quick/items/qquicktext.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index e67e2cee9c..ea2d2f3133 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2013,6 +2013,7 @@ void QQuickText::setTextFormat(TextFormat format) } d->updateLayout(); setAcceptHoverEvents(d->richText || d->styledText); + setAcceptedMouseButtons(d->richText || d->styledText ? Qt::LeftButton : Qt::NoButton); emit textFormatChanged(d->format); } -- cgit v1.2.3 From 35597f301480ffc59f598be4de2c2074543725be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 2 Jun 2016 12:08:29 +0200 Subject: Fix char conversions in QML This is a partial revert of 90b06e2773842, as it had unwanted side effects. The original intention was to make assignment from char to string possible, or more specifically, we wanted a solution where a QChar could be assigned to a QString, as a character and not a string representation of its value. While this behavior is desirable for QChar, we most likely want the opposite for the regular character types. Task-number: QTBUG-49232 Change-Id: I82d5f72b900fe984c4db1478fd52a9eb69ad2ee6 Reviewed-by: Michael Brasser Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 13 +++++++++---- src/qml/qml/qqmlproperty.cpp | 25 ++----------------------- 2 files changed, 11 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 5dc3e6151f..557b678ef8 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1143,8 +1143,13 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return value.integerValue(); if (value.isNumber()) return value.asDouble(); - if (value.isString()) - return value.stringValue()->toQString(); + if (value.isString()) { + const QString &str = value.toQString(); + // QChars are stored as a strings + if (typeHint == QVariant::Char && str.size() == 1) + return str.at(0); + return str; + } if (const QV4::QQmlLocaleData *ld = value.as()) return ld->d()->locale; if (const QV4::DateObject *d = value.as()) @@ -1284,9 +1289,9 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::UShort: return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::Char: - return newString(QChar::fromLatin1(*reinterpret_cast(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::UChar: - return newString(QChar::fromLatin1(*reinterpret_cast(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::QChar: return newString(*reinterpret_cast(ptr))->asReturnedValue(); case QMetaType::QDateTime: diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 1b78ada698..1eaff6b600 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1327,29 +1327,8 @@ bool QQmlPropertyPrivate::write(QObject *object, bool ok = false; QVariant v; - if (variantType == QVariant::String) { - const QString &str = value.toString(); - const bool targetIsChar = (propertyType == qMetaTypeId() - || propertyType == qMetaTypeId() - || propertyType == qMetaTypeId()); - // If the string contains only one character and the target is a char, try converting it. - if (targetIsChar) { - if (str.size() != 1) - return false; // We can only convert if the string contains exactly one character. - - const QChar &qChar = str.at(0); - if (propertyType == qMetaTypeId()) { - v = qChar; - ok = true; - } else if (propertyType == qMetaTypeId() || propertyType == qMetaTypeId()) { - const char c = qChar.toLatin1(); - v = c; - ok = (qChar == c); - } - } else { - v = QQmlStringConverters::variantFromString(str, propertyType, &ok); - } - } + if (variantType == QVariant::String) + v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok); if (!ok) { v = value; -- cgit v1.2.3 From 4493524ec24afb946eba3942f48d9fc1ff3192c1 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 9 Aug 2016 10:49:22 +0200 Subject: V4: Align stack on 16 byte boundaries in the YarrJIT This is the required alignment for Aarch64, and a number of other ABIs prefer this size too when calling into system libraries. Change-Id: Ie38cabb77cf83543b915553e69c5c5728a67503b Reviewed-by: Simon Hausmann --- src/3rdparty/masm/yarr/YarrJIT.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp index 5664c585b9..d8211ec4b2 100644 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp @@ -338,17 +338,31 @@ class YarrGenerator : private MacroAssembler { jump(Address(stackPointerRegister, frameLocation * sizeof(void*))); } + unsigned alignCallFrameSizeInBytes(unsigned callFrameSize) + { + callFrameSize *= sizeof(void*); + if (callFrameSize / sizeof(void*) != m_pattern.m_body->m_callFrameSize) + CRASH(); + // Originally, the code was: +// callFrameSize = (callFrameSize + 0x3f) & ~0x3f; + // However, 64 bytes is a bit surprising. The biggest "alignment" requirement is on Aarch64, where: + // "SP mod 16 = 0. The stack must be quad-word aligned." (IHI0055B_aapcs64.pdf) + callFrameSize = (callFrameSize + 0xf) & ~0xf; + if (!callFrameSize) + CRASH(); + return callFrameSize; + } void initCallFrame() { unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; if (callFrameSize) - subPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); + subPtr(Imm32(alignCallFrameSizeInBytes(callFrameSize)), stackPointerRegister); } void removeCallFrame() { unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; if (callFrameSize) - addPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); + addPtr(Imm32(alignCallFrameSizeInBytes(callFrameSize)), stackPointerRegister); } // Used to record subpatters, should only be called if compileMode is IncludeSubpatterns. @@ -2565,6 +2579,10 @@ class YarrGenerator : private MacroAssembler { if (compileMode == IncludeSubpatterns) loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif +#elif CPU(ARM64) + // The ABI doesn't guarantee the upper bits are zero on unsigned arguments, so clear them ourselves. + zeroExtend32ToPtr(index, index); + zeroExtend32ToPtr(length, length); #elif CPU(ARM) push(ARMRegisters::r4); push(ARMRegisters::r5); -- cgit v1.2.3 From 580f2872f09cf7ad83ec9ae5dca686683a3cac80 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 9 Aug 2016 15:14:55 +0200 Subject: TextInput: fix horizontal alignment when implicit resizing is disabled By default, TextInput updates its implicit width to match the content width. This implies that when TextInput does not have an explicit width set, there is no need to handle horizontal alignment. TextField wants to override the default implicit width, so it disables the "implicit resizing" feature of TextInput. In this scenario, the implicit width does not match the content width. Therefore the text layouting code should also treat the item as if it had an explicit width set to achieve the correct horizontal alignment. Task-number: QTBUG-55138 Change-Id: I8c04971a6aff44c6f1734df50153a9788849e98a Reviewed-by: Mitch Curtis --- src/quick/items/qquicktextinput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 03c6b892c4..63e8505ffa 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2916,7 +2916,7 @@ void QQuickTextInputPrivate::updateLayout() if (inLayout) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect. } - qreal lineWidth = q->widthValid() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX; + qreal lineWidth = q->widthValid() || !isImplicitResizeEnabled() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX; qreal height = 0; qreal width = 0; do { -- cgit v1.2.3 From fdd8bf7dbf91b8e8ce84c990a03767c0b8ba064a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 8 Jun 2016 10:02:29 +0200 Subject: QQmlObjectCreator: initialize _bindingTarget Coverity (CID 163180) noticed _bindingTarget wasn't initialized. Change-Id: Ia727d00a161e514c437a72084b6ef01a7ebf4abc Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlobjectcreator.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0c13a7a017..c06e1827ac 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -114,6 +114,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) context = 0; _qobject = 0; _scopeObject = 0; + _bindingTarget = 0; _valueTypeProperty = 0; _compiledObject = 0; _compiledObjectIndex = -1; -- cgit v1.2.3 From b054a700576f61d9fbd196987f42fdea7a806db1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 8 Jun 2016 10:03:37 +0200 Subject: QQmlObjectCreator: prefer initializer syntax over assignment Greater uniformity; also opens the door to potential const-ing, should this ever be worht considering. Change-Id: I91b44472cb7d84f85b3033f14a763beeea837459 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlobjectcreator.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index c06e1827ac..8fa1f48d18 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -68,12 +68,12 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(new QQmlObjectCreatorSharedState) + , topLevelCreator(true) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); - sharedState = new QQmlObjectCreatorSharedState; - topLevelCreator = true; sharedState->componentAttached = 0; sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount); sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount); @@ -93,12 +93,11 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(inheritedSharedState) + , topLevelCreator(false) , activeVMEDataForRootContext(0) { init(parentContext); - - sharedState = inheritedSharedState; - topLevelCreator = false; } void QQmlObjectCreator::init(QQmlContextData *providedParentContext) -- cgit v1.2.3 From b4327851a4895b28b2c60ca51e77eca3ee0a1b4e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Aug 2016 08:02:37 +0200 Subject: Move the moth stack slot allocator into qmldevtools This way it's accessible to the QML compiler. Change-Id: I3918a796c698fc75e134b29a61eed2ec028bc851 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4isel_moth.cpp | 163 +------------------------------------- src/qml/compiler/qv4ssa_p.h | 163 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 162 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index afb36c5f14..f87cbe3f1b 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -143,167 +143,6 @@ inline bool isBoolType(IR::Expr *e) return (e->type == IR::BoolType); } -/* - * stack slot allocation: - * - * foreach bb do - * foreach stmt do - * if the current statement is not a phi-node: - * purge ranges that end before the current statement - * check for life ranges to activate, and if they don't have a stackslot associated then allocate one - * renumber temps to stack - * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated - * if it's a jump: - * foreach phi node in the successor: - * allocate slots for each temp (both sources and targets) if they don't have one allocated already - * insert moves before the jump - */ -class AllocateStackSlots: protected ConvertTemps -{ - IR::LifeTimeIntervals::Ptr _intervals; - QVector _unhandled; - QVector _live; - QBitArray _slotIsInUse; - IR::Function *_function; - - int defPosition(IR::Stmt *s) const - { - return usePosition(s) + 1; - } - - int usePosition(IR::Stmt *s) const - { - return _intervals->positionForStatement(s); - } - -public: - AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) - : _intervals(intervals) - , _slotIsInUse(intervals->size(), false) - , _function(0) - { - _live.reserve(8); - _unhandled = _intervals->intervals(); - } - - void forFunction(IR::Function *function) - { - IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); - _function = function; - toStackSlots(function); - } - -protected: - virtual int allocateFreeSlot() - { - for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { - if (!_slotIsInUse[i]) { - if (_nextUnusedStackSlot <= i) { - Q_ASSERT(_nextUnusedStackSlot == i); - _nextUnusedStackSlot = i + 1; - } - _slotIsInUse[i] = true; - return i; - } - } - - Q_UNREACHABLE(); - return -1; - } - - virtual void process(IR::Stmt *s) - { -// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); - - if (IR::Phi *phi = s->asPhi()) { - visitPhi(phi); - } else { - // purge ranges no longer alive: - for (int i = 0; i < _live.size(); ) { - const IR::LifeTimeInterval *lti = _live.at(i); - if (lti->end() < usePosition(s)) { -// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; - _live.remove(i); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); - _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; - continue; - } else { - ++i; - } - } - - // active new ranges: - while (!_unhandled.isEmpty()) { - IR::LifeTimeInterval *lti = _unhandled.last(); - if (lti->start() > defPosition(s)) - break; // we're done - Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); - _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); -// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; - _live.append(lti); - _unhandled.removeLast(); - } - - s->accept(this); - } - - if (IR::Jump *jump = s->asJump()) { - IR::MoveMapping moves; - foreach (IR::Stmt *succStmt, jump->target->statements()) { - if (IR::Phi *phi = succStmt->asPhi()) { - forceActivation(*phi->targetTemp); - for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) { - IR::Expr *e = phi->d->incoming[i]; - if (IR::Temp *t = e->asTemp()) { - forceActivation(*t); - } - if (jump->target->in[i] == _currentBasicBlock) - moves.add(phi->d->incoming[i], phi->targetTemp); - } - } else { - break; - } - } - moves.order(); - QList newMoves = moves.insertMoves(_currentBasicBlock, _function, true); - foreach (IR::Move *move, newMoves) - move->accept(this); - } - } - - void forceActivation(const IR::Temp &t) - { - if (_stackSlotForTemp.contains(t.index)) - return; - - int i = _unhandled.size() - 1; - for (; i >= 0; --i) { - IR::LifeTimeInterval *lti = _unhandled[i]; - if (lti->temp() == t) { - _live.append(lti); - _unhandled.remove(i); - break; - } - } - Q_ASSERT(i >= 0); // check that we always found the entry - - _stackSlotForTemp[t.index] = allocateFreeSlot(); -// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; - } - - virtual void visitPhi(IR::Phi *phi) - { - Q_UNUSED(phi); -#if !defined(QT_NO_DEBUG) - Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); - foreach (IR::Expr *e, phi->d->incoming) { - if (IR::Temp *t = e->asTemp()) - Q_ASSERT(_stackSlotForTemp.contains(t->index)); - } -#endif // defined(QT_NO_DEBUG) - } -}; } // anonymous namespace InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) @@ -353,7 +192,7 @@ void InstructionSelection::run(int functionIndex) qEnvironmentVariableIsEmpty("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION"); if (doStackSlotAllocation) { - AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); + IR::AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); } else { opt.convertOutOfSSA(); ConvertTemps().toStackSlots(_function); diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index d06774e803..c5690a8581 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -46,6 +46,7 @@ // #include "qv4jsir_p.h" +#include "qv4isel_util_p.h" #include QT_BEGIN_NAMESPACE @@ -271,6 +272,168 @@ private: QList &swaps) const; }; +/* + * stack slot allocation: + * + * foreach bb do + * foreach stmt do + * if the current statement is not a phi-node: + * purge ranges that end before the current statement + * check for life ranges to activate, and if they don't have a stackslot associated then allocate one + * renumber temps to stack + * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated + * if it's a jump: + * foreach phi node in the successor: + * allocate slots for each temp (both sources and targets) if they don't have one allocated already + * insert moves before the jump + */ +class AllocateStackSlots: protected ConvertTemps +{ + IR::LifeTimeIntervals::Ptr _intervals; + QVector _unhandled; + QVector _live; + QBitArray _slotIsInUse; + IR::Function *_function; + + int defPosition(IR::Stmt *s) const + { + return usePosition(s) + 1; + } + + int usePosition(IR::Stmt *s) const + { + return _intervals->positionForStatement(s); + } + +public: + AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) + : _intervals(intervals) + , _slotIsInUse(intervals->size(), false) + , _function(0) + { + _live.reserve(8); + _unhandled = _intervals->intervals(); + } + + void forFunction(IR::Function *function) + { + IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); + _function = function; + toStackSlots(function); + } + +protected: + virtual int allocateFreeSlot() + { + for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { + if (!_slotIsInUse[i]) { + if (_nextUnusedStackSlot <= i) { + Q_ASSERT(_nextUnusedStackSlot == i); + _nextUnusedStackSlot = i + 1; + } + _slotIsInUse[i] = true; + return i; + } + } + + Q_UNREACHABLE(); + return -1; + } + + virtual void process(IR::Stmt *s) + { +// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); + + if (IR::Phi *phi = s->asPhi()) { + visitPhi(phi); + } else { + // purge ranges no longer alive: + for (int i = 0; i < _live.size(); ) { + const IR::LifeTimeInterval *lti = _live.at(i); + if (lti->end() < usePosition(s)) { +// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; + _live.remove(i); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); + _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; + continue; + } else { + ++i; + } + } + + // active new ranges: + while (!_unhandled.isEmpty()) { + IR::LifeTimeInterval *lti = _unhandled.last(); + if (lti->start() > defPosition(s)) + break; // we're done + Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); + _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); +// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; + _live.append(lti); + _unhandled.removeLast(); + } + + s->accept(this); + } + + if (IR::Jump *jump = s->asJump()) { + IR::MoveMapping moves; + foreach (IR::Stmt *succStmt, jump->target->statements()) { + if (IR::Phi *phi = succStmt->asPhi()) { + forceActivation(*phi->targetTemp); + for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) { + IR::Expr *e = phi->d->incoming[i]; + if (IR::Temp *t = e->asTemp()) { + forceActivation(*t); + } + if (jump->target->in[i] == _currentBasicBlock) + moves.add(phi->d->incoming[i], phi->targetTemp); + } + } else { + break; + } + } + moves.order(); + QList newMoves = moves.insertMoves(_currentBasicBlock, _function, true); + foreach (IR::Move *move, newMoves) + move->accept(this); + } + } + + void forceActivation(const IR::Temp &t) + { + if (_stackSlotForTemp.contains(t.index)) + return; + + int i = _unhandled.size() - 1; + for (; i >= 0; --i) { + IR::LifeTimeInterval *lti = _unhandled[i]; + if (lti->temp() == t) { + _live.append(lti); + _unhandled.remove(i); + break; + } + } + Q_ASSERT(i >= 0); // check that we always found the entry + + _stackSlotForTemp[t.index] = allocateFreeSlot(); +// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; + } + + virtual void visitPhi(IR::Phi *phi) + { + Q_UNUSED(phi); +#if !defined(QT_NO_DEBUG) + Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); + foreach (IR::Expr *e, phi->d->incoming) { + if (IR::Temp *t = e->asTemp()) + Q_ASSERT(_stackSlotForTemp.contains(t->index)); + } +#endif // defined(QT_NO_DEBUG) + } +}; + } // IR namespace } // QV4 namespace -- cgit v1.2.3 From 273e5b0bdc1239df77e2e5694fdd5ad068595be3 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 24 May 2016 12:21:39 +0300 Subject: PathView: fix item creation First call of QQuickPathView::refill() did not use currentIndex for item prepending and there was situation when items were not created, e.g.: PathView with current item in center and currentIndex was set so that item with index 0 was after current item and before path end. The result of this situation: items from path begin to current item were not created. The reason was that idx always equaled (modelCount-1) for item prepending. Now first filling uses currentIndex to calculate valid idx. Task-number: QTBUG-53464 Change-Id: I7e343b0712c9c5c5cd56b1d8e020cf8c0f6e6301 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 7e1fa95692..1dbdd10303 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1854,6 +1854,14 @@ void QQuickPathView::updatePolish() refill(); } +static inline int currentIndexRemainder(int currentIndex, int modelCount) Q_DECL_NOTHROW +{ + if (currentIndex < 0) + return modelCount + currentIndex % modelCount; + else + return currentIndex % modelCount; +} + void QQuickPathView::componentComplete() { Q_D(QQuickPathView); @@ -1865,7 +1873,7 @@ void QQuickPathView::componentComplete() if (d->model) { d->modelCount = d->model->count(); if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex - d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount); + d->offset = qmlMod(d->modelCount - currentIndexRemainder(d->currentIndex, d->modelCount), d->modelCount); } d->createHighlight(); @@ -1939,7 +1947,8 @@ void QQuickPathView::refill() qreal endPos; int startIdx = 0; qreal startPos = 0.0; - if (d->items.count()) { + const bool wasEmpty = d->items.isEmpty(); + if (!wasEmpty) { //Find the beginning and end, items may not be in sorted order endPos = -1.0; startPos = 2.0; @@ -1998,7 +2007,8 @@ void QQuickPathView::refill() } //Prepend - idx = startIdx - 1; + idx = (wasEmpty ? d->calcCurrentIndex() : startIdx) - 1; + if (idx < 0) idx = d->modelCount - 1; nextPos = d->positionOfIndex(idx); -- cgit v1.2.3 From 6f15de1d2da9c83d7fca1d5c8243c0d69a1390ee Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 26 May 2016 14:45:31 +0300 Subject: PathView: fix infinite construction/destruction loop ... when all (or almost all) items are in the cache. When all items are in cache, check lower bound is equal to upper_bound. In rare cases, especially when almost all items are in cache, the inserting code was used (not only appending and prepending). In this code there was not bound check before creation of item and there was such situation: 1. Create item by inserting code (without bound check) 2. At the next call of refill() remove this item by life cycle because this item does not meet the conditions. And go to step 1. In other words at the first call we create some item, at the second remove this item. And again. So we had infinite construction/destruction loop. To break it we should check position of new item before creation in inserting code too (like we do in appending and prepending code). Task-number: QTBUG-37815 Change-Id: I015cdeb67ca5fcd06c34b3145b49cbd3e38d4078 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 44 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 1dbdd10303..f858b18c84 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -289,6 +289,8 @@ qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const // account the circular space. bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower, qreal upper) const { + if (lower == upper) + return true; if (lower > upper) { if (position > upper && position > lower) position -= mappedRange; @@ -2047,27 +2049,33 @@ void QQuickPathView::refill() idx = startIdx; QQuickItem *lastItem = d->items[0]; while (idx != endIdx) { - //This gets the reference from the delegate model, and will not re-create - QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); - if (!item) { - waiting = true; - break; - } - if (!d->items.contains(item)) { //We found a hole - nextPos = d->positionOfIndex(idx); - qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count(); - if (d->currentIndex == idx) { - currentVisible = true; - d->currentItemOffset = nextPos; + nextPos = d->positionOfIndex(idx); + if (d->isInBound(nextPos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) { + //This gets the reference from the delegate model, and will not re-create + QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); + if (!item) { + waiting = true; + break; } - int lastListIdx = d->items.indexOf(lastItem); - d->items.insert(lastListIdx + 1, item); - d->updateItem(item, nextPos); - } else { - d->releaseItem(item); + + if (!d->items.contains(item)) { //We found a hole + qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos + << (d->currentIndex == idx ? "current" : "") + << "items count was" << d->items.count(); + if (d->currentIndex == idx) { + currentVisible = true; + d->currentItemOffset = nextPos; + } + int lastListIdx = d->items.indexOf(lastItem); + d->items.insert(lastListIdx + 1, item); + d->updateItem(item, nextPos); + } else { + d->releaseItem(item); + } + + lastItem = item; } - lastItem = item; ++idx; if (idx >= d->modelCount) idx = 0; -- cgit v1.2.3 From c0f3c8ae5cee3ecda1ac8829336aa95cbe4d330e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 14 Aug 2016 12:20:45 +0200 Subject: Doc: mention when Flickable.AutoFlickIfNeeded was added Change-Id: Icf72c05c9573715771353bd03735f64eadd808f2 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 03b2a8128c..870a0268e1 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -886,7 +886,7 @@ QQuickFlickableVisibleArea *QQuickFlickable::visibleArea() \li Flickable.AutoFlickIfNeeded - allows flicking vertically if the \e contentHeight is greater than the \e height of the Flickable. Allows flicking horizontally if the \e contentWidth is greater than - to the \e width of the Flickable. + to the \e width of the Flickable. (since \c{QtQuick 2.7}) \li Flickable.HorizontalFlick - allows flicking horizontally. \li Flickable.VerticalFlick - allows flicking vertically. \li Flickable.HorizontalAndVerticalFlick - allows flicking in both directions. -- cgit v1.2.3 From 2e277da4d17cbb4da04d34b260ee157aedf60f3f Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 12 Aug 2016 10:57:39 +0200 Subject: Doc: Change instances of 'OS X' to 'macOS' As of version 10.12 (Sierra), the name of Apple's desktop operating system will be macOS. Change all occurrences where the Mac platform is discussed to use the macro \macos (defined in the documentation configuration in qtbase). Change-Id: Iea114ac73c01d74401bcd77373b41a825d2636c9 Reviewed-by: Leena Miettinen Reviewed-by: Jake Petroules --- src/imports/settings/qqmlsettings.cpp | 2 +- src/qml/doc/src/cppintegration/extending-tutorial.qdoc | 2 +- src/qml/qml/qqmlengine.cpp | 2 +- src/qml/qml/qqmlimport.cpp | 2 +- src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc | 2 +- src/quick/items/qquickevents.cpp | 2 +- src/quick/items/qquickpincharea.cpp | 2 +- src/quick/items/qquicktextinput.cpp | 2 +- src/quick/util/qquickshortcut.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp index 954161b60b..8db998fefb 100644 --- a/src/imports/settings/qqmlsettings.cpp +++ b/src/imports/settings/qqmlsettings.cpp @@ -208,7 +208,7 @@ QT_BEGIN_NAMESPACE instance, even if they are referring to the same setting in the same category. The information is stored in the system registry on Windows, and in XML - preferences files on OS X. On other Unix systems, in the absence of a + preferences files on \macos. On other Unix systems, in the absence of a standard, INI text files are used. See \l QSettings documentation for more details. diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index c0cfc3e1aa..58cc650e01 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -389,7 +389,7 @@ directory. When building this example on Windows or Linux, the \c Charts directory will be located at the same level as the application that uses our new import module. This way, the QML engine will find our module as the default search path for QML -imports includes the directory of the application executable. On OS X, the +imports includes the directory of the application executable. On \macos, the plugin binary is copied to \c Contents/PlugIns in the the application bundle; this path is set in \l {tutorials/extending-qml/chapter6-plugins/app.pro} {chapter6-plugins/app.pro}: diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9a06f6b055..8f22533472 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -398,7 +398,7 @@ The following functions are also on the Qt object. \li \c "blackberry" - BlackBerry OS \li \c "ios" - iOS \li \c "linux" - Linux - \li \c "osx" - OS X + \li \c "osx" - \macos \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows \li \c "wince" - Windows CE diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index c4e0c7b778..dfdf2edbe0 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1658,7 +1658,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, \header \li Platform \li Valid suffixes \row \li Windows \li \c .dll \row \li Unix/Linux \li \c .so - \row \li OS X \li \c .dylib, \c .bundle, \c .so + \row \li \macos \li \c .dylib, \c .bundle, \c .so \endtable Version number on unix are ignored. diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index caedd72dc5..e5cd7e2424 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -263,7 +263,7 @@ animations, process events, etc. \endlist The threaded renderer is currently used by default on Windows with -opengl32.dll, Linux with non-Mesa based drivers, OS X, mobile +opengl32.dll, Linux with non-Mesa based drivers, \macos, mobile platforms, and Embedded Linux with EGLFS but this is subject to change. It is possible to force use of the threaded renderer by setting \c {QSG_RENDER_LOOP=threaded} in the environment. diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 88deefbd9a..23a99ba616 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -323,7 +323,7 @@ Item { \qmlproperty point QtQuick::WheelEvent::pixelDelta This property holds the delta in screen pixels and is available in platforms that - have high-resolution trackpads, such as OS X. + have high-resolution trackpads, such as \macos. The x and y cordinate of this property holds the delta in horizontal and vertical orientation. The value should be used directly to scroll content on screen. diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index f419d570f3..70b3ca6450 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -239,7 +239,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() \since 5.5 This signal is emitted when the pinch area detects the smart zoom gesture. - This gesture occurs only on certain operating systems such as OS X. + This gesture occurs only on certain operating systems such as \macos. The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture, including the location where the gesture occurred. \c pinch.scale diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index ffc94dfd46..f3b217dd7f 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -78,7 +78,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) and setting \l echoMode to an appropriate value enables TextInput to be used for a password input field. - On OS X, the Up/Down key bindings for Home/End are explicitly disabled. + On \macos, the Up/Down key bindings for Home/End are explicitly disabled. If you want such bindings (on any platform), you will need to construct them in QML. \sa TextEdit, Text diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index e6f66f7bf1..d47f2282b7 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -138,7 +138,7 @@ void QQuickShortcut::setSequence(const QVariant &sequence) \since 5.6 This property provides the shortcut's key sequence as a platform specific - string. This means that it will be shown translated, and on OS X it will + string. This means that it will be shown translated, and on \macos it will resemble a key sequence from the menu bar. It is best to display this text to the user (for example, on a tooltip). -- cgit v1.2.3 From 8b8492d3ffdcdba9e9decb6d9ae8b7939be6c7f2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 11 Aug 2016 15:37:21 +0200 Subject: Fix throwing an exception inside a finally block with a return in catch When exiting a catch block with a return statement, we'll unwind the exception handling manually and emit finally statements right before jumping to the exit block. If we throw an exception in the final block, we'll end up using the exception handler of the catch block that contains the return statement, which means we'll end up popping the exception scope one too many times, once through ScopeAndFinally::CatchScope in unwindException() and then when executing the exception handler block. The latter we should not be executing, instead we should jump straight to the exit block. Therefore any statements emitted as part of the manual exception unwinding (finally block here) need to be part of a new basic block with no exception handler. This bug became visible in debug builds where the Scope destructor compares the scope mark against the engine stack top to ensure correct cleanup order (which was wrong). However that in turn was hidden in debug builds again due to an accidental = instead of == in a Q_ASSERT. With the Q_ASSERT fixed this use-case is covered by ch12/12.14/S12.14_A13_T3 Change-Id: Id74a1b2bb3e063871b89cc05353b601dd60df08e Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 7 +++++++ src/qml/jsruntime/qv4runtime.cpp | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 6bf931c882..d29b11ac84 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2506,6 +2506,13 @@ bool Codegen::visit(ReturnStatement *ast) Result expr = expression(ast->expression); move(_block->TEMP(_returnAddress), *expr); } + + // Since we're leaving, don't let any finally statements we emit as part of the unwinding + // jump to exception handlers at run-time if they throw. + IR::BasicBlock *unwindBlock = _function->newBasicBlock(/*no exception handler*/Q_NULLPTR); + _block->JUMP(unwindBlock); + _block = unwindBlock; + unwindException(0); _block->JUMP(_exitBlock); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index d8ae7d4e92..0a05c50432 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1204,19 +1204,19 @@ ReturnedValue Runtime::unwindException(ExecutionEngine *engine) void Runtime::pushWithScope(const Value &o, ExecutionEngine *engine) { engine->pushContext(engine->currentContext->newWithContext(o.toObject(engine))); - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); } void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex) { ExecutionContext *c = engine->currentContext; engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0))); - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); } void Runtime::popScope(ExecutionEngine *engine) { - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); engine->popContext(); engine->jsStackTop -= 2; } -- cgit v1.2.3 From 12c7f225e6072264964bd3a0cbec834c5382031e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 16 Aug 2016 17:56:46 +0200 Subject: QV4Object: fix GCC 6.1 tautologial compare warning GCC warned: qtdeclarative/src/imports/localstorage/plugin.cpp:152:126: error: self-comparison always evaluates to true [-Werror=tautological-compare] Fix by comparing the types for equality instead of the addresses of their static_vtbls. Task-number: QTBUG-53373 Change-Id: Idd1598610ad6381c03c3a46abe56a332726bd6a0 Reviewed-by: Thiago Macieira Reviewed-by: Shawn Rutledge --- src/qml/jsruntime/qv4object_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 5c660f7e3f..4e39ccaf99 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -51,6 +51,8 @@ #include "qv4scopedvalue_p.h" #include "qv4value_p.h" +#include + QT_BEGIN_NAMESPACE @@ -125,7 +127,7 @@ struct ObjectVTable #define DEFINE_OBJECT_VTABLE(classname) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.vTable), \ + DEFINE_MANAGED_VTABLE_INT(classname, (QT_PREPEND_NAMESPACE(QtPrivate)::is_same::value) ? Q_NULLPTR : &classname::SuperClass::static_vtbl.vTable), \ call, \ construct, \ get, \ -- cgit v1.2.3 From b03c85de2ab337858b44bf0a21692d7b544313a5 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Tue, 16 Aug 2016 13:10:51 +0200 Subject: Doc: Remove references to Windows CE The platform is not supported since Qt 5.7 Task-number: QTBUG-55331 Change-Id: I5a38940bd8ebf7dd62d04015e1738ee23ac65bb2 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 28f8bf4855..dd54760760 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -409,7 +409,6 @@ The following functions are also on the Qt object. \li \c "osx" - OS X \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows - \li \c "wince" - Windows CE \li \c "winrt" - Windows Runtime \li \c "winphone" - Windows Phone \endlist -- cgit v1.2.3 From 0bf89f3ce602ce2ecd3d21bc989aef6f8fb02207 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 16 Aug 2016 16:31:46 -0700 Subject: D3D12: Convert 8-bit glyphs to 32-bit to prevent using R8 formats Until we figure out why DXGI_FORMAT_R8_UNORM sampling produces weird results with AMD cards, disable it and convert to RGBA. The check could be done at runtime based on the device's VendorId (0x1002), however the shader needs changes too so it would make things more convoluted. Hence only a compile-time define for now. Task-number: QTBUG-55330 Change-Id: I73f038cf0aeba742e8ea6669359c8a6e8e400a06 Reviewed-by: Andy Nichols --- src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp | 34 +++++++++++++++------- src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h | 15 +++++++--- src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h | 3 +- .../scenegraph/d3d12/qsgd3d12glyphcache.cpp | 17 +++++++++-- src/plugins/scenegraph/d3d12/shaders/textmask.hlsl | 16 +++++----- 5 files changed, 59 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp index 87215d5b54..900dfe7ef7 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp @@ -497,14 +497,15 @@ void QSGD3D12Engine::queueTextureResize(uint id, const QSize &size) d->queueTextureResize(id, size); } -void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos) +void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos, TextureUploadFlags flags) { - d->queueTextureUpload(id, QVector() << image, QVector() << dstPos); + d->queueTextureUpload(id, QVector() << image, QVector() << dstPos, flags); } -void QSGD3D12Engine::queueTextureUpload(uint id, const QVector &images, const QVector &dstPos) +void QSGD3D12Engine::queueTextureUpload(uint id, const QVector &images, const QVector &dstPos, + TextureUploadFlags flags) { - d->queueTextureUpload(id, images, dstPos); + d->queueTextureUpload(id, images, dstPos, flags); } void QSGD3D12Engine::releaseTexture(uint id) @@ -2321,7 +2322,7 @@ uint QSGD3D12EnginePrivate::genTexture() return id; } -static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap, +static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap, bool force32bit, QImage::Format *imageFormat, int *bytesPerPixel) { DXGI_FORMAT f = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -2333,8 +2334,12 @@ static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, case QImage::Format_Grayscale8: case QImage::Format_Indexed8: case QImage::Format_Alpha8: - f = DXGI_FORMAT_R8_UNORM; - bpp = 1; + if (!force32bit) { + f = DXGI_FORMAT_R8_UNORM; + bpp = 1; + } else { + convFormat = QImage::Format_RGBA8888; + } break; case QImage::Format_RGB32: f = DXGI_FORMAT_B8G8R8A8_UNORM; @@ -2410,7 +2415,9 @@ void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Fo textureDesc.Height = adjustedSize.height(); textureDesc.DepthOrArraySize = 1; textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize); - textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), nullptr, nullptr); + textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), + createFlags.testFlag(QSGD3D12Engine::TextureAlways32Bit), + nullptr, nullptr); textureDesc.SampleDesc.Count = 1; textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; if (t.mipmap()) @@ -2524,7 +2531,8 @@ void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size) qDebug("submitted old content copy for texture %u on the copy queue, fence %llu", id, t.fenceValue); } -void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector &images, const QVector &dstPos) +void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector &images, const QVector &dstPos, + QSGD3D12Engine::TextureUploadFlags flags) { Q_ASSERT(id); Q_ASSERT(images.count() == dstPos.count()); @@ -2561,7 +2569,9 @@ void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector &i int totalSize = 0; for (const QImage &image : images) { int bytesPerPixel; - textureFormat(image.format(), t.alpha(), t.mipmap(), nullptr, &bytesPerPixel); + textureFormat(image.format(), t.alpha(), t.mipmap(), + flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit), + nullptr, &bytesPerPixel); const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width(); const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height(); const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); @@ -2593,7 +2603,9 @@ void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector &i for (int i = 0; i < images.count(); ++i) { QImage::Format convFormat; int bytesPerPixel; - textureFormat(images[i].format(), t.alpha(), t.mipmap(), &convFormat, &bytesPerPixel); + textureFormat(images[i].format(), t.alpha(), t.mipmap(), + flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit), + &convFormat, &bytesPerPixel); if (Q_UNLIKELY(debug_texture() && i == 0)) qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel); diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h index 46cd73e63a..b30994fe0d 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h @@ -349,16 +349,22 @@ public: static QSize mipMapAdjustedSourceSize(const QSize &size); enum TextureCreateFlag { - TextureWithAlpha = 0x1, - TextureWithMipMaps = 0x2 + TextureWithAlpha = 0x01, + TextureWithMipMaps = 0x02, + TextureAlways32Bit = 0x04 }; Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag) + enum TextureUploadFlag { + TextureUploadAlways32Bit = 0x01 + }; + Q_DECLARE_FLAGS(TextureUploadFlags, TextureUploadFlag) + uint genTexture(); void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags); void queueTextureResize(uint id, const QSize &size); - void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint()); - void queueTextureUpload(uint id, const QVector &images, const QVector &dstPos); + void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint(), TextureUploadFlags flags = 0); + void queueTextureUpload(uint id, const QVector &images, const QVector &dstPos, TextureUploadFlags flags = 0); void releaseTexture(uint id); void useTexture(uint id); @@ -381,6 +387,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureUploadFlags) QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h index b3b244cd86..1048ed63e7 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h @@ -170,7 +170,8 @@ public: uint genTexture(); void createTexture(uint id, const QSize &size, QImage::Format format, QSGD3D12Engine::TextureCreateFlags flags); void queueTextureResize(uint id, const QSize &size); - void queueTextureUpload(uint id, const QVector &images, const QVector &dstPos); + void queueTextureUpload(uint id, const QVector &images, const QVector &dstPos, + QSGD3D12Engine::TextureUploadFlags flags); void releaseTexture(uint id); void useTexture(uint id); diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp index 45ef202e83..915917c3d5 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp @@ -42,6 +42,11 @@ QT_BEGIN_NAMESPACE +// Convert A8 glyphs to 32-bit in the engine. This is here to work around +// QTBUG-55330 for AMD cards. +// If removing, textmask.hlsl must be adjusted! (.a -> .r) +#define ALWAYS_32BIT + // NOTE: Avoid categorized logging. It is slow. #define DECLARE_DEBUG_VAR(variable) \ @@ -77,7 +82,11 @@ void QSGD3D12GlyphCache::createTextureData(int width, int height) const QImage::Format imageFormat = m_format == QFontEngine::Format_A8 ? QImage::Format_Alpha8 : QImage::Format_ARGB32_Premultiplied; - m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::TextureWithAlpha); + m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::TextureWithAlpha +#ifdef ALWAYS_32BIT + | QSGD3D12Engine::TextureAlways32Bit +#endif + ); } void QSGD3D12GlyphCache::resizeTextureData(int width, int height) @@ -146,7 +155,11 @@ void QSGD3D12GlyphCache::endFillTexture() Q_ASSERT(m_id); - m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos); + m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos +#ifdef ALWAYS_32BIT + , QSGD3D12Engine::TextureUploadAlways32Bit +#endif + ); // Nothing else left to do, it is up to the text material to call // useTexture() which will then add the texture dependency to the frame. diff --git a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl b/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl index f9d92e8ee9..bb9381e7c0 100644 --- a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl +++ b/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl @@ -45,7 +45,7 @@ float4 PS_TextMask32(PSInput input) : SV_TARGET float4 PS_TextMask8(PSInput input) : SV_TARGET { - return colorVec * tex.Sample(samp, input.coord).r; + return colorVec * tex.Sample(samp, input.coord).a; } struct StyledPSInput @@ -66,8 +66,8 @@ StyledPSInput VS_StyledText(VSInput input) float4 PS_StyledText(StyledPSInput input) : SV_TARGET { - float glyph = tex.Sample(samp, input.coord).r; - float style = clamp(tex.Sample(samp, input.shiftedCoord).r - glyph, 0.0, 1.0); + float glyph = tex.Sample(samp, input.coord).a; + float style = clamp(tex.Sample(samp, input.shiftedCoord).a - glyph, 0.0, 1.0); return style * styleColor + glyph * colorVec; } @@ -95,10 +95,10 @@ OutlinedPSInput VS_OutlinedText(VSInput input) float4 PS_OutlinedText(OutlinedPSInput input) : SV_TARGET { - float glyph = tex.Sample(samp, input.coord).r; - float outline = clamp(clamp(tex.Sample(samp, input.coordUp).r - + tex.Sample(samp, input.coordDown).r - + tex.Sample(samp, input.coordLeft).r - + tex.Sample(samp, input.coordRight).r, 0.0, 1.0) - glyph, 0.0, 1.0); + float glyph = tex.Sample(samp, input.coord).a; + float outline = clamp(clamp(tex.Sample(samp, input.coordUp).a + + tex.Sample(samp, input.coordDown).a + + tex.Sample(samp, input.coordLeft).a + + tex.Sample(samp, input.coordRight).a, 0.0, 1.0) - glyph, 0.0, 1.0); return outline * styleColor + glyph * colorVec; } -- cgit v1.2.3 From 9fcca80bc4682fd274d2e4d8014390962dab5daa Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Aug 2016 16:05:34 +0200 Subject: Make the unit mapping on Windows configurable with regards to executable mapping If we generate byte code, then we can mmap without the executable flags, otherwise we need them. This should make things work out of the box on platforms where special rights are needed before executable mappings are allowed. Change-Id: I24e663f85d661bc51cd3bf2463547b1d1590ea32 Reviewed-by: Maurice Kalinowski --- src/qml/compiler/qqmlirbuilder.cpp | 2 -- src/qml/compiler/qqmlirbuilder_p.h | 1 - src/qml/compiler/qv4compilationunitmapper_win.cpp | 9 +++++++-- src/qml/compiler/qv4compileddata_p.h | 5 +++-- src/qml/compiler/qv4compiler.cpp | 1 + src/qml/compiler/qv4jsir_p.h | 2 ++ src/qml/jit/qv4isel_masm.cpp | 1 + src/qml/qml/qqmltypeloader.cpp | 2 +- 8 files changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index ef8ffa8620..31b964897f 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -302,7 +302,6 @@ Document::Document(bool debugMode) , program(0) , indexOfRootObject(0) , jsGenerator(&jsModule) - , unitFlags(0) { } @@ -1393,7 +1392,6 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine QV4::CompiledData::Unit *qmlUnit = reinterpret_cast(data); qmlUnit->unitSize = totalSize; - qmlUnit->flags |= output.unitFlags; qmlUnit->flags |= QV4::CompiledData::Unit::IsQml; qmlUnit->offsetToImports = unitSize; qmlUnit->nImports = output.imports.count(); diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index eedc262e7a..cc16dc2104 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -435,7 +435,6 @@ struct Q_QML_PRIVATE_EXPORT Document int indexOfRootObject; QVector objects; QV4::Compiler::JSUnitGenerator jsGenerator; - quint32 unitFlags; QQmlRefPointer javaScriptCompilationUnit; diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp index 7e62cbfe8b..6c2f36e7a0 100644 --- a/src/qml/compiler/qv4compilationunitmapper_win.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp @@ -94,9 +94,14 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co if (!verifyHeader(&header, sourcePath, errorString)) return nullptr; + const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode + ? PAGE_EXECUTE_READ : PAGE_READONLY; + const uint viewFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode + ? (FILE_MAP_READ | FILE_MAP_EXECUTE) : FILE_MAP_READ; + // Data structure and qt version matched, so now we can access the rest of the file safely. - HANDLE fileMappingHandle = CreateFileMapping(handle, 0, PAGE_EXECUTE_READ, 0, 0, 0); + HANDLE fileMappingHandle = CreateFileMapping(handle, 0, mappingFlags, 0, 0, 0); if (!fileMappingHandle) { *errorString = qt_error_string(GetLastError()); return false; @@ -106,7 +111,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co CloseHandle(fileMappingHandle); }); - dataPtr = MapViewOfFile(fileMappingHandle, FILE_MAP_READ | FILE_MAP_EXECUTE, 0, 0, 0); + dataPtr = MapViewOfFile(fileMappingHandle, viewFlags, 0, 0, 0); if (!dataPtr) { *errorString = qt_error_string(GetLastError()); return nullptr; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index a6ca1594a4..b71c1d8185 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE // Bump this whenever the compiler data structures change in an incompatible way. -#define QV4_DATA_STRUCTURE_VERSION 0x02 +#define QV4_DATA_STRUCTURE_VERSION 0x03 class QIODevice; class QQmlPropertyCache; @@ -619,7 +619,8 @@ struct Unit IsQml = 0x2, StaticData = 0x4, // Unit data persistent in memory? IsSingleton = 0x8, - IsSharedLibrary = 0x10 // .pragma shared? + IsSharedLibrary = 0x10, // .pragma shared? + ContainsMachineCode = 0x20 // used to determine if we need to mmap with execute permissions }; LEUInt32 flags; LEUInt32 stringTableSize; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 50ade2c6e5..c6a872cc34 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -364,6 +364,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp CompiledData::Unit unit; memcpy(unit.magic, CompiledData::magic_str, sizeof(unit.magic)); unit.flags = QV4::CompiledData::Unit::IsJavascript; + unit.flags |= irModule->unitFlags; unit.version = QV4_DATA_STRUCTURE_VERSION; unit.qtVersion = QT_VERSION; unit.architectureIndex = registerString(QSysInfo::buildAbi()); diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 51b8797862..73aa6c4975 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -934,6 +934,7 @@ struct Q_QML_PRIVATE_EXPORT Module { QString fileName; qint64 sourceTimeStamp; bool isQmlModule; // implies rootFunction is always 0 + uint unitFlags; // flags merged into CompiledData::Unit::flags #ifdef QT_NO_QML_DEBUGGER static const bool debugMode = false; #else @@ -946,6 +947,7 @@ struct Q_QML_PRIVATE_EXPORT Module { : rootFunction(0) , sourceTimeStamp(0) , isQmlModule(false) + , unitFlags(0) #ifndef QT_NO_QML_DEBUGGER , debugMode(debugMode) {} diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index c1c42f876c..9759b72794 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -265,6 +265,7 @@ InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::Ex , qmlEngine(qmlEngine) { compilationUnit->codeRefs.resize(module->functions.size()); + module->unitFlags |= QV4::CompiledData::Unit::ContainsMachineCode; } InstructionSelection::~InstructionSelection() diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index f7846f333b..566f5ef767 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2929,7 +2929,7 @@ void QQmlScriptBlob::dataReceived(const Data &data) irUnit.javaScriptCompilationUnit = unit; irUnit.imports = collector.imports; if (collector.hasPragmaLibrary) - irUnit.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary; + irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary; QmlIR::QmlUnitGenerator qmlGenerator; QV4::CompiledData::ResolvedTypeReferenceMap emptyDependencies; -- cgit v1.2.3 From 7101ca92fe9449d4da1b45cf57b9fa62e527b500 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 15 Aug 2016 11:24:17 +0200 Subject: Enable QML disk cache on WinRT 10 Change-Id: I6a61d015c93bf507c0b68f3a975d8574334a05e5 Reviewed-by: Maurice Kalinowski --- src/qml/compiler/qv4compilationunitmapper_win.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp index 6c2f36e7a0..4361752f93 100644 --- a/src/qml/compiler/qv4compilationunitmapper_win.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp @@ -75,10 +75,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co CloseHandle(handle); }); -#if defined(Q_OS_WINRT) - *errorString = QStringLiteral("Compilation unit mapping not supported on WinRT yet"); - return nullptr; -#else +#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900 CompiledData::Unit header; DWORD bytesRead; if (!ReadFile(handle, reinterpret_cast(&header), sizeof(header), &bytesRead, nullptr)) { @@ -118,12 +115,15 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co } return reinterpret_cast(dataPtr); +#else + *errorString = QStringLiteral("Compilation unit mapping not supported on WinRT 8.1"); + return nullptr; #endif } void CompilationUnitMapper::close() { -#if !defined(Q_OS_WINRT) +#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900 if (dataPtr != nullptr) UnmapViewOfFile(dataPtr); #endif -- cgit v1.2.3 From 39179d41f0b7278f869f3d746aa276940754875e Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Aug 2016 13:26:12 +0200 Subject: Fix return value CompilationUnitMapper::open is supposed to return a pointer, not bool. Change-Id: I798be4038b8df047d380201b746f8d97cc1db526 Reviewed-by: Simon Hausmann --- src/qml/compiler/qv4compilationunitmapper_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp index 4361752f93..abf109484b 100644 --- a/src/qml/compiler/qv4compilationunitmapper_win.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp @@ -80,7 +80,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co DWORD bytesRead; if (!ReadFile(handle, reinterpret_cast(&header), sizeof(header), &bytesRead, nullptr)) { *errorString = qt_error_string(GetLastError()); - return false; + return nullptr; } if (bytesRead != sizeof(header)) { @@ -101,7 +101,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co HANDLE fileMappingHandle = CreateFileMapping(handle, 0, mappingFlags, 0, 0, 0); if (!fileMappingHandle) { *errorString = qt_error_string(GetLastError()); - return false; + return nullptr; } QDeferredCleanup mappingCleanup([fileMappingHandle]{ -- cgit v1.2.3 From a86e6e1821da51065b2fb3392c23da17e6e13f97 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 16 Aug 2016 12:51:12 +0200 Subject: Prospective fix for invalidating caches for qml files from resources The Qt resource system does not store any time stamps, so to validation purposes fall back to the time stamp of the application binary. Change-Id: Ia1c4d06a634ffdb2d4d281aae55e5ed34f044a3c Reviewed-by: J-P Nurmi Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compilationunitmapper.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/compiler/qv4compilationunitmapper.cpp b/src/qml/compiler/qv4compilationunitmapper.cpp index b53b7cf784..2e1213464c 100644 --- a/src/qml/compiler/qv4compilationunitmapper.cpp +++ b/src/qml/compiler/qv4compilationunitmapper.cpp @@ -42,6 +42,7 @@ #include "qv4compileddata_p.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -77,7 +78,16 @@ bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const { QFileInfo sourceCode(sourcePath); - if (sourceCode.exists() && sourceCode.lastModified().toMSecsSinceEpoch() != header->sourceTimeStamp) { + QDateTime sourceTimeStamp; + if (sourceCode.exists()) + sourceTimeStamp = sourceCode.lastModified(); + + // Files from the resource system do not have any time stamps, so fall back to the application + // executable. + if (!sourceTimeStamp.isValid()) + sourceTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); + + if (sourceTimeStamp.isValid() && sourceTimeStamp.toMSecsSinceEpoch() != header->sourceTimeStamp) { *errorString = QStringLiteral("QML source file has a different time stamp than cached file."); return false; } -- cgit v1.2.3 From 82e551b5fa321612cb155a450d3e0ec76a63fd45 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 8 Aug 2016 11:24:04 +0200 Subject: QML: Get rid of propTypeName in QQmlPropertyRawData This information can be recreated when needed: the property/method index is known, just like the meta-object, so we can query that for the type name. Change-Id: I9d4f557eda4e4a946a80b68d3787823767b0b1d3 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlpropertycache.cpp | 17 ++++++++++++----- src/qml/qml/qqmlpropertycache_p.h | 8 +------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index af9b8cc045..7cb1425725 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -161,7 +161,6 @@ void QQmlPropertyData::lazyLoad(const QMetaProperty &p) _flags.type = Flags::QVariantType; } else if (type == QVariant::UserType || type == -1) { _flags.notFullyResolved = true; - setPropTypeName(p.typeName()); } else { setPropType(type); } @@ -224,7 +223,6 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m) if (!returnType) returnType = "\0"; if ((*returnType != 'v') || (qstrcmp(returnType+1, "oid") != 0)) { - setPropTypeName(returnType); _flags.notFullyResolved = true; } @@ -691,13 +689,22 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, void QQmlPropertyCache::resolve(QQmlPropertyData *data) const { Q_ASSERT(data->notFullyResolved()); - - data->setPropType(QMetaType::type(data->propTypeName())); data->_flags.notFullyResolved = false; + const QMetaObject *mo = firstCppMetaObject(); + if (data->isFunction()) { + auto metaMethod = mo->method(data->coreIndex()); + const char *retTy = metaMethod.typeName(); + if (!retTy) + retTy = "\0"; + data->setPropType(QMetaType::type(retTy)); + } else { + auto metaProperty = mo->property(data->coreIndex()); + data->setPropType(QMetaType::type(metaProperty.typeName())); + } + if (!data->isFunction()) { if (data->propType() == QMetaType::UnknownType) { - const QMetaObject *mo = _metaObject; QQmlPropertyCache *p = _parent; while (p && (!mo || _ownMetaObject)) { mo = p->_metaObject; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 6d3c4a8a7e..8a1f3810aa 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -177,9 +177,6 @@ public: int propType() const { Q_ASSERT(isFullyResolved()); return _propType; } void setPropType(int pt) { _propType = pt; } - const char *propTypeName() const { Q_ASSERT(!isFullyResolved()); return _propTypeName; } - void setPropTypeName(const char *ptn) { _propTypeName = ptn; } - int notifyIndex() const { return _notifyIndex; } void setNotifyIndex(int idx) { _notifyIndex = idx; } @@ -220,10 +217,7 @@ public: void setCoreIndex(int idx) { _coreIndex = idx; } private: - union { - int _propType; // When !NotFullyResolved - const char *_propTypeName; // When NotFullyResolved - }; + int _propType; // When !NotFullyResolved union { // The notify index is in the range returned by QObjectPrivate::signalIndex(). // This is different from QMetaMethod::methodIndex(). -- cgit v1.2.3 From 4840bc0c207aa09b4332842c67e65bc92f43d3bd Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:13:04 +0300 Subject: QQuickPathView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: I61f42076d36265b58dcc598394c6b3576b02dd60 Reviewed-by: Shawn Rutledge Reviewed-by: Venugopal Shivashankar --- src/quick/items/qquickpathview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index f858b18c84..07a33db231 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1459,7 +1459,7 @@ void QQuickPathView::positionViewAtIndex(int index, int mode) } /*! - \qmlmethod int QtQuick::PathView::indexAt(int x, int y) + \qmlmethod int QtQuick::PathView::indexAt(real x, real y) Returns the index of the item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, -1 is returned. @@ -1483,7 +1483,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const } /*! - \qmlmethod Item QtQuick::PathView::itemAt(int x, int y) + \qmlmethod Item QtQuick::PathView::itemAt(real x, real y) Returns the item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, null is returned. -- cgit v1.2.3 From f2ba71dd55736fc2ff1d817c19d5295d70b49c07 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 17:19:29 +0300 Subject: QQuickPathView: port some loops to 'range for' The 'range for' works with pointer increments and the generated code is less, so we save some text size. Change-Id: I66a2827c9a342d9453a52028d3ec76a91a19a606 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 0d047bc882..ef6a45b014 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -244,10 +244,9 @@ void QQuickPathViewPrivate::clear() releaseItem(currentItem); currentItem = 0; } - for (int i=0; i= 0) { if (model) model->cancel(requestedIndex); @@ -417,12 +416,9 @@ void QQuickPathViewPrivate::setHighlightPosition(qreal pos) void QQuickPathView::pathUpdated() { Q_D(QQuickPathView); - QList::iterator it = d->items.begin(); - while (it != d->items.end()) { - QQuickItem *item = *it; + for (QQuickItem *item : qAsConst(d->items)) { if (QQuickPathViewAttached *att = d->attached(item)) att->m_percent = -1; - ++it; } refill(); } @@ -1521,8 +1517,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const if (!d->isValid()) return -1; - for (int idx = 0; idx < d->items.count(); ++idx) { - QQuickItem *item = d->items.at(idx); + for (QQuickItem *item : d->items) { QPointF p = item->mapFromItem(this, QPointF(x, y)); if (item->contains(p)) return d->model->indexOf(item, 0); @@ -1545,8 +1540,7 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const if (!d->isValid()) return 0; - for (int idx = 0; idx < d->items.count(); ++idx) { - QQuickItem *item = d->items.at(idx); + for (QQuickItem *item : d->items) { QPointF p = item->mapFromItem(this, QPointF(x, y)); if (item->contains(p)) return item; -- cgit v1.2.3 From 4354588f556953a357d23bd303a8d85296b44457 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 17:41:23 +0300 Subject: QQuickPathView: de-duplicate code of indexAt() Re-use itemAt() method. Change-Id: Ic3673fe4d9fd3f27abc90c9436e99e0da9821cdb Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index ef6a45b014..1533a14831 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1514,16 +1514,8 @@ void QQuickPathView::positionViewAtIndex(int index, int mode) int QQuickPathView::indexAt(qreal x, qreal y) const { Q_D(const QQuickPathView); - if (!d->isValid()) - return -1; - - for (QQuickItem *item : d->items) { - QPointF p = item->mapFromItem(this, QPointF(x, y)); - if (item->contains(p)) - return d->model->indexOf(item, 0); - } - - return -1; + QQuickItem *item = itemAt(x, y); + return item ? d->model->indexOf(item, 0) : -1; } /*! -- cgit v1.2.3 From b095e0a85b1caef592f01f9786c56ac301a42dcf Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 18:41:48 +0300 Subject: QQuickPathView: de-duplicate calls and cache results Change-Id: I4b49b912c068fd5c76a2c2c8580f616cb42e9bdb Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 1533a14831..c061c8159a 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1543,8 +1543,9 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const { - qreal samples = qMin(path->path().length()/5, qreal(500.0)); - qreal res = path->path().length()/samples; + const auto pathLength = path->path().length(); + qreal samples = qMin(pathLength / 5, qreal(500.0)); + qreal res = pathLength / samples; qreal mindist = 1e10; // big number QPointF nearPoint = path->pointAt(0); @@ -1741,12 +1742,13 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *) qreal velocity = calcVelocity(); qreal count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount); - qreal pixelVelocity = (path->path().length()/count) * velocity; + const auto averageItemLength = path->path().length() / count; + qreal pixelVelocity = averageItemLength * velocity; if (qAbs(pixelVelocity) > MinimumFlickVelocity) { if (qAbs(pixelVelocity) > maximumFlickVelocity || snapMode == QQuickPathView::SnapOneItem) { // limit velocity qreal maxVel = velocity < 0 ? -maximumFlickVelocity : maximumFlickVelocity; - velocity = maxVel / (path->path().length()/count); + velocity = maxVel / averageItemLength; } // Calculate the distance to be travelled qreal v2 = velocity*velocity; -- cgit v1.2.3 From e330198669f8897212912caee65ae8910ad77519 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:21:22 +0300 Subject: QQuickListView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: Ieb4ea8396876f237adedf5df8ab5aeec1055229f Reviewed-by: Shawn Rutledge --- src/quick/items/qquicklistview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index b324e00cac..9f126525d6 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3318,7 +3318,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex */ /*! - \qmlmethod int QtQuick::ListView::indexAt(int x, int y) + \qmlmethod int QtQuick::ListView::indexAt(real x, real y) Returns the index of the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is @@ -3331,7 +3331,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex */ /*! - \qmlmethod Item QtQuick::ListView::itemAt(int x, int y) + \qmlmethod Item QtQuick::ListView::itemAt(real x, real y) Returns the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is -- cgit v1.2.3 From 24e6df252dc6118541d064835cea6ee470985dae Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:20:16 +0300 Subject: QQuickGridView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: I5362a407b8417b62bb27bb313dccce8611b5e316 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickgridview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 6e5710a97b..e78ad07548 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2586,7 +2586,7 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co */ /*! - \qmlmethod int QtQuick::GridView::indexAt(int x, int y) + \qmlmethod int QtQuick::GridView::indexAt(real x, real y) Returns the index of the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is @@ -2599,7 +2599,7 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co */ /*! - \qmlmethod Item QtQuick::GridView::itemAt(int x, int y) + \qmlmethod Item QtQuick::GridView::itemAt(real x, real y) Returns the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is -- cgit v1.2.3 From 7b2d2d773594bde1b67ef068edef7a6ef920cf9c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 18:27:44 +0300 Subject: QQuickPathView: optimize releasing of cache items Release all cache items, and then clean container. Avoid quadratic complexity. Change-Id: I61f3e43aa070c0be074c3804a83f2ff1de9a398d Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index c061c8159a..660ed9db16 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -2152,8 +2152,9 @@ void QQuickPathView::refill() if (QQuickPathViewAttached *att = d->attached(d->highlightItem)) att->setOnPath(currentVisible); } - while (d->itemCache.count()) - d->releaseItem(d->itemCache.takeLast()); + for (QQuickItem *item : qAsConst(d->itemCache)) + d->releaseItem(item); + d->itemCache.clear(); d->inRefill = false; if (currentChanged) @@ -2237,8 +2238,9 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) d->items.clear(); if (!d->modelCount) { - while (d->itemCache.count()) - d->releaseItem(d->itemCache.takeLast()); + for (QQuickItem * item : qAsConst(d->itemCache)) + d->releaseItem(item); + d->itemCache.clear(); d->offset = 0; changedOffset = true; d->tl.reset(d->moveOffset); -- cgit v1.2.3 From 707b9be53cef30ea9b7029945ef70e3d769b4e78 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 8 Aug 2016 11:49:04 +0200 Subject: QML: Change storage types of QQmlPropertyRawData fields By getting rid of the unions, all "features" (like accessors and notify indices) can now be used for all properties or functions. Other fields are trimmed to the size as used in other parts of QML. Now the size of QQmlPropertyRawData is 24 bytes on 32bit platforms, and 32 bytes on 64bit platforms. Change-Id: Ie2f22eb60e6119c93e3d3ea32a2974a718d45e91 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlpropertycache_p.h | 96 ++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 8a1f3810aa..480f1dcf40 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -168,20 +168,45 @@ public: bool isCloned() const { return _flags.isCloned; } bool isConstructor() const { return _flags.isConstructor; } - bool hasOverride() const { return !(_flags.hasAccessors) && - overrideIndex() >= 0; } - bool hasRevision() const { return !(_flags.hasAccessors) && revision() != 0; } + bool hasOverride() const { return overrideIndex() >= 0; } + bool hasRevision() const { return revision() != 0; } bool isFullyResolved() const { return !_flags.notFullyResolved; } int propType() const { Q_ASSERT(isFullyResolved()); return _propType; } - void setPropType(int pt) { _propType = pt; } + void setPropType(int pt) + { + Q_ASSERT(pt >= 0); + Q_ASSERT(pt <= std::numeric_limits::max()); + _propType = quint16(pt); + } int notifyIndex() const { return _notifyIndex; } - void setNotifyIndex(int idx) { _notifyIndex = idx; } + void setNotifyIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _notifyIndex = qint16(idx); + } - QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; } - void setArguments(QQmlPropertyCacheMethodArguments *args) { _arguments = args; } + bool overrideIndexIsProperty() const { return _flags.overrideIndexIsProperty; } + void setOverrideIndexIsProperty(bool onoff) { _flags.overrideIndexIsProperty = onoff; } + + int overrideIndex() const { return _overrideIndex; } + void setOverrideIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _overrideIndex = qint16(idx); + } + + int coreIndex() const { return _coreIndex; } + void setCoreIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _coreIndex = qint16(idx); + } int revision() const { return _revision; } void setRevision(int rev) @@ -191,6 +216,9 @@ public: _revision = qint16(rev); } + QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; } + void setArguments(QQmlPropertyCacheMethodArguments *args) { _arguments = args; } + int metaObjectOffset() const { return _metaObjectOffset; } void setMetaObjectOffset(int off) { @@ -199,51 +227,35 @@ public: _metaObjectOffset = qint16(off); } - bool overrideIndexIsProperty() const { return _flags.overrideIndexIsProperty; } - void setOverrideIndexIsProperty(bool onoff) { _flags.overrideIndexIsProperty = onoff; } - - int overrideIndex() const { return _overrideIndex; } - void setOverrideIndex(int idx) - { - Q_ASSERT(idx >= std::numeric_limits::min()); - Q_ASSERT(idx <= std::numeric_limits::max()); - _overrideIndex = idx; - } - QQmlAccessors *accessors() const { return _accessors; } void setAccessors(QQmlAccessors *acc) { _accessors = acc; } - int coreIndex() const { return _coreIndex; } - void setCoreIndex(int idx) { _coreIndex = idx; } - private: - int _propType; // When !NotFullyResolved - union { - // The notify index is in the range returned by QObjectPrivate::signalIndex(). - // This is different from QMetaMethod::methodIndex(). - int _notifyIndex; // When !IsFunction - QQmlPropertyCacheMethodArguments *_arguments; // When IsFunction && HasArguments - }; + Flags _flags; + qint16 _coreIndex; + quint16 _propType; - union { - struct { // When !HasAccessors - qint16 _revision; - qint16 _metaObjectOffset; + // The notify index is in the range returned by QObjectPrivate::signalIndex(). + // This is different from QMetaMethod::methodIndex(). + qint16 _notifyIndex; + qint16 _overrideIndex; - signed int _overrideIndex; // When !IsValueTypeVirtual - }; - struct { // When HasAccessors - QQmlAccessors *_accessors; - }; - }; + qint16 _revision; + qint16 _metaObjectOffset; - int _coreIndex; - Flags _flags; + QQmlPropertyCacheMethodArguments *_arguments; + QQmlAccessors *_accessors; friend class QQmlPropertyData; friend class QQmlPropertyCache; }; +#if QT_POINTER_SIZE == 4 +Q_STATIC_ASSERT(sizeof(QQmlPropertyRawData) == 24); +#else // QT_POINTER_SIZE == 8 +Q_STATIC_ASSERT(sizeof(QQmlPropertyRawData) == 32); +#endif + class QQmlPropertyData : public QQmlPropertyRawData { public: @@ -619,12 +631,14 @@ void QQmlPropertyRawData::Flags::copyPropertyTypeFlags(QQmlPropertyRawData::Flag QQmlPropertyData::QQmlPropertyData() { + setCoreIndex(-1); setPropType(0); setNotifyIndex(-1); setOverrideIndex(-1); setRevision(0); setMetaObjectOffset(-1); - setCoreIndex(-1); + setArguments(nullptr); + setAccessors(nullptr); } QQmlPropertyData::QQmlPropertyData(const QQmlPropertyRawData &d) -- cgit v1.2.3 From 31650bc49b64c8ee6e14094a4d869afe08c5c25d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Aug 2016 16:57:29 +0200 Subject: Minor binding code cleanup Remove the QQmlBinding *binding argument as it is always the this pointer. Change-Id: I76ccf64a1d37ce32089c81f60466dce79b9fa5bf Reviewed-by: Lars Knoll --- src/qml/qml/qqmlbinding.cpp | 11 ++++++----- src/qml/qml/qqmlbinding_p.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 8ed7641610..d944857fc1 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -191,7 +191,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) flags.setFlag(QQmlPropertyData::BypassInterceptor); QQmlBindingProfiler prof(ep->profiler, this, f); - doUpdate(this, watcher, flags, scope, f); + doUpdate(watcher, flags, scope, f); if (!watcher.wasDeleted()) setUpdatingFlag(false); @@ -205,14 +205,15 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) class QQmlBindingBinding: public QQmlBinding { protected: - void doUpdate(QQmlBinding *binding, const DeleteWatcher &, + void doUpdate(const DeleteWatcher &, QQmlPropertyData::WriteFlags flags, QV4::Scope &, const QV4::ScopedFunctionObject &) Q_DECL_OVERRIDE Q_DECL_FINAL { Q_ASSERT(!m_targetIndex.hasValueTypeIndex()); QQmlPropertyData *pd = nullptr; getPropertyData(&pd, nullptr); - pd->writeProperty(*m_target, &binding, flags); + QQmlBinding *thisPtr = this; + pd->writeProperty(*m_target, &thisPtr, flags); } }; @@ -221,7 +222,7 @@ protected: class QQmlNonbindingBinding: public QQmlBinding { protected: - void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, + void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) Q_DECL_OVERRIDE Q_DECL_FINAL { @@ -231,7 +232,7 @@ protected: bool isUndefined = false; QV4::ScopedCallData callData(scope); - binding->QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); + QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); bool error = false; if (!watcher.wasDeleted() && isAddedToObject() && !hasError()) diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 1801c3040c..6d42a8ea8a 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -102,7 +102,7 @@ public: void expressionChanged() Q_DECL_OVERRIDE; protected: - virtual void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, + virtual void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) = 0; -- cgit v1.2.3 From b35858d4b8371adb030bc17f4aa161ce60e5984e Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 9 Aug 2016 16:41:33 +0300 Subject: Quick: replace 'foreach' with 'range for' Change-Id: I3493b16a184fc811289db9e98eff37bb987113a3 Reviewed-by: Shawn Rutledge --- src/quick/accessible/qaccessiblequickitem.cpp | 4 ++-- .../designer/qquickdesignercustomobjectdata.cpp | 4 ++-- src/quick/designer/qquickdesignersupport.cpp | 7 ++++--- src/quick/designer/qquickdesignersupportitems.cpp | 14 ++++++++------ src/quick/items/qquickdroparea.cpp | 2 +- src/quick/items/qquickitem.cpp | 3 ++- src/quick/items/qquickitemview.cpp | 4 ++-- src/quick/items/qquickmultipointtoucharea.cpp | 20 ++++++++++---------- src/quick/items/qquickpathview.cpp | 13 ++++++++----- src/quick/items/qquickrepeater.cpp | 4 ++-- src/quick/items/qquickspriteengine.cpp | 19 ++++++++++--------- src/quick/items/qquickspriteengine_p.h | 2 +- src/quick/items/qquicktext.cpp | 11 ++++++----- src/quick/items/qquicktextdocument.cpp | 2 +- src/quick/items/qquicktextedit.cpp | 4 ++-- src/quick/items/qquickview.cpp | 12 ++++++------ src/quick/qtquick2.cpp | 2 +- src/quick/scenegraph/coreapi/qsgmaterial.cpp | 4 ++-- src/quick/util/qquickanimation.cpp | 2 +- src/quick/util/qquickanimatorcontroller.cpp | 20 ++++++++++---------- src/quick/util/qquickpath.cpp | 14 +++++++------- src/quick/util/qquickpixmapcache.cpp | 2 +- src/quick/util/qquickpropertychanges.cpp | 2 +- src/quick/util/qquickstate.cpp | 4 ++-- src/quick/util/qquicktransitionmanager.cpp | 10 +++++----- 25 files changed, 97 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index a56d098717..acea958e20 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -160,9 +160,9 @@ int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const static void unignoredChildren(QQuickItem *item, QList *items, bool paintOrder) { - QList childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems() + const QList childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems() : item->childItems(); - Q_FOREACH (QQuickItem *child, childItems) { + for (QQuickItem *child : childItems) { if (QQuickItemPrivate::get(child)->isAccessible) { items->append(child); } else { diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp index 3c8f4b281c..e37254d165 100644 --- a/src/quick/designer/qquickdesignercustomobjectdata.cpp +++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp @@ -145,10 +145,10 @@ void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QObject *obje void QQuickDesignerCustomObjectData::populateResetHashes() { - QQuickDesignerSupport::PropertyNameList propertyNameList = + const QQuickDesignerSupport::PropertyNameList propertyNameList = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object()); - Q_FOREACH (const QQuickDesignerSupport::PropertyName &propertyName, propertyNameList) { + for (const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) { QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object())); QQmlAbstractBinding::Ptr binding = QQmlAbstractBinding::Ptr(QQmlPropertyPrivate::binding(property)); diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index f063cd3a81..44be12bb78 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -236,7 +236,8 @@ bool QQuickDesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toIte bool QQuickDesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem) { - Q_FOREACH (QQuickItem *childItem, fromItem->childItems()) { + const auto childItems = fromItem->childItems(); + for (QQuickItem *childItem : childItems) { if (childItem) { if (isAnchoredTo(childItem, toItem)) return true; @@ -392,10 +393,10 @@ void QQuickDesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuic QList QQuickDesignerSupport::statesForItem(QQuickItem *item) { QList objectList; - QList stateList = QQuickItemPrivate::get(item)->_states()->states(); + const QList stateList = QQuickItemPrivate::get(item)->_states()->states(); objectList.reserve(stateList.size()); - Q_FOREACH (QQuickState* state, stateList) + for (QQuickState* state : stateList) objectList.append(state); return objectList; diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 544ca04754..2003b484ad 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -118,16 +118,16 @@ static void allSubObjects(QObject *object, QObjectList &objectList) } // search recursive in object children list - Q_FOREACH (QObject *childObject, object->children()) { + for (QObject *childObject : object->children()) { allSubObjects(childObject, objectList); } // search recursive in quick item childItems list QQuickItem *quickItem = qobject_cast(object); if (quickItem) { - Q_FOREACH (QQuickItem *childItem, quickItem->childItems()) { + const auto childItems = quickItem->childItems(); + for (QQuickItem *childItem : childItems) allSubObjects(childItem, objectList); - } } } @@ -135,7 +135,7 @@ void QQuickDesignerSupportItems::tweakObjects(QObject *object) { QObjectList objectList; allSubObjects(object, objectList); - Q_FOREACH (QObject* childObject, objectList) { + for (QObject* childObject : qAsConst(objectList)) { stopAnimation(childObject); if (fixResourcePathsForObjectCallBack) fixResourcePathsForObjectCallBack(childObject); @@ -254,7 +254,8 @@ QObject *QQuickDesignerSupportItems::createComponent(const QUrl &componentUrl, Q if (component.isError()) { qWarning() << "Error in:" << Q_FUNC_INFO << componentUrl; - Q_FOREACH (const QQmlError &error, component.errors()) + const auto errors = component.errors(); + for (const QQmlError &error : errors) qWarning() << error; } return object; @@ -282,7 +283,8 @@ void QQuickDesignerSupportItems::disableNativeTextRendering(QQuickItem *item) void QQuickDesignerSupportItems::disableTextCursor(QQuickItem *item) { - Q_FOREACH (QQuickItem *childItem, item->childItems()) + const auto childItems = item->childItems(); + for (QQuickItem *childItem : childItems) disableTextCursor(childItem); QQuickTextInput *textInput = qobject_cast(item); diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index 1701441240..8dcc13971e 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -235,7 +235,7 @@ bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const return true; QRegExp copy = keyRegExp; - foreach (const QString &key, keys) { + for (const QString &key : keys) { if (copy.exactMatch(key)) return true; } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 84f9b0f169..bb5ed60e68 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4106,7 +4106,8 @@ bool QQuickItem::childMouseEventFilter(QQuickItem *item, QEvent *event) */ void QQuickItem::windowDeactivateEvent() { - foreach (QQuickItem* item, childItems()) { + const auto children = childItems(); + for (QQuickItem* item : children) { item->windowDeactivateEvent(); } } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index d3f045f35c..fa874d631c 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -181,7 +181,7 @@ void QQuickItemViewChangeSet::applyChanges(const QQmlChangeSet &changeSet) int moveId = -1; int moveOffset = 0; - foreach (const QQmlChangeSet::Change &r, changeSet.removes()) { + for (const QQmlChangeSet::Change &r : changeSet.removes()) { itemCount -= r.count; if (moveId == -1 && newCurrentIndex >= r.index + r.count) { newCurrentIndex -= r.count; @@ -200,7 +200,7 @@ void QQuickItemViewChangeSet::applyChanges(const QQmlChangeSet &changeSet) currentChanged = true; } } - foreach (const QQmlChangeSet::Change &i, changeSet.inserts()) { + for (const QQmlChangeSet::Change &i : changeSet.inserts()) { if (moveId == -1) { if (itemCount && newCurrentIndex >= i.index) { newCurrentIndex += i.count; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index d31807de7f..d68cb8e3f6 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -362,7 +362,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent) QQuickMultiPointTouchArea::~QQuickMultiPointTouchArea() { clearTouchLists(); - foreach (QObject *obj, _touchPoints) { + for (QObject *obj : qAsConst(_touchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) delete dtp; @@ -524,7 +524,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) } int numTouchPoints = touchPoints.count(); //always remove released touches, and make sure we handle all releases before adds. - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { Qt::TouchPointState touchPointState = p.state(); int id = p.id(); if (touchPointState & Qt::TouchPointReleased) { @@ -539,7 +539,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) } } if (numTouchPoints >= _minimumTouchPoints && numTouchPoints <= _maximumTouchPoints) { - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { Qt::TouchPointState touchPointState = p.state(); int id = p.id(); if (touchPointState & Qt::TouchPointReleased) { @@ -565,7 +565,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) if (!_stealMouse /* !ignoring gesture*/) { bool offerGrab = false; const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { if (p.state() == Qt::TouchPointReleased) continue; const QPointF ¤tPos = p.scenePos(); @@ -599,7 +599,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) void QQuickMultiPointTouchArea::clearTouchLists() { - foreach (QObject *obj, _releasedTouchPoints) { + for (QObject *obj : qAsConst(_releasedTouchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) { _touchPoints.remove(dtp->pointId()); @@ -616,7 +616,7 @@ void QQuickMultiPointTouchArea::clearTouchLists() void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) { QQuickTouchPoint *dtp = 0; - foreach (QQuickTouchPoint* tp, _touchPrototypes) { + for (QQuickTouchPoint* tp : qAsConst(_touchPrototypes)) { if (!tp->inUse()) { tp->setInUse(true); dtp = tp; @@ -636,7 +636,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) { QQuickTouchPoint *dtp = 0; - foreach (QQuickTouchPoint *tp, _touchPrototypes) + for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) if (!tp->inUse()) { tp->setInUse(true); dtp = tp; @@ -782,11 +782,11 @@ void QQuickMultiPointTouchArea::ungrab() ungrabTouchPoints(); if (_touchPoints.count()) { - foreach (QObject *obj, _touchPoints) + for (QObject *obj : qAsConst(_touchPoints)) static_cast(obj)->setPressed(false); emit canceled(_touchPoints.values()); clearTouchLists(); - foreach (QObject *obj, _touchPoints) { + for (QObject *obj : qAsConst(_touchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) delete dtp; @@ -901,7 +901,7 @@ bool QQuickMultiPointTouchArea::shouldFilter(QEvent *event) case QEvent::TouchUpdate: case QEvent::TouchEnd: { QTouchEvent *te = static_cast(event); - foreach (const QTouchEvent::TouchPoint &point, te->touchPoints()) { + for (const QTouchEvent::TouchPoint &point : te->touchPoints()) { if (contains(mapFromScene(point.scenePos()))) { containsPoint = true; break; diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 660ed9db16..af895570a8 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -191,7 +191,8 @@ void QQuickPathView::initItem(int index, QObject *object) att->m_view = this; qreal percent = d->positionOfIndex(index); if (percent < 1.0 && d->path) { - foreach (const QString &attr, d->path->attributes()) + const auto attributes = d->path->attributes(); + for (const QString &attr : attributes) att->setValue(attr.toUtf8(), d->path->attributeAt(attr, percent)); item->setZ(d->requestedZ); } @@ -230,7 +231,8 @@ QQmlOpenMetaObjectType *QQuickPathViewPrivate::attachedType() // pre-create one metatype to share with all attached objects attType = new QQmlOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q)); if (path) { - foreach (const QString &attr, path->attributes()) + const auto attributes = path->attributes(); + for (const QString &attr : attributes) attType->createProperty(attr.toUtf8()); } } @@ -431,7 +433,8 @@ void QQuickPathViewPrivate::updateItem(QQuickItem *item, qreal percent) if (qFuzzyCompare(att->m_percent, percent)) return; att->m_percent = percent; - foreach (const QString &attr, path->attributes()) + const auto attributes = path->attributes(); + for (const QString &attr : attributes) att->setValue(attr.toUtf8(), path->attributeAt(attr, percent)); att->setOnPath(percent < 1.0); } @@ -2182,7 +2185,7 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) int moveOffset = 0; bool currentChanged = false; bool changedOffset = false; - foreach (const QQmlChangeSet::Change &r, changeSet.removes()) { + for (const QQmlChangeSet::Change &r : changeSet.removes()) { if (moveId == -1 && d->currentIndex >= r.index + r.count) { d->currentIndex -= r.count; currentChanged = true; @@ -2208,7 +2211,7 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) } d->modelCount -= r.count; } - foreach (const QQmlChangeSet::Change &i, changeSet.inserts()) { + for (const QQmlChangeSet::Change &i : changeSet.inserts()) { if (d->modelCount) { if (moveId == -1 && i.index <= d->currentIndex) { d->currentIndex += i.count; diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 198573fda5..4f46f41b0d 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -461,7 +461,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) int difference = 0; QHash > > moved; - foreach (const QQmlChangeSet::Change &remove, changeSet.removes()) { + for (const QQmlChangeSet::Change &remove : changeSet.removes()) { int index = qMin(remove.index, d->deletables.count()); int count = qMin(remove.index + remove.count, d->deletables.count()) - index; if (remove.isMove()) { @@ -483,7 +483,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) difference -= remove.count; } - foreach (const QQmlChangeSet::Change &insert, changeSet.inserts()) { + for (const QQmlChangeSet::Change &insert : changeSet.inserts()) { int index = qMin(insert.index, d->deletables.count()); if (insert.isMove()) { QVector > items = moved.value(insert.moveId); diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index db04a83afc..10e0d51709 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -110,10 +110,10 @@ QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent) { } -QQuickSpriteEngine::QQuickSpriteEngine(QList sprites, QObject *parent) +QQuickSpriteEngine::QQuickSpriteEngine(const QList &sprites, QObject *parent) : QQuickSpriteEngine(parent) { - foreach (QQuickSprite* sprite, sprites) + for (QQuickSprite* sprite : sprites) m_states << (QQuickStochasticState*)sprite; } @@ -329,7 +329,7 @@ QQuickPixmap::Status QQuickSpriteEngine::status()//Composed status of all Sprite return QQuickPixmap::Null; int null, loading, ready; null = loading = ready = 0; - foreach (QQuickSprite* s, m_sprites) { + for (QQuickSprite* s : qAsConst(m_sprites)) { switch (s->m_pix.status()) { // ### Maybe add an error message here, because this null shouldn't be reached but when it does, the image fails without an error message. case QQuickPixmap::Null : null++; break; @@ -358,7 +358,7 @@ void QQuickSpriteEngine::startAssemblingImage() QList removals; - foreach (QQuickStochasticState* s, m_states){ + for (QQuickStochasticState* s : qAsConst(m_states)) { QQuickSprite* sprite = qobject_cast(s); if (sprite) { m_sprites << sprite; @@ -367,7 +367,7 @@ void QQuickSpriteEngine::startAssemblingImage() qDebug() << "Error: Non-sprite in QQuickSpriteEngine"; } } - foreach (QQuickStochasticState* s, removals) + for (QQuickStochasticState* s : qAsConst(removals)) m_states.removeAll(s); m_startedImageAssembly = true; } @@ -376,7 +376,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) { QQuickPixmap::Status stat = status(); if (!m_errorsPrinted && stat == QQuickPixmap::Error) { - foreach (QQuickSprite* s, m_sprites) + for (QQuickSprite* s : qAsConst(m_sprites)) if (s->m_pix.isError()) qmlInfo(s) << s->m_pix.error(); m_errorsPrinted = true; @@ -390,7 +390,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) m_maxFrames = 0; m_imageStateCount = 0; - foreach (QQuickSprite* state, m_sprites){ + for (QQuickSprite* state : qAsConst(m_sprites)) { if (state->frames() > m_maxFrames) m_maxFrames = state->frames(); @@ -441,7 +441,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) image.fill(0); QPainter p(&image); int y = 0; - foreach (QQuickSprite* state, m_sprites){ + for (QQuickSprite* state : qAsConst(m_sprites)) { QImage img(state->m_pix.image()); int frameWidth = state->m_frameWidth; int frameHeight = state->m_frameHeight; @@ -665,7 +665,8 @@ uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a lis m_timeOffset = time; m_addAdvance = false; while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.constFirst().first){ - foreach (int idx, m_stateUpdates.constFirst().second) + const auto copy = m_stateUpdates.constFirst().second; + for (int idx : copy) advance(idx); m_stateUpdates.pop_front(); } diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h index 424fa18a54..485afc16e5 100644 --- a/src/quick/items/qquickspriteengine_p.h +++ b/src/quick/items/qquickspriteengine_p.h @@ -266,7 +266,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine Q_PROPERTY(QQmlListProperty sprites READ sprites) public: explicit QQuickSpriteEngine(QObject *parent = 0); - QQuickSpriteEngine(QList sprites, QObject *parent=0); + QQuickSpriteEngine(const QList &sprites, QObject *parent = 0); ~QQuickSpriteEngine(); QQmlListProperty sprites() { diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 9494a55c2d..14268b472e 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -322,7 +322,7 @@ void QQuickText::imageDownloadFinished() if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) { bool needToUpdateLayout = false; - foreach (QQuickStyledTextImgTag *img, d->extra->visibleImgTags) { + for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) { if (!img->size.isValid()) { img->size = img->pix->implicitSize(); needToUpdateLayout = true; @@ -1115,7 +1115,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal QList imagesInLine; if (extra.isAllocated()) { - foreach (QQuickStyledTextImgTag *image, extra->imgTags) { + for (QQuickStyledTextImgTag *image : qAsConst(extra->imgTags)) { if (image->position >= line.textStart() && image->position < line.textStart() + line.textLength()) { @@ -1152,7 +1152,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal } } - foreach (QQuickStyledTextImgTag *image, imagesInLine) { + for (QQuickStyledTextImgTag *image : qAsConst(imagesInLine)) { totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height()); const int leadX = line.cursorToX(image->position); const int trailX = line.cursorToX(image->position, QTextLine::Trailing); @@ -2342,7 +2342,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data node->addTextLayout(QPointF(dx, dy), d->elideLayout, color, d->style, styleColor, linkColor); if (d->extra.isAllocated()) { - foreach (QQuickStyledTextImgTag *img, d->extra->visibleImgTags) { + for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) { QQuickPixmap *pix = img->pix; if (pix && pix->isReady()) node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image()); @@ -2596,7 +2596,8 @@ QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mo QTextLine line = layout->lineAt(i); if (line.naturalTextRect().contains(mousePos)) { int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter); - foreach (const QTextLayout::FormatRange &formatRange, layout->formats()) { + const auto formats = layout->formats(); + for (const QTextLayout::FormatRange &formatRange : formats) { if (formatRange.format.isAnchor() && charPos >= formatRange.start && charPos < formatRange.start + formatRange.length) { diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp index 3eacfd61bc..1dc54eb107 100644 --- a/src/quick/items/qquicktextdocument.cpp +++ b/src/quick/items/qquicktextdocument.cpp @@ -219,7 +219,7 @@ QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap( void QQuickTextDocumentWithImageResources::clearResources() { - foreach (QQuickPixmap *pixmap, m_resources) + for (QQuickPixmap *pixmap : qAsConst(m_resources)) pixmap->clear(this); qDeleteAll(m_resources); m_resources.clear(); diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index d6d9d53a3b..c81544cbdb 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2065,7 +2065,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Having nodes spanning across frame boundaries will break the current bookkeeping mechanism. We need to prevent that. QList frameBoundaries; frameBoundaries.reserve(frames.size()); - Q_FOREACH (QTextFrame *frame, frames) + for (QTextFrame *frame : qAsConst(frames)) frameBoundaries.append(frame->firstPosition()); std::sort(frameBoundaries.begin(), frameBoundaries.end()); @@ -2499,7 +2499,7 @@ void QQuickTextEdit::updateWholeDocument() { Q_D(QQuickTextEdit); if (!d->textNodeMap.isEmpty()) { - Q_FOREACH (TextNode* node, d->textNodeMap) + for (TextNode* node : qAsConst(d->textNodeMap)) node->setDirty(); } diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 8b74d26576..d79d8ba3cd 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -264,8 +264,8 @@ void QQuickView::setContent(const QUrl& url, QQmlComponent *component, QObject* d->component = component; if (d->component && d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } @@ -475,8 +475,8 @@ void QQuickView::continueExecute() disconnect(d->component, SIGNAL(statusChanged(QQmlComponent::Status)), this, SLOT(continueExecute())); if (d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } @@ -487,8 +487,8 @@ void QQuickView::continueExecute() QObject *obj = d->component->create(); if (d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp index c36adf56ec..9a50250ebb 100644 --- a/src/quick/qtquick2.cpp +++ b/src/quick/qtquick2.cpp @@ -133,7 +133,7 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, typedef QPointer QuickStatePointer; QObject *object = property.object(); QString propertyName = property.name(); - foreach (const QuickStatePointer& statePointer, m_allStates) { + for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) { if (QQuickState *state = statePointer.data()) { // here we assume that the revert list on itself defines the base state if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 42a4c4abd3..4bec7b19f4 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -67,9 +67,9 @@ void qsg_set_material_failure() #ifndef QT_NO_OPENGL const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const { - QStringList files = m_sourceFiles[type]; + const QStringList files = m_sourceFiles[type]; QSGShaderSourceBuilder builder; - Q_FOREACH (const QString &file, files) + for (const QString &file : files) builder.appendSourceFile(file); m_sources[type] = builder.source(); return m_sources[type].constData(); diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index d782f9309f..206b92eb81 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -2643,7 +2643,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA } if (!successfullyCreatedDefaultProperty) { - foreach (const QString &errorMessage, errorMessages) + for (const QString &errorMessage : qAsConst(errorMessages)) qmlInfo(this) << errorMessage; } } diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index eb902b2972..6d8167413e 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -69,14 +69,14 @@ QQuickAnimatorController::~QQuickAnimatorController() { // The proxy job might already have been deleted, in which case we // need to avoid calling functions on them. Then delete the job. - foreach (QAbstractAnimationJob *job, m_deleting) { + for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { m_starting.take(job); m_stopping.take(job); m_animatorRoots.take(job); delete job; } - foreach (QQuickAnimatorProxyJob *proxy, m_animatorRoots) + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_animatorRoots)) proxy->controllerWasDeleted(); for (auto it = m_animatorRoots.keyBegin(), end = m_animatorRoots.keyEnd(); it != end; ++it) delete *it; @@ -171,7 +171,7 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC void QQuickAnimatorController::beforeNodeSync() { - foreach (QAbstractAnimationJob *job, m_deleting) { + for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { m_starting.take(job); m_stopping.take(job); m_animatorRoots.take(job); @@ -182,7 +182,7 @@ void QQuickAnimatorController::beforeNodeSync() if (m_starting.size()) m_window->update(); - foreach (QQuickAnimatorProxyJob *proxy, m_starting) { + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_starting)) { QAbstractAnimationJob *job = proxy->job(); job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); qquick_initialize_helper(job, this, true); @@ -192,7 +192,7 @@ void QQuickAnimatorController::beforeNodeSync() } m_starting.clear(); - foreach (QQuickAnimatorProxyJob *proxy, m_stopping) { + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_stopping)) { QAbstractAnimationJob *job = proxy->job(); job->stop(); } @@ -208,7 +208,7 @@ void QQuickAnimatorController::beforeNodeSync() m_nodesAreInvalid = false; } - foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { + for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { if (!job->target()) continue; else if (m_deletedSinceLastFrame.contains(job->target())) @@ -218,7 +218,7 @@ void QQuickAnimatorController::beforeNodeSync() xform->transformHelper()->sync(); } } - foreach (QQuickItem *wiped, m_deletedSinceLastFrame) { + for (QQuickItem *wiped : qAsConst(m_deletedSinceLastFrame)) { QQuickTransformAnimatorJob::Helper *helper = m_transforms.take(wiped); // Helper will now already have been reset in all animators referencing it. delete helper; @@ -229,7 +229,7 @@ void QQuickAnimatorController::beforeNodeSync() void QQuickAnimatorController::afterNodeSync() { - foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { + for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { if (job->target()) job->afterNodeSync(); } @@ -249,10 +249,10 @@ void QQuickAnimatorController::stopProxyJobs() // to be outside the lock. It is also safe because deletion of // proxies happens on the GUI thread, where this code is also executing. lock(); - QSet jobs = m_proxiesToStop; + const QSet jobs = m_proxiesToStop; m_proxiesToStop.clear(); unlock(); - foreach (QQuickAnimatorProxyJob *p, jobs) + for (QQuickAnimatorProxyJob *p : jobs) p->stop(); } diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index dfed4c1885..25a4433a9b 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -358,7 +358,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en bool usesPercent = false; int index = 0; - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) { if (QQuickCurve *curve = qobject_cast(pathElement)) { QQuickPathData data; data.index = index; @@ -432,17 +432,17 @@ void QQuickPath::classBegin() void QQuickPath::disconnectPathElements() { - Q_D(QQuickPath); + Q_D(const QQuickPath); - foreach (QQuickPathElement *pathElement, d->_pathElements) + for (QQuickPathElement *pathElement : d->_pathElements) disconnect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); } void QQuickPath::connectPathElements() { - Q_D(QQuickPath); + Q_D(const QQuickPath); - foreach (QQuickPathElement *pathElement, d->_pathElements) + for (QQuickPathElement *pathElement : d->_pathElements) connect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); } @@ -453,7 +453,7 @@ void QQuickPath::gatherAttributes() QSet attributes; // First gather up all the attributes - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) { if (QQuickCurve *curve = qobject_cast(pathElement)) d->_pathCurves.append(curve); else if (QQuickPathAttribute *attribute = qobject_cast(pathElement)) @@ -488,7 +488,7 @@ QStringList QQuickPath::attributes() const QSet attrs; // First gather up all the attributes - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : d->_pathElements) { if (QQuickPathAttribute *attribute = qobject_cast(pathElement)) attrs.insert(attribute->name()); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 49956de822..9722bf544b 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -448,7 +448,7 @@ QQuickPixmapReader::~QQuickPixmapReader() mutex.lock(); // manually cancel all outstanding jobs. - foreach (QQuickPixmapReply *reply, jobs) { + for (QQuickPixmapReply *reply : qAsConst(jobs)) { if (reply->data && reply->data->reply == reply) reply->data->reply = 0; delete reply; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 555533a44e..37a910876e 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -256,7 +256,7 @@ void QQuickPropertyChangesPrivate::decode() if (decoded) return; - foreach (const QV4::CompiledData::Binding *binding, bindings) + for (const QV4::CompiledData::Binding *binding : qAsConst(bindings)) decodeBinding(QString(), compilationUnit->data, binding); bindings.clear(); diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 947a5b6e4e..2d3934cce8 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -334,7 +334,7 @@ QQuickStatePrivate::generateActionList() const } } - foreach(QQuickStateOperation *op, operations) + for (QQuickStateOperation *op : operations) applyList << op->actions(); inState = false; @@ -676,7 +676,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) #ifndef QT_NO_DEBUG_STREAM // Output for debugging if (stateChangeDebug()) { - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) qWarning() << " QQuickStateAction event:" << action.event->type(); else diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 60f710549b..714e6d62b6 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -106,7 +106,7 @@ void QQuickTransitionManager::complete() void QQuickTransitionManagerPrivate::applyBindings() { - foreach(const QQuickStateAction &action, bindingsList) { + for (const QQuickStateAction &action : qAsConst(bindingsList)) { if (action.toBinding) { QQmlPropertyPrivate::setBinding(action.toBinding.data()); } else if (action.event) { @@ -133,7 +133,7 @@ void QQuickTransitionManager::transition(const QList &list, QQuickStateOperation::ActionList applyList = list; // Determine which actions are binding changes and disable any current bindings - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.toBinding) d->bindingsList << action; if (action.fromBinding) @@ -184,7 +184,7 @@ void QQuickTransitionManager::transition(const QList &list, } // Revert back to the original values - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) { if (action.event->isReversable()) { action.event->clearBindings(); @@ -239,7 +239,7 @@ void QQuickTransitionManager::transition(const QList &list, // be applied immediately. We skip applying bindings, as they are all // applied at the end in applyBindings() to avoid any nastiness mid // transition - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event && !action.event->changesBindings()) { if (action.event->isReversable() && action.reverseEvent) action.event->reverse(); @@ -251,7 +251,7 @@ void QQuickTransitionManager::transition(const QList &list, } #ifndef QT_NO_DEBUG_STREAM if (stateChangeDebug()) { - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) qWarning() << " No transition for event:" << action.event->type(); else -- cgit v1.2.3 From 2a4f543ca2b0f90262184fa97f9c386737ec6dd1 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 17 Aug 2016 14:58:40 +0200 Subject: QML: Do not register dependencies of deleted binding Because it can lead to a use-after-free. Change-Id: I6701b370c0ecee4967e5f749f673a6f9ee3d504c Reviewed-by: Simon Hausmann --- src/qml/qml/qqmljavascriptexpression.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 5938ebf5d7..cd2f120218 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -296,7 +296,7 @@ void QQmlPropertyCapture::registerQmlDependencies(QV4::ExecutionEngine *engine, if (!ep) return; QQmlPropertyCapture *capture = ep->propertyCapture; - if (!capture) + if (!capture || capture->watcher->wasDeleted()) return; QV4::Scope scope(engine); -- cgit v1.2.3 From 32a980a86257021247a742b2b8c0b4aafe6e9035 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 17 Aug 2016 11:02:28 +0200 Subject: Revert "localstorage: disable warning about tautological comparison" After 12c7f22, the comparison should now be done at compile time. This reverts commit a858ce0039cb63a6a0afdfabab80ad4adc98ce17. Task-number: QTBUG-53373 Change-Id: I79d2c8aaabba8a2676df6da64206fefc9cdef3b2 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/imports/localstorage/plugin.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index fbcb6ddea5..a043af6b46 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -149,12 +149,7 @@ public: using namespace QV4; -QT_WARNING_PUSH -#if (Q_CC_GNU >= 600) -QT_WARNING_DISABLE_GCC("-Wtautological-compare") -#endif DEFINE_OBJECT_VTABLE(QV4::QQmlSqlDatabaseWrapper); -QT_WARNING_POP -- cgit v1.2.3 From b5f9c1e6e7f3a6881874e4ec2f43cea68107a06b Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 8 Aug 2016 11:58:30 +0200 Subject: QML: Remove hasAccessors flag from QQmlPropertyRawData We can now always check if the pointer is null (no accessors) or not. Change-Id: Ie9abf2f8930ea1f75a6d637a47f7f9c4fbab1151 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlpropertycache.cpp | 1 - src/qml/qml/qqmlpropertycache_p.h | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 7cb1425725..5c53e342f3 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -678,7 +678,6 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, Q_ASSERT(accessorProperty == 0 || (old == 0 && data->revision() == 0)); if (accessorProperty) { - data->_flags.hasAccessors = true; data->setAccessors(accessorProperty->accessors); } else if (old) { data->markAsOverrideOf(old); diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 480f1dcf40..63a9c63d90 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -108,7 +108,6 @@ public: unsigned isFinal : 1; // Has FINAL flag unsigned isOverridden : 1; // Is overridden by a extension property unsigned isDirect : 1; // Exists on a C++ QMetaObject - unsigned hasAccessors : 1; // Has property accessors unsigned type : 4; // stores an entry of Types @@ -127,7 +126,7 @@ public: unsigned notFullyResolved : 1; // True if the type data is to be lazily resolved unsigned overrideIndexIsProperty: 1; - unsigned _padding : 9; // align to 32 bits + unsigned _padding : 10; // align to 32 bits inline Flags(); inline bool operator==(const Flags &other) const; @@ -147,7 +146,7 @@ public: bool isFinal() const { return _flags.isFinal; } bool isOverridden() const { return _flags.isOverridden; } bool isDirect() const { return _flags.isDirect; } - bool hasAccessors() const { return _flags.hasAccessors; } + bool hasAccessors() const { return accessors() != nullptr; } bool isFunction() const { return _flags.type == Flags::FunctionType; } bool isQObject() const { return _flags.type == Flags::QObjectDerivedType; } bool isEnum() const { return _flags.type == Flags::EnumType; } @@ -576,7 +575,6 @@ QQmlPropertyRawData::Flags::Flags() , isFinal(false) , isOverridden(false) , isDirect(false) - , hasAccessors(false) , type(OtherType) , isVMEFunction(false) , hasArguments(false) @@ -600,7 +598,6 @@ bool QQmlPropertyRawData::Flags::operator==(const QQmlPropertyRawData::Flags &ot isAlias == other.isAlias && isFinal == other.isFinal && isOverridden == other.isOverridden && - hasAccessors == other.hasAccessors && type == other.type && isVMEFunction == other.isVMEFunction && hasArguments == other.hasArguments && -- cgit v1.2.3 From 96bd2337a98c892b5def555163c491507dce7185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Wed, 21 Oct 2015 22:13:19 +0300 Subject: Flickable: Fixed rounding errors with contentX/Y contentX/Y are qreals, but they are rounded using qRound/qFloor/qCeil which will limit the values to 2^31 needlessly. This fix will use (std::)round, std::floor and std::ceil instead to allow bigger values for contentX and contentY. Change-Id: I35ad4bcfa3b8bbc21e90768d348d3002ca400081 Task-number: QTBUG-48018 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 31581c0f07..0333f6b9bd 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -55,6 +55,8 @@ #include #include "qplatformdefs.h" +#include + QT_BEGIN_NAMESPACE // FlickThreshold determines how far the "mouse" must have moved @@ -69,6 +71,21 @@ static const int RetainGrabVelocity = 100; static const int MovementEndingTimerInterval = 100; #endif +// Currently std::round can't be used on Android when using ndk g++, so +// use C version instead. We could just define two versions of Round, one +// for float and one for double, but then only one of them would be used +// and compiler would trigger a warning about unused function. +// +// See https://code.google.com/p/android/issues/detail?id=54418 +template +static T Round(T t) { + return round(t); +} +template<> +Q_DECL_UNUSED float Round(float f) { + return roundf(f); +} + static qreal EaseOvershoot(qreal t) { return qAtan(t); } @@ -351,7 +368,7 @@ bool QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExt qreal dist = v2 / (accel * 2.0); if (v > 0) dist = -dist; - qreal target = -qRound(-(data.move.value() - dist)); + qreal target = -Round(-(data.move.value() - dist)); dist = -target + data.move.value(); accel = v2 / (2.0f * qAbs(dist)); @@ -455,18 +472,18 @@ void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExt } else if (data.move.value() <= maxExtent) { resetTimeline(data); adjustContentPos(data, maxExtent); - } else if (-qRound(-data.move.value()) != data.move.value()) { + } else if (-Round(-data.move.value()) != data.move.value()) { // We could animate, but since it is less than 0.5 pixel it's probably not worthwhile. resetTimeline(data); qreal val = data.move.value(); - if (qAbs(-qRound(-val) - val) < 0.25) // round small differences - val = -qRound(-val); + if (std::abs(-Round(-val) - val) < 0.25) // round small differences + val = -Round(-val); else if (data.smoothVelocity.value() > 0) // continue direction of motion for larger - val = -qFloor(-val); + val = -std::floor(-val); else if (data.smoothVelocity.value() < 0) - val = -qCeil(-val); + val = -std::ceil(-val); else // otherwise round - val = -qRound(-val); + val = -Round(-val); timeline.set(data.move, val); } data.inOvershoot = false; @@ -1553,12 +1570,12 @@ void QQuickFlickablePrivate::replayDelayedPress() //XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned. void QQuickFlickablePrivate::setViewportX(qreal x) { - contentItem->setX(pixelAligned ? -qRound(-x) : x); + contentItem->setX(pixelAligned ? -Round(-x) : x); } void QQuickFlickablePrivate::setViewportY(qreal y) { - contentItem->setY(pixelAligned ? -qRound(-y) : y); + contentItem->setY(pixelAligned ? -Round(-y) : y); } void QQuickFlickable::timerEvent(QTimerEvent *event) -- cgit v1.2.3 From 4a9635b0bfdc6a189375bc48e68b00bd05e15c82 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Wed, 10 Aug 2016 15:49:43 +0200 Subject: Remove some double-meaning text from documentation Change-Id: I9b69dbe929947795bdfbff4e0e3a16a47fa94197 Reviewed-by: Simon Hausmann --- src/qml/doc/src/cppintegration/exposecppattributes.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc index c7e4930bfb..f5aea0b01a 100644 --- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -73,7 +73,7 @@ convert them as appropriately when used from QML. Additionally, C++ classes that are \l{Registering C++ types with the QML type system}{registered} with the QML type system can be can be used as data types, as can their enums if appropriately registered. See \l{qtqml-cppintegration-data.html}{Data Type -Conversion Between QML and C++} for details for further information. +Conversion Between QML and C++} for further information. Additionally, data ownership rules are taken into consideration when data is transferred from C++ to QML. See \l {Data Ownership} for more details. -- cgit v1.2.3 From 79cdb4bd45944cce9bb389bebf49917775898ca2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 18 Aug 2016 16:08:54 +0200 Subject: Remove unused delete watcher class Change-Id: I8ccb3ae9029d17dcb4d60239d225393b1da88993 Reviewed-by: Erik Verbruggen --- src/qml/qml/ftw/ftw.pri | 1 - src/qml/qml/ftw/qdeletewatcher_p.h | 111 ------------------------------------- src/qml/qml/qqmlexpression_p.h | 1 - 3 files changed, 113 deletions(-) delete mode 100644 src/qml/qml/ftw/qdeletewatcher_p.h (limited to 'src') diff --git a/src/qml/qml/ftw/ftw.pri b/src/qml/qml/ftw/ftw.pri index 2d4a82e2f4..bb2374d1fa 100644 --- a/src/qml/qml/ftw/ftw.pri +++ b/src/qml/qml/ftw/ftw.pri @@ -8,7 +8,6 @@ HEADERS += \ $$PWD/qqmlthread_p.h \ $$PWD/qfinitestack_p.h \ $$PWD/qrecursionwatcher_p.h \ - $$PWD/qdeletewatcher_p.h \ $$PWD/qrecyclepool_p.h \ $$PWD/qflagpointer_p.h \ $$PWD/qlazilyallocated_p.h \ diff --git a/src/qml/qml/ftw/qdeletewatcher_p.h b/src/qml/qml/ftw/qdeletewatcher_p.h deleted file mode 100644 index d4c0c6dfb2..0000000000 --- a/src/qml/qml/ftw/qdeletewatcher_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDELETEWATCHER_P_H -#define QDELETEWATCHER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QDeleteWatchable -{ -public: - inline QDeleteWatchable(); - inline ~QDeleteWatchable(); -private: - friend class QDeleteWatcher; - bool *_w; -}; - -class QDeleteWatcher { -public: - inline QDeleteWatcher(QDeleteWatchable *data); - inline ~QDeleteWatcher(); - inline bool wasDeleted() const; -private: - void *operator new(size_t); - bool *_w; - bool _s; - QDeleteWatchable *m_d; -}; - -QDeleteWatchable::QDeleteWatchable() -: _w(0) -{ -} - -QDeleteWatchable::~QDeleteWatchable() -{ - if (_w) *_w = true; -} - -QDeleteWatcher::QDeleteWatcher(QDeleteWatchable *data) -: _s(false), m_d(data) -{ - if (!m_d->_w) - m_d->_w = &_s; - _w = m_d->_w; -} - -QDeleteWatcher::~QDeleteWatcher() -{ - if (false == *_w && &_s == m_d->_w) - m_d->_w = 0; -} - -bool QDeleteWatcher::wasDeleted() const -{ - return *_w; -} - -QT_END_NAMESPACE - -#endif // QDELETEWATCHER_P_H diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 741c25e206..809a57b169 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -56,7 +56,6 @@ #include #include #include -#include #include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From be846890f3b34343c139baa99e10d0f9a25fcea3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 Aug 2016 09:31:50 +0200 Subject: Adjust decarative after qtConfig changes in qtbase Most of the changes are optional, but cleanup our QT_CONFIG usage. Change-Id: I5253d53f72f6fb03c2cfedae1e17d94f424a6bbb Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/imports/imports.pro | 6 ++---- src/qml/qml/ftw/ftw.pri | 2 +- src/quick/items/items.pri | 2 +- src/quick/quick.pro | 2 +- src/quick/scenegraph/scenegraph.pri | 10 ++++------ src/src.pro | 3 +-- 6 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 9e3cdf3f42..affc1db2c0 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -16,10 +16,8 @@ qtHaveModule(quick) { window \ testlib - contains(QT_CONFIG, opengl(es1|es2)?) { - SUBDIRS += \ - particles - } + qtConfig(opengl(es1|es2)?): \ + SUBDIRS += particles } qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel diff --git a/src/qml/qml/ftw/ftw.pri b/src/qml/qml/ftw/ftw.pri index bb2374d1fa..87d80d04bc 100644 --- a/src/qml/qml/ftw/ftw.pri +++ b/src/qml/qml/ftw/ftw.pri @@ -21,4 +21,4 @@ SOURCES += \ # mirrors logic in $$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri # clock_gettime() is implemented in librt on these systems -contains(QT_CONFIG, clock-gettime):linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt +qtConfig(clock-gettime):linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index beaf3540bc..d91705451e 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -147,7 +147,7 @@ SOURCES += \ $$PWD/qquickanimatedsprite.cpp # Items that depend on OpenGL Renderer -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SOURCES += \ $$PWD/qquickopenglinfo.cpp \ $$PWD/qquickopenglshadereffect.cpp \ diff --git a/src/quick/quick.pro b/src/quick/quick.pro index f74a554aa9..4909f7fce8 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -33,7 +33,7 @@ include(util/util.pri) include(scenegraph/scenegraph.pri) include(items/items.pri) include(designer/designer.pri) -contains(QT_CONFIG, accessibility) { +qtConfig(accessibility) { include(accessible/accessible.pri) } diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 4ef8b0f638..a659ca5e10 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -1,5 +1,3 @@ -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # DEFINES += QSG_SEPARATE_INDEX_BUFFER # DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG @@ -29,7 +27,7 @@ SOURCES += \ $$PWD/coreapi/qsgrendernode.cpp \ $$PWD/coreapi/qsgrendererinterface.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { HEADERS += \ $$PWD/coreapi/qsgbatchrenderer_p.h SOURCES += \ @@ -73,7 +71,7 @@ SOURCES += \ $$PWD/util/qsgimagenode.cpp \ $$PWD/util/qsgninepatchnode.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { HEADERS += \ $$PWD/util/qsgdepthstencilbuffer_p.h \ $$PWD/util/qsgshadersourcebuilder_p.h \ @@ -104,7 +102,7 @@ SOURCES += \ $$PWD/qsgbasicglyphnode.cpp \ $$PWD/qsgrenderloop.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SOURCES += \ $$PWD/qsgdefaultglyphnode.cpp \ $$PWD/qsgdefaultglyphnode_p.cpp \ @@ -150,7 +148,7 @@ RESOURCES += \ $$PWD/scenegraph.qrc # OpenGL Shaders -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { OTHER_FILES += \ $$PWD/shaders/24bittextmask.frag \ $$PWD/shaders/8bittextmask.frag \ diff --git a/src/src.pro b/src/src.pro index fbc4feaec4..fc1cea67cd 100644 --- a/src/src.pro +++ b/src/src.pro @@ -5,9 +5,8 @@ SUBDIRS += \ quick \ qmltest -qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { +qtHaveModule(gui):qtConfig(opengl(es1|es2)?): \ SUBDIRS += particles -} qtHaveModule(gui): qtHaveModule(widgets): SUBDIRS += quickwidgets -- cgit v1.2.3 From 01a9c006b0cb3f9ec7c140d25e6bfa3ca6250a4c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 19 Aug 2016 10:01:30 +0200 Subject: TestCase::mouseDrag: set mouse move delay >= 1 ms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Infinite-speed drags do not work well with velocity-sensitive components like Flickable. As with change d04982dc on qtbase, adding a short delay helps to stabilize tests. To keep it flexible, we make QTest::defaultMouseDelay() available via the qtest_events.defaultMouseDelay property. So the delay can be increased by passing a larger delay value to mouseDrag, or by changing the QTEST_MOUSEEVENT_DELAY environment variable (as before). Task-number: QTBUG-55382 Change-Id: I8f8088758a206be104a439ee0d1832eeca574e8c Reviewed-by: Liang Qi Reviewed-by: Jan Arve Sæther --- src/imports/testlib/TestCase.qml | 9 +++++---- src/qmltest/quicktestevent.cpp | 13 +++++++++---- src/qmltest/quicktestevent_p.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index c736a1a93a..46a395308d 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -1047,6 +1047,7 @@ Item { modifiers = Qt.NoModifier if (delay == undefined) delay = -1 + var moveDelay = Math.max(1, delay === -1 ? qtest_events.defaultMouseDelay : delay) // Divide dx and dy to have intermediate mouseMove while dragging // Fractions of dx/dy need be superior to the dragThreshold @@ -1060,12 +1061,12 @@ Item { mousePress(item, x, y, button, modifiers, delay) //trigger dragging - mouseMove(item, x + util.dragThreshold + 1, y + util.dragThreshold + 1, delay, button) + mouseMove(item, x + util.dragThreshold + 1, y + util.dragThreshold + 1, moveDelay, button) if (ddx > 0 || ddy > 0) { - mouseMove(item, x + ddx, y + ddy, delay, button) - mouseMove(item, x + 2*ddx, y + 2*ddy, delay, button) + mouseMove(item, x + ddx, y + ddy, moveDelay, button) + mouseMove(item, x + 2*ddx, y + 2*ddy, moveDelay, button) } - mouseMove(item, x + dx, y + dy, delay, button) + mouseMove(item, x + dx, y + dy, moveDelay, button) mouseRelease(item, x + dx, y + dy, button, modifiers, delay) } diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp index cfa80c4f19..e71b4f8f54 100644 --- a/src/qmltest/quicktestevent.cpp +++ b/src/qmltest/quicktestevent.cpp @@ -39,6 +39,10 @@ QT_BEGIN_NAMESPACE +namespace QTest { + extern int Q_TESTLIB_EXPORT defaultMouseDelay(); +} + QuickTestEvent::QuickTestEvent(QObject *parent) : QObject(parent) { @@ -48,6 +52,11 @@ QuickTestEvent::~QuickTestEvent() { } +int QuickTestEvent::defaultMouseDelay() const +{ + return QTest::defaultMouseDelay(); +} + bool QuickTestEvent::keyPress(int key, int modifiers, int delay) { QWindow *window = activeWindow(); @@ -105,10 +114,6 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d return true; } -namespace QTest { - extern int Q_TESTLIB_EXPORT defaultMouseDelay(); -}; - namespace QtQuickTest { enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove, MouseDoubleClickSequence }; diff --git a/src/qmltest/quicktestevent_p.h b/src/qmltest/quicktestevent_p.h index 0cba644cba..0a08347db8 100644 --- a/src/qmltest/quicktestevent_p.h +++ b/src/qmltest/quicktestevent_p.h @@ -53,9 +53,11 @@ QT_BEGIN_NAMESPACE class Q_QUICK_TEST_EXPORT QuickTestEvent : public QObject { Q_OBJECT + Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL) public: QuickTestEvent(QObject *parent = 0); ~QuickTestEvent(); + int defaultMouseDelay() const; public Q_SLOTS: bool keyPress(int key, int modifiers, int delay); -- cgit v1.2.3 From bf3b596066af733c04b5ed3ef2dc9ec753a41e79 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 17:21:33 +0300 Subject: QQuickItemView: use reverse iterators more Since qt5.6 we can use reverse iterators. Change-Id: Ibf78b937e793c868ecc40710ef74c25308cc39bf Reviewed-by: Shawn Rutledge --- src/quick/items/qquickitemview.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index fa874d631c..e017d6564a 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1622,12 +1622,10 @@ qreal QQuickItemViewPrivate::contentStartOffset() const int QQuickItemViewPrivate::findLastVisibleIndex(int defaultValue) const { - if (visibleItems.count()) { - int i = visibleItems.count() - 1; - while (i > 0 && visibleItems.at(i)->index == -1) - --i; - if (visibleItems.at(i)->index != -1) - return visibleItems.at(i)->index; + for (auto it = visibleItems.rbegin(), end = visibleItems.rend(); it != end; ++it) { + auto item = *it; + if (item->index != -1) + return item->index; } return defaultValue; } @@ -1658,9 +1656,10 @@ FxViewItem *QQuickItemViewPrivate::firstVisibleItem() const { int QQuickItemViewPrivate::findLastIndexInView() const { const qreal viewEndPos = isContentFlowReversed() ? -position() : position() + size(); - for (int i=visibleItems.count() - 1; i>=0; i--) { - if (visibleItems.at(i)->position() <= viewEndPos && visibleItems.at(i)->index != -1) - return visibleItems.at(i)->index; + for (auto it = visibleItems.rbegin(), end = visibleItems.rend(); it != end; ++it) { + auto item = *it; + if (item->index != -1 && item->position() <= viewEndPos) + return item->index; } return -1; } -- cgit v1.2.3 From 23527754d60780ac4830f1acd6a54d3487a2c362 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 1 Aug 2016 13:39:37 +0200 Subject: Fix crash in tst_qqmlextensionplugin on shutdown On shutdown the test will unload all the plugins it loaded. In the case of the QtQuick2 plugin we only loaded it but never called registerTypes, as the test merely sees if the plugin can be instantiated. Consequently the attempt at unregistering the value type providers will fail because it was previously never defined. Note: We can't just let the QQmlValueTypeProvider destructor take care of the deregistration, as we do not truly unload plugins anymore (thankfully). However the plugin object will be destroyed and along with it we should correctly de-register the things we registered earlier, otherwise when initializing the plugin again, we'll register handers multiple times. Change-Id: Id778890bcd3f1fab16eb312a01de7d423ea3aa22 Reviewed-by: Ulf Hermann --- src/imports/qtquick2/plugin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp index e56027c1bb..d16467a5bb 100644 --- a/src/imports/qtquick2/plugin.cpp +++ b/src/imports/qtquick2/plugin.cpp @@ -61,13 +61,17 @@ public: { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick")); Q_UNUSED(uri); + moduleDefined = true; QQmlQtQuick2Module::defineModule(); } ~QtQuick2Plugin() { - QQmlQtQuick2Module::undefineModule(); + if (moduleDefined) + QQmlQtQuick2Module::undefineModule(); } + + bool moduleDefined = false; }; //![class decl] -- cgit v1.2.3 From 19baf625b984b4fafa28c4fc9bb8e5f8f0390d71 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 15:45:00 +0300 Subject: Imports: replace 'foreach' with 'range for' Change-Id: I283ce40b52de2371550dab7a54cdce89c78cdc68 Reviewed-by: Shawn Rutledge --- src/imports/folderlistmodel/fileinfothread.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp index 5d911eec1e..0b62935f87 100644 --- a/src/imports/folderlistmodel/fileinfothread.cpp +++ b/src/imports/folderlistmodel/fileinfothread.cpp @@ -260,14 +260,13 @@ void FileInfoThread::getFileInfos(const QString &path) sortFlags = sortFlags | QDir::DirsFirst; QDir currentDir(path, QString(), sortFlags); - QFileInfoList fileInfoList; QList filePropertyList; - fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags); + const QFileInfoList fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags); if (!fileInfoList.isEmpty()) { filePropertyList.reserve(fileInfoList.count()); - foreach (const QFileInfo &info, fileInfoList) { + for (const QFileInfo &info : fileInfoList) { //qDebug() << "Adding file : " << info.fileName() << "to list "; filePropertyList << FileProperty(info); } -- cgit v1.2.3 From e923ac48a5bfdef206f6fdf0e194db976f2af8ee Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:28:16 +0300 Subject: Particles: fix incorrect usage of 'range for' with Qt containers Change-Id: Ibe750b068bc8d4c33272a65dafcc398239d7d591 Reviewed-by: Shawn Rutledge --- src/particles/qquickparticlepainter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp index d6303eb219..0c2521cd9e 100644 --- a/src/particles/qquickparticlepainter.cpp +++ b/src/particles/qquickparticlepainter.cpp @@ -103,7 +103,8 @@ void QQuickParticlePainter::recalculateGroupIds() const m_groupIdsNeedRecalculation = false; m_groupIds.clear(); - for (const QString &str : groups()) { + const auto groupList = groups(); + for (const QString &str : groupList) { QQuickParticleGroupData::ID groupId = m_system->groupIds.value(str, QQuickParticleGroupData::InvalidID); if (groupId == QQuickParticleGroupData::InvalidID) { // invalid data, not finished setting up, or whatever. Fallback: do not cache. -- cgit v1.2.3 From cd3380862b312a2d349bb72522f0751622448404 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:23:37 +0300 Subject: QQuickWidget: fix incorrect usage of 'range for' with Qt containers Change-Id: Ifd95a2076c6f5330820dc0eb4890636f83b93794 Reviewed-by: Shawn Rutledge --- src/quickwidgets/qquickwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index b8c5b900c9..c608697c94 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1603,7 +1603,8 @@ void QQuickWidget::paintEvent(QPaintEvent *event) painter.drawImage(rect(), d->softwareImage); } else { //Paint only the updated areas - for (auto targetRect : d->updateRegion.rects()) { + const auto rects = d->updateRegion.rects(); + for (auto targetRect : rects) { auto sourceRect = QRect(targetRect.topLeft() * devicePixelRatio(), targetRect.size() * devicePixelRatio()); painter.drawImage(targetRect, d->softwareImage, sourceRect); } -- cgit v1.2.3 From e9667491d82985f86ff98426b6948a65af94a611 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:03:15 +0300 Subject: Quick: fix incorrect usage of 'range for' with Qt containers Also port remaining foreach to 'range for'. Change-Id: I20296bb3bb6d63f144ebddaba02cabeb16b7d734 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickitem.cpp | 3 ++- src/quick/items/qquickwindow.cpp | 14 ++++++++------ .../adaptations/software/qsgabstractsoftwarerenderer.cpp | 4 +--- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index bb5ed60e68..4c6b0b4167 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -98,7 +98,8 @@ void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1) << item->hasActiveFocus() << item->isFocusScope() << item; - for (QQuickItem *child : item->childItems()) { + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { debugFocusTree( child, item->isFocusScope() || !scope ? item : scope, diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index f958d1a087..a54d6daf9c 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -764,7 +764,8 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector ungrab; for (int i = 0; i < ids.count(); ++i) { // FIXME: deprecate this function, we need a device - for (auto device: QQuickPointerDevice::touchDevices()) { + const auto touchDevices = QQuickPointerDevice::touchDevices(); + for (auto device : touchDevices) { auto point = device->pointerEvent()->pointById(ids.at(i)); if (!point) continue; @@ -783,7 +784,7 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVectortouchUngrabEvent(); } @@ -791,7 +792,8 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to { Q_Q(QQuickWindow); if (Q_LIKELY(touch)) { - for (auto device: QQuickPointerDevice::touchDevices()) { + const auto touchDevices = QQuickPointerDevice::touchDevices(); + for (auto device : touchDevices) { auto pointerEvent = device->pointerEvent(); for (int i = 0; i < pointerEvent->pointCount(); ++i) { if (pointerEvent->point(i)->grabber() == grabber) { @@ -1477,7 +1479,7 @@ bool QQuickWindowPrivate::clearHover(ulong timestamp) QPointF pos = q->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()); bool accepted = false; - foreach (QQuickItem* item, hoverItems) + for (QQuickItem* item : qAsConst(hoverItems)) accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), timestamp, true) || accepted; hoverItems.clear(); return accepted; @@ -2199,9 +2201,9 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) // Deliver touch points to existing grabbers bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet *hasFiltered) { - for (auto grabber: event->grabbers()) { + const auto grabbers = event->grabbers(); + for (auto grabber : grabbers) deliverMatchingPointsToItem(grabber, event, hasFiltered); - } return false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index a6cb99ae05..2ff180ea99 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -67,9 +67,7 @@ QSGAbstractSoftwareRenderer::~QSGAbstractSoftwareRenderer() // Cleanup RenderableNodes delete m_background; - for (QSGSoftwareRenderableNode *node : m_nodes.values()) { - delete node; - } + qDeleteAll(m_nodes); delete m_nodeUpdater; } -- cgit v1.2.3