From 67d783622d7a180da89af4c1fb57c6973e5b4386 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Wed, 28 Dec 2016 10:59:05 +0100 Subject: Removed auto-generated links to internal classes QQmlExtensionInterface and QQmlTypesExtensionInterface are internal classes that are not relevant from an external API perspective, but merely an implementation detail of the plugin loading mechanism in QML. Task-number: QTBUG-57190 Change-Id: I5fdfe26f1b74c4782040aaadd3ee13b9c92153eb Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlextensionplugin.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index ca19691e93..097fa71200 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -117,4 +117,14 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) Q_UNUSED(uri); } +/*! + \class QQmlExtensionInterface + \internal + \inmodule QtQml + + \class QQmlTypesExtensionInterface + \internal + \inmodule QtQml +*/ + QT_END_NAMESPACE -- cgit v1.2.3 From d2eaf438ac44a39aab6ac6ecc23e9ebb39aa58ac Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 22 Dec 2016 12:50:54 +0100 Subject: Get rid of the GCBlocker It's a hack we needed when we still had a conservative GC, but it is not required anymore. The only thing we still need is the protection against running the GC recursively. Change-Id: I55cd51d4929c828db5b61b38e781467c5bf77314 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 2 -- src/qml/jsruntime/qv4script.cpp | 2 -- src/qml/memory/qv4mm.cpp | 10 ---------- src/qml/memory/qv4mm_p.h | 22 ---------------------- 4 files changed, 36 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2b90b43eab..8c4c39b774 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -158,8 +158,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) } Q_ASSERT(maxCallDepth > 0); - MemoryManager::GCBlocker gcBlocker(memoryManager); - if (!factory) { #if QT_CONFIG(qml_interpreter) bool jitDisabled = true; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 5d7df9a9d7..fe8f8474e4 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -88,8 +88,6 @@ void Script::parse() ExecutionEngine *v4 = scope->engine(); Scope valueScope(v4); - MemoryManager::GCBlocker gcBlocker(v4->memoryManager); - IR::Module module(v4->debugger() != 0); QQmlJS::Engine ee, *engine = ⅇ diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 606d3ec162..8732b02685 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -565,16 +565,6 @@ void MemoryManager::sweep(bool lastSweep) } } -bool MemoryManager::isGCBlocked() const -{ - return m_d->gcBlocked; -} - -void MemoryManager::setGCBlocked(bool blockGC) -{ - m_d->gcBlocked = blockGC; -} - void MemoryManager::runGC() { if (m_d->gcBlocked) { diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index dfa0d85dff..86a0ba2735 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -76,26 +76,6 @@ class Q_QML_EXPORT MemoryManager public: struct Data; - class GCBlocker - { - public: - GCBlocker(MemoryManager *mm) - : mm(mm) - , wasBlocked(mm->isGCBlocked()) - { - mm->setGCBlocked(true); - } - - ~GCBlocker() - { - mm->setGCBlocked(wasBlocked); - } - - private: - MemoryManager *mm; - bool wasBlocked; - }; - public: MemoryManager(ExecutionEngine *engine); ~MemoryManager(); @@ -309,8 +289,6 @@ public: return t->d(); } - bool isGCBlocked() const; - void setGCBlocked(bool blockGC); void runGC(); void dumpStats() const; -- cgit v1.2.3 From b2501b0bda6a0bf4f4d5ce19e7efeda236bcbe9a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 21 Nov 2016 13:39:38 +0100 Subject: QQuickWindow flushFrameSynchronousEvents: don't hover if nothing dirty An optimization revising 6f84a09dfbd15aac023580cf06e7b8c24f3b524c Calling hoverMoveEvent every frame is too inefficient when an item subclass is actually doing something there. For example, any QtQuick-based Wayland compositor needs to notify its client windows when hover state changes, so calling this method too often would impose extra work to double-check whether it really changed or not. Change-Id: I98b40a2083700e7a50820bd13154247444249e59 Reviewed-by: Robin Burchell --- src/quick/items/qquickwindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 155a52bd9b..a58912e38f 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2081,11 +2081,12 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents() ut->startAnimations(); } - // Once per frame, send a synthetic hover, in case items have changed position. + // Once per frame, if any items are dirty, send a synthetic hover, + // in case items have changed position, visibility, etc. // For instance, during animation (including the case of a ListView // whose delegates contain MouseAreas), a MouseArea needs to know // whether it has moved into a position where it is now under the cursor. - if (!q->mouseGrabberItem() && !lastMousePosition.isNull()) { + if (!q->mouseGrabberItem() && !lastMousePosition.isNull() && dirtyItemList) { bool accepted = false; bool delivered = deliverHoverEvent(contentItem, lastMousePosition, lastMousePosition, QGuiApplication::keyboardModifiers(), 0, accepted); if (!delivered) -- cgit v1.2.3 From f43dc181d7416eddfafb7493273a371c1eba8b4a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 2 Jan 2017 10:46:38 +0100 Subject: Fix QML cache not being invalidated when source path changes When somebody renames the directory name underneath a QML file and its cache file, then we need to re-generate the cache as it contains the fully path of the source path. That is sometimes used to resolve relative URLs (such as images) and therefore needs updating (by re-creating the cache). Task-number: QTBUG-57644 Change-Id: I9766668859aad8e9d71f278c3f26c0585258c14e Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compileddata.cpp | 5 ++ tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp | 58 ++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 8586c84c3d..6aac111897 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -407,6 +407,11 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr; QScopedValueRollback dataPtrChange(data, mappedUnit); + if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) { + *errorString = QStringLiteral("QML source file has moved to a different location."); + return false; + } + { const QString foundArchitecture = stringAt(data->architectureIndex); const QString expectedArchitecture = QSysInfo::buildAbi(); diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index 8af446173d..b265607fd1 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -53,6 +53,7 @@ private slots: void registerImportForImplicitComponent(); void basicVersionChecks(); void recompileAfterChange(); + void recompileAfterDirectoryChange(); void fileSelectors(); void localAliases(); void cacheResources(); @@ -95,11 +96,17 @@ struct TestCompiler TestCompiler(QQmlEngine *engine) : engine(engine) , tempDir() - , testFilePath(tempDir.path() + QStringLiteral("/test.qml")) - , cacheFilePath(tempDir.path() + QStringLiteral("/test.qmlc")) - , mappedFile(cacheFilePath) , currentMapping(nullptr) { + init(tempDir.path()); + } + + void init(const QString &baseDirectory) + { + closeMapping(); + testFilePath = baseDirectory + QStringLiteral("/test.qml"); + cacheFilePath = baseDirectory + QStringLiteral("/test.qmlc"); + mappedFile.setFileName(cacheFilePath); } bool compile(const QByteArray &contents) @@ -187,8 +194,8 @@ struct TestCompiler QQmlEngine *engine; const QTemporaryDir tempDir; - const QString testFilePath; - const QString cacheFilePath; + QString testFilePath; + QString cacheFilePath; QString lastErrorString; QFile mappedFile; uchar *currentMapping; @@ -441,6 +448,47 @@ void tst_qmldiskcache::recompileAfterChange() } } +void tst_qmldiskcache::recompileAfterDirectoryChange() +{ + QQmlEngine engine; + TestCompiler testCompiler(&engine); + + QVERIFY(testCompiler.tempDir.isValid()); + + QVERIFY(QDir(testCompiler.tempDir.path()).mkdir("source1")); + testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source1")); + + { + const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n" + "QtObject {\n" + " property int blah: 42;\n" + "}"); + + testCompiler.clearCache(); + QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString)); + QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString)); + testCompiler.closeMapping(); + } + + const QDateTime initialCacheTimeStamp = QFileInfo(testCompiler.cacheFilePath).lastModified(); + + QDir(testCompiler.tempDir.path()).rename(QStringLiteral("source1"), QStringLiteral("source2")); + waitForFileSystem(); + + testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source2")); + + { + CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); + QScopedPointer obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("blah").toInt(), 42); + } + + QFile cacheFile(testCompiler.cacheFilePath); + QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName())); + QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp); +} + void tst_qmldiskcache::fileSelectors() { QQmlEngine engine; -- cgit v1.2.3 From fc724dd473cd68fd074ed5f7d849a0b23f99ebd4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 3 Jan 2017 13:26:24 +0100 Subject: Bump version Change-Id: I26e2b01ac6ce30b04509af1413163460e992cb92 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 556f554e5e..9d7f045e45 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += warning_clean -MODULE_VERSION = 5.8.0 +MODULE_VERSION = 5.8.1 -- cgit v1.2.3 From 4406667874b22803ef78650f4af28337eaf7952b Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Wed, 28 Dec 2016 12:06:29 +0100 Subject: Added the missing link to Animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Animator inherits from QQuickAbstractAnimation which is known as Animation in QML. Its properties are inherited. Task-number: QTBUG-55738 Change-Id: If16c87c9367825d7661940e7c1930179862e59cb Reviewed-by: Mitch Curtis Reviewed-by: Topi Reiniö --- src/quick/util/qquickanimator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index 5d2af0f940..c3b5865369 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick \since 5.2 \ingroup qtquick-transitions-animations + \inherits Animation \brief Is the base of all QML animators. Animator types are a special type of animation which operate -- cgit v1.2.3 From 0a88774a0f11bf96a87012ac4a83e31ced19460b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 22 Dec 2016 15:05:56 +0100 Subject: Fix stencil clips with core profile contexts Client-side pointers are not supported. Start using a VBO instead. Task-number: QTBUG-57768 Change-Id: Ia7ac9b0838d837b02e8bf99fcd22f0373cb357c9 Reviewed-by: Gunnar Sletta --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 6db96f369c..4893c175a3 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -2022,6 +2022,8 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) } ClipType clipType = NoClip; + GLuint vbo = 0; + int vboSize = 0; glDisable(GL_SCISSOR_TEST); @@ -2106,7 +2108,21 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) const QSGGeometry *g = clip->geometry(); Q_ASSERT(g->attributeCount() > 0); const QSGGeometry::Attribute *a = g->attributes(); - glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), g->vertexData()); + + if (!vbo) + glGenBuffers(1, &vbo); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + + const int vertexByteSize = g->sizeOfVertex() * g->vertexCount(); + if (vboSize < vertexByteSize) { + vboSize = vertexByteSize; + glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), GL_STATIC_DRAW); + } else { + glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData()); + } + + glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), 0); m_clipProgram.setUniformValue(m_clipMatrixId, m); if (g->indexCount()) { @@ -2115,12 +2131,17 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) glDrawArrays(g->drawingMode(), 0, g->vertexCount()); } + glBindBuffer(GL_ARRAY_BUFFER, 0); + ++m_currentStencilValue; } clip = clip->clipList(); } + if (vbo) + glDeleteBuffers(1, &vbo); + if (clipType & StencilClip) { m_clipProgram.disableAttributeArray(0); glStencilFunc(GL_EQUAL, m_currentStencilValue, 0xff); // stencil test, ref, test mask -- cgit v1.2.3 From 0d2db1438e3f7e07f768991a39d4f6b2ab1dc432 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Wed, 28 Dec 2016 20:40:28 +0100 Subject: Added documentation for the GroupSwitchModifier Used the default sentence from Qt::KeyboardModifier. Task-number: QTBUG-53211 Change-Id: If763ca1b8d9ee7dcfa511f3a19dd012aac4d4f9c Reviewed-by: Robin Burchell --- src/quick/items/qquickevents.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index a5497f4627..70d95ccdf8 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -137,6 +137,7 @@ Item { \li Qt.AltModifier - An Alt key on the keyboard is pressed. \li Qt.MetaModifier - A Meta key on the keyboard is pressed. \li Qt.KeypadModifier - A keypad button is pressed. + \li Qt.GroupSwitchModifier - X11 only. A Mode_switch key on the keyboard is pressed. \endlist For example, to react to a Shift key + Enter key combination: -- cgit v1.2.3 From e62fde84e2fac321386c6fbb6fb90a36c0989a3d Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Wed, 28 Dec 2016 21:52:24 +0100 Subject: Clarified that QQmlListProperty can only be used for lists of QObject-derived object pointers Added the info to the QQmlListProperty's brief itself so it stands out. Removed the original note. Also added a See also link to the complete example. Task-number: QTBUG-37888 Change-Id: I9e1b77b035321ade44fe57d56e68a9c3d20cb879 Reviewed-by: Mitch Curtis --- src/qml/qml/qqmllist.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp index a719956483..edd93ef03d 100644 --- a/src/qml/qml/qqmllist.cpp +++ b/src/qml/qml/qqmllist.cpp @@ -335,7 +335,7 @@ int QQmlListReference::count() const \since 5.0 \inmodule QtQml \brief The QQmlListProperty class allows applications to expose list-like -properties to QML. +properties of QObject-derived classes to QML. QML has many list properties, where more than one object value can be assigned. The use of a list property from QML looks like this: @@ -369,7 +369,8 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty. -\note QQmlListProperty can only be used for lists of QObject-derived object pointers. +\sa {Extending QML - Object and List Property Types Example} + */ /*! -- cgit v1.2.3 From 321726cb5e87be1969f22a0eef4166ba36344329 Mon Sep 17 00:00:00 2001 From: Jacques GUILLOU Date: Wed, 4 Jan 2017 14:31:29 +0100 Subject: qmlplugindump : Add a "-output" argument to specify the output file Having only the possibility to redirect the stdout of qmlplugindump to a file is both unconvenient and unreliable since some plugins might write content (such as logs) to stdout, which pollute the output. Change-Id: I8b1d482d7674945e6145d59aea839c54600e7784 Reviewed-by: Marco Benelli --- tools/qmlplugindump/main.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 883afa057c..443ede4bf0 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -739,7 +739,7 @@ void sigSegvHandler(int) { void printUsage(const QString &appName) { std::cerr << qPrintable(QString( - "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies ] [-merge ] [-noforceqtquick] module.uri version [module/import/path]\n" + "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies ] [-merge ] [-output ] [-noforceqtquick] module.uri version [module/import/path]\n" " %1 [-v] [-noinstantiate] -path path/to/qmldir/directory [version]\n" " %1 [-v] -builtins\n" "Example: %1 Qt.labs.folderlistmodel 2.0 /home/user/dev/qt-install/imports").arg( @@ -994,6 +994,7 @@ int main(int argc, char *argv[]) return EXIT_INVALIDARGUMENTS; } + QString outputFilename; QString pluginImportUri; QString pluginImportVersion; bool relocatable = true; @@ -1047,6 +1048,13 @@ int main(int argc, char *argv[]) } else if (arg == QLatin1String("--noforceqtquick") || arg == QLatin1String("-noforceqtquick")){ forceQtQuickDependency = false; + } else if (arg == QLatin1String("--output") + || arg == QLatin1String("-output")) { + if (++iArg == args.size()) { + std::cerr << "missing output file" << std::endl; + return EXIT_INVALIDARGUMENTS; + } + outputFilename = args.at(iArg); } else if (arg == QLatin1String("--defaultplatform") || arg == QLatin1String("-defaultplatform")) { continue; @@ -1300,7 +1308,15 @@ int main(int argc, char *argv[]) qml.writeEndObject(); qml.writeEndDocument(); - std::cout << bytes.constData() << std::flush; + if (!outputFilename.isEmpty()) { + QFile file(outputFilename); + if (file.open(QIODevice::WriteOnly)) { + QTextStream stream(&file); + stream << bytes.constData(); + } + } else { + std::cout << bytes.constData() << std::flush; + } // workaround to avoid crashes on exit QTimer timer; -- cgit v1.2.3 From 11aef4eec22cac62d7728ee2895efe4cc80cd335 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Wed, 28 Dec 2016 21:22:13 +0100 Subject: Clarify MouseArea's onClicked and onPressAndHold documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changing the accepted property within the onClicked and onPressAndHold event handlers only have an effect if the propagateComposedEvents property is true. Task-number: QTBUG-46912 Change-Id: I66a9114f6dafdf79a5fbf1278656c2988ffb42a2 Reviewed-by: Tor Arne Vestbø --- src/quick/items/qquickmousearea.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index 5e30bf9e0a..3160495332 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -340,7 +340,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i position of the release of the click, and whether the click was held. When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse - parameter has no effect. + parameter has no effect, unless the \l propagateComposedEvents property is \c true. The corresponding handler is \c onClicked. */ @@ -384,7 +384,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i position of the press, and which button is pressed. When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse - parameter has no effect. + parameter has no effect, unless the \l propagateComposedEvents property is \c true. The corresponding handler is \c onPressAndHold. */ -- cgit v1.2.3 From 27ea28b0f451076e773f9dc78babfdd799c3e0d8 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 16 Dec 2016 13:14:01 +0100 Subject: Doc: Rearranged order of Extending QML Examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rearranged in logical order of example build up Change-Id: I6af8e39bd900d4ce058de46e0b3ebd5e368222c8 Reviewed-by: Topi Reiniö --- examples/qml/doc/src/qml-extending.qdoc | 19 ++++++++++--- examples/qml/referenceexamples/extended/main.cpp | 4 +++ src/qml/doc/src/examples.qdoc | 36 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc index 0812a3dba1..0cb004be7d 100644 --- a/examples/qml/doc/src/qml-extending.qdoc +++ b/examples/qml/doc/src/qml-extending.qdoc @@ -75,9 +75,21 @@ This example builds on: Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an \l {Registering Extension Objects}{extension object} to a \l QLineEdit without modifying or -subclassing. The QML engine instantiates a \l QLineEdit and sets a property that -only exists on the extension type. The extension type performs calls on the \l -QLineEdit that otherwise will not be accessible to the QML engine. +subclassing. + +\snippet referenceexamples/extended/main.cpp 0 + +The QML engine instantiates a \l QLineEdit + +\snippet referenceexamples/extended/main.cpp 1 + +and sets a property that oly exists on the extension type. + +\snippet referenceexamples/extended/example.qml 0 + +The QML engine instantiates a \l QLineEdit and sets a property that +only exists on the extension type. The extension type performs calls on the +\l QLineEdit that otherwise will not be accessible to the QML engine. */ @@ -293,7 +305,6 @@ This example builds on: This example builds on: \list -\li \l {Extending QML - Default Property Example} \li \l {Extending QML - Inheritance and Coercion Example} \li \l {Extending QML - Object and List Property Types Example} \li \l {Extending QML - Adding Types Example} diff --git a/examples/qml/referenceexamples/extended/main.cpp b/examples/qml/referenceexamples/extended/main.cpp index fc11587841..f72cb0d9e2 100644 --- a/examples/qml/referenceexamples/extended/main.cpp +++ b/examples/qml/referenceexamples/extended/main.cpp @@ -48,11 +48,15 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); +// ![0] qmlRegisterExtendedType("People", 1,0, "QLineEdit"); +// ![0] +// ![1] QQmlEngine engine; QQmlComponent component(&engine, QUrl("qrc:example.qml")); QLineEdit *edit = qobject_cast(component.create()); +// ![1] if (edit) { edit->show(); diff --git a/src/qml/doc/src/examples.qdoc b/src/qml/doc/src/examples.qdoc index f3550ae199..4f12d42f48 100644 --- a/src/qml/doc/src/examples.qdoc +++ b/src/qml/doc/src/examples.qdoc @@ -32,4 +32,40 @@ The list of examples demonstrating how to extend C++ to QML or the other way around. + +\noautolist + +\table + \row + \li \l {Extending QML - Adding Types Example} + \li Exporting C++ Classes + \row + \li \l {Extending QML - Object and List Property Types Example} + \li Exporting C++ Properties + \row + \li \l {Extending QML - Extension Objects Example} + \li Extension Objects + \row + \li \l {Extending QML - Inheritance and Coercion Example} + \li C++ Inheritance and Coercion + \row + \li \l {Extending QML - Methods Example} + \li Methods Support + \row + \li \l {Extending QML - Attached Properties Example} + \li Attached Properties + \row + \li \l {Extending QML - Signal Support Example} + \li Signal Support + \row + \li \l {Extending QML - Property Value Source Example} + \li Property Value Source + \row + \li \l {Extending QML - Default Property Example} + \li Default Property + \row + \li \l {Extending QML - Grouped Properties Example} + \li Grouped Properties +\endtable + */ -- cgit v1.2.3 From a0ed2b0ef3f9259f245294c59e6f4695f29caddd Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 21 Dec 2016 14:33:32 +0100 Subject: Doc: added specs to Extending QML - Methods Example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7386c2bd738776455a71bde8cffdcedb9e292b24 Reviewed-by: Venugopal Shivashankar Reviewed-by: Mitch Curtis Reviewed-by: Topi Reiniö --- examples/qml/doc/src/qml-extending.qdoc | 9 +++++++++ examples/qml/referenceexamples/methods/example.qml | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc index 0cb004be7d..b4174426a8 100644 --- a/examples/qml/doc/src/qml-extending.qdoc +++ b/examples/qml/doc/src/qml-extending.qdoc @@ -310,6 +310,15 @@ This example builds on: \li \l {Extending QML - Adding Types Example} \endlist +The Methods Example has an additional method in the \c BirthdayParty class: \c invite(). +\c invite() is declared with \l Q_INVOKABLE so that it can be +called from QML. + +\snippet referenceexamples/methods/birthdayparty.h 0 + +In \c example.qml, the \c invite() method is called in the \l [QML]{QtQml::Component::completed()}{Component.onCompleted} signal handler: + +\snippet referenceexamples/methods/example.qml 0 */ /*! diff --git a/examples/qml/referenceexamples/methods/example.qml b/examples/qml/referenceexamples/methods/example.qml index 58985c5d5f..197e6007e1 100644 --- a/examples/qml/referenceexamples/methods/example.qml +++ b/examples/qml/referenceexamples/methods/example.qml @@ -38,6 +38,7 @@ ** ****************************************************************************/ +// ![0] import QtQuick 2.0 import People 1.0 @@ -52,7 +53,6 @@ BirthdayParty { Person { name: "Anne Brown" } ] -// ![0] Component.onCompleted: invite("William Green") -// ![0] } +// ![0] -- cgit v1.2.3 From 208e118924d648a472dafd18d11f3404e30ad8be Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 9 Jan 2017 15:21:47 +0100 Subject: Fix crash in Canvas The Image based code path will delete the texture in textureForNextFrame() so deleting it again here is wrong. The convention is supposed to be that if the textureForNextFrame returns 0, it also deleted the input texture. So not deleting is correct for both Image and FBO. Change-Id: I45a5ef94c13358f3637f51ae2d21224518ea6a25 Reviewed-by: Laszlo Agocs --- src/quick/items/context2d/qquickcanvasitem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 212148b754..28e9173bf7 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -766,7 +766,6 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (!texture) { delete node; d->node = 0; - delete d->nodeTexture; d->nodeTexture = 0; if (d->textureProvider) { d->textureProvider->tex = 0; -- cgit v1.2.3 From 046d1a092b7b1ce7cb615d5e5e080a1cf8e41e10 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 1 Dec 2016 16:35:05 +0100 Subject: graph example: Fix MSVC warning about truncation of 'double' graph.cpp(105): warning C4305: 'argument': truncation from 'double' to 'float' Change-Id: I644dec9be8aeb1837a2b7402f7ab7c3b3beb7e1b Reviewed-by: Jesus Fernandez Reviewed-by: Shawn Rutledge --- examples/quick/scenegraph/graph/graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/quick/scenegraph/graph/graph.cpp b/examples/quick/scenegraph/graph/graph.cpp index 389bd384c2..6048a1032c 100644 --- a/examples/quick/scenegraph/graph/graph.cpp +++ b/examples/quick/scenegraph/graph/graph.cpp @@ -102,7 +102,7 @@ QSGNode *Graph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) n->background = new NoisyNode(window()); n->grid = new GridNode(); n->line = new LineNode(10, 0.5, QColor("steelblue")); - n->shadow = new LineNode(20, 0.2, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4)); + n->shadow = new LineNode(20, 0.2f, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4)); n->appendChildNode(n->background); n->appendChildNode(n->grid); -- cgit v1.2.3 From 6746db54f2adb40b836ce41101462bc38604749f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 11 Jan 2017 11:44:58 +0100 Subject: QML tooling: Make sure we signal object creation also from QQmlIncubator We have to call the QQmlEngineDebugService back from QQmlObjectCreator rather than QQmlComponent, as there are more ways to create an object. We also add the new instance to the global instance list if only the V4 debug service is active, as both QQmlEngineDebugService and QV4DebugService use it. Change-Id: I5dcc71b2e91049bc19ec70d7b87959a61c9b6b75 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlcomponent.cpp | 11 --------- src/qml/qml/qqmlobjectcreator.cpp | 13 ++++++++++ .../tst_qqmlenginedebugservice.cpp | 28 ++++++++++++++++++++++ .../qml/debugger/shared/qqmlenginedebugclient.cpp | 4 +++- .../qml/debugger/shared/qqmlenginedebugclient.h | 2 +- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 8be5172cd4..15e09f0b85 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -47,8 +47,6 @@ #include "qqml.h" #include "qqmlengine.h" #include "qqmlbinding_p.h" -#include -#include #include "qqmlincubator.h" #include "qqmlincubator_p.h" #include @@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) depthIncreased = false; } - if (rv) { - if (QQmlEngineDebugService *service = - QQmlDebugConnector::service()) { - if (!context->isInternal) - context->asQQmlContextPrivate()->instances.append(rv); - service->objectCreated(engine, rv); - } - } - return rv; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 2e2a3fb303..09936f6e7a 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -53,6 +53,8 @@ #include #include #include +#include +#include QT_USE_NAMESPACE @@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI phase = ObjectsCreated; + if (instance) { + if (QQmlEngineDebugService *service + = QQmlDebugConnector::service()) { + if (!parentContext->isInternal) + parentContext->asQQmlContextPrivate()->instances.append(instance); + service->objectCreated(engine, instance); + } else if (!parentContext->isInternal && QQmlDebugConnector::service()) { + parentContext->asQQmlContextPrivate()->instances.append(instance); + } + } + return instance; } diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index 40e19d375d..8c30a82317 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -136,6 +137,7 @@ private slots: void regression_QTCREATORBUG_7451(); void queryObjectWithNonStreamableTypes(); + void asynchronousCreate(); }; QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( @@ -1220,6 +1222,32 @@ void tst_QQmlEngineDebugService::queryObjectTree() QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100); } +void tst_QQmlEngineDebugService::asynchronousCreate() { + QmlDebugObjectReference object; + auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) { + object.debugId = objectId; + }); + + QByteArray asynchronousComponent = "import QtQuick 2.5\n" + "Rectangle { id: asyncRect }"; + QQmlComponent component(m_engine); + component.setData(asynchronousComponent, QUrl::fromLocalFile("")); + QVERIFY(component.isReady()); // fails if bad syntax + QQmlIncubator incubator(QQmlIncubator::Asynchronous); + component.create(incubator); + + QVERIFY(m_dbg->object().idString != QLatin1String("asyncRect")); + + QTRY_VERIFY(object.debugId != -1); + disconnect(connection); + + bool success = false; + m_dbg->queryObject(object, &success); + QVERIFY(success); + + QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect")); +} + int main(int argc, char *argv[]) { int _argc = argc + 1; diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp index 3ad7beb7ff..3e27951d78 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp +++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp @@ -489,7 +489,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data) return; } else if (type == "OBJECT_CREATED") { - emit newObjects(); + int engineId, objectId, parentId; + ds >> engineId >> objectId >> parentId; + emit newObject(objectId); return; } else if (type == "SET_BINDING_R") { ds >> m_valid; diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h index a64a77e13e..5d74f2d43c 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h +++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h @@ -213,7 +213,7 @@ public: bool valid() { return m_valid; } signals: - void newObjects(); + void newObject(int objectId); void valueChanged(QByteArray,QVariant); void result(); -- cgit v1.2.3 From 342c72da64cac4aec1463091f6fe0bfb16cd1850 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Thu, 5 Jan 2017 13:42:14 +0100 Subject: Avoid needless notifications when destroying layouts When deleting a layout with children, it ends up in ~QQuickItem(), which in turn will call setParentItem(0). setParentItem(0) will in turn call setEffectiveVisibleRecur(), which will recurse down all its descendants. Therefore, deleting a top level layout might trigger item change listeners for *all* its descendants, not only its direct children. This behavior might even cause crashes: The visibility changes will then trigger an invalidation of the layout, which will propagate up the parent hierarchy, and potentially call invalidate() on a partially-destroyed layout, which then might crash. Change-Id: I48e11d57f69e9011ced6c3a0b51e3d89b24ad5c1 Task-number: QTBUG-55103 Reviewed-by: Shawn Rutledge --- src/imports/layouts/qquicklayout.cpp | 26 ++++++++++++++++++++++ src/imports/layouts/qquicklayout_p.h | 2 ++ src/imports/layouts/qquicklinearlayout.cpp | 6 +---- .../quick/qquicklayouts/data/tst_rowlayout.qml | 21 +++++++++++++++++ 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp index 3786d21727..fd2ff4a73e 100644 --- a/src/imports/layouts/qquicklayout.cpp +++ b/src/imports/layouts/qquicklayout.cpp @@ -762,9 +762,11 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value) { if (change == ItemChildAddedChange) { + Q_D(QQuickLayout); QQuickItem *item = value.item; qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility); + d->m_hasItemChangeListeners = true; if (isReady()) updateLayoutItems(); } else if (change == ItemChildRemovedChange) { @@ -802,6 +804,30 @@ bool QQuickLayout::isReady() const return d_func()->m_isReady; } +/*! + * \brief QQuickLayout::deactivateRecur + * \internal + * + * Call this from the dtor of the top-level layout. + * Otherwise, it will trigger lots of unneeded item change listeners (itemVisibleChanged()) for all its descendants + * that will have its impact thrown away. + */ +void QQuickLayout::deactivateRecur() +{ + if (d_func()->m_hasItemChangeListeners) { + for (int i = 0; i < itemCount(); ++i) { + QQuickItem *item = itemAt(i); + // When deleting a layout with children, there is no reason for the children to inform the layout that their + // e.g. visibility got changed. The layout already knows that all its children will eventually become invisible, so + // we therefore remove its change listener. + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility); + if (QQuickLayout *layout = qobject_cast(item)) + layout->deactivateRecur(); + } + d_func()->m_hasItemChangeListeners = false; + } +} + void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item) { Q_UNUSED(item); diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h index eece6f8658..113498eb2b 100644 --- a/src/imports/layouts/qquicklayout_p.h +++ b/src/imports/layouts/qquicklayout_p.h @@ -95,6 +95,7 @@ public: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; bool isReady() const; + void deactivateRecur(); /* QQuickItemChangeListener */ @@ -134,6 +135,7 @@ public: protected: unsigned m_isReady : 1; unsigned m_disableRearrange : 1; + unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners... mutable QSet m_ignoredItems; }; diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp index 13fdd496c2..50b3eed87e 100644 --- a/src/imports/layouts/qquicklinearlayout.cpp +++ b/src/imports/layouts/qquicklinearlayout.cpp @@ -305,11 +305,7 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase() // Remove item listeners so we do not act on signalling unnecessarily // (there is no point, as the layout will be torn down anyway). - for (int i = 0; i < itemCount(); ++i) { - QQuickItem *item = itemAt(i); - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility); - } - + deactivateRecur(); delete d->styleInfo; } diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 2d4e227a9e..97860458fe 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -802,6 +802,27 @@ Item { layout.destroy() // Do not crash } + Component { + id: rectangle_Component + Rectangle { + width: 100 + height: 50 + } + } + + function test_destroyImplicitInvisibleLayout() + { + var root = rectangle_Component.createObject(container) + root.visible = false + var layout = layout_deleteLayout.createObject(root) + layout.visible = true + // at this point the layout is still invisible because root is invisible + layout.destroy() + // Do not crash when destructing the layout + waitForRendering(container) // should ideally call gc(), but does not work + root.destroy() + } + function test_sizeHintWithHiddenChildren(data) { var layout = layout_sizeHint_Component.createObject(container) var grid = layout.children[0] -- cgit v1.2.3 From 770915841def879301e58496caf4b552a86a6103 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 11 Dec 2016 17:04:50 +0100 Subject: Update QSGRenderNode docs to match reality Scissor and stencil tests are not actually enabled when invoking render(), meaning rendernode implementations do not clip by default. This has been documented when making the class public in 5.8, but the older list with the OpenGL states still contains contradictory entries which are false since Qt 5.2 or so. Change-Id: I46875b11322585d40962db2c4302602a1410a7b9 Reviewed-by: Andy Nichols --- src/quick/scenegraph/coreapi/qsgrendernode.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp index 5915d51f2b..1bc0210b72 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp @@ -160,10 +160,7 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const \list \li glDepthMask(false) \li glDisable(GL_DEPTH_TEST) - \li glStencilMask(0) - \li glEnable(GL_STENCIL_TEST)/glDisable(GL_STENCIL_TEST) depending on clip \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip - \li glEnable(GL_SCISSOR_TEST)/glDisable(GL_SCISSOR_TEST) depending on clip \li glScissor(state.scissorRect.x(), state.scissorRect.y(), state.scissorRect.width(), state.scissorRect.height()) depending on clip \li glEnable(GL_BLEND) -- cgit v1.2.3 From 1cead4f316184489ff81e689611b91d3760ee5cf Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Dec 2016 14:24:49 +0100 Subject: Propagate root changes to rendernodes too Otherwise weird things will happen once a node gets turned into a batch root and the rendernodes in the child subtree still refers to their old root. Change-Id: I42b0ba514c2fbeed833f0f665e49b275c19b5686 Reviewed-by: Andy Nichols --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 4893c175a3..8d4c313056 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -979,6 +979,10 @@ void Renderer::nodeChangedBatchRoot(Node *node, Node *root) e->root = root; e->boundsComputed = false; } + } else if (node->type() == QSGNode::RenderNodeType) { + RenderNodeElement *e = node->renderNodeElement(); + if (e) + e->root = root; } SHADOWNODE_TRAVERSE(node) -- cgit v1.2.3 From 9ce6712c981c312f5c417c58b0d578d872af428a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 6 Dec 2016 14:35:56 +0100 Subject: Fix projection matrix for DepthAware QSGRenderNodes Unlike renderUnmergedBatches(), renderRenderNode() did not adjust the projection matrix. Change-Id: Ib5a7183a3623d35c85af47205cc22187bad89409 Reviewed-by: Andy Nichols --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 8d4c313056..d4324bc489 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -2803,8 +2803,13 @@ void Renderer::renderRenderNode(Batch *batch) updateClip(rd->m_clip_list, batch); - RenderNodeState state; QMatrix4x4 pm = projectionMatrix(); + if (m_useDepthBuffer) { + pm(2, 2) = m_zRange; + pm(2, 3) = 1.0f - e->order * m_zRange; + } + + RenderNodeState state; state.m_projectionMatrix = ± state.m_scissorEnabled = m_currentClipType & ScissorClip; state.m_stencilEnabled = m_currentClipType & StencilClip; -- cgit v1.2.3 From fd0d4464533ae773a5b70cb803b25fd97b6f09a0 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Wed, 11 Jan 2017 21:08:23 +0100 Subject: QJSValue: Mention how to construct QJSValue from other non-obvious types This has come up in queries from users, so let's add a helping hand. Change-Id: If4e5efdd8969a71a78fc88ae168ede8d681858aa Reviewed-by: Simon Hausmann --- src/qml/jsapi/qjsvalue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index b473e96286..bab2e633a7 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -73,7 +73,8 @@ For the object-based types (including Date and RegExp), use the newT() functions in QJSEngine (e.g. QJSEngine::newObject()) to create a QJSValue of the desired type. For the primitive types, - use one of the QJSValue constructor overloads. + use one of the QJSValue constructor overloads. For other types, e.g. + registered gadget types such as QPoint, you can use QJSEngine::toScriptValue. The methods named isT() (e.g. isBool(), isUndefined()) can be used to test if a value is of a certain type. The methods named -- cgit v1.2.3 From 6e568c6ef5b34e32b0e2ec7b66d01d63888166a5 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Fri, 13 Jan 2017 18:31:13 +0900 Subject: Fix build without feature.im Change-Id: I9c0c0138e48b30a443307faf6cd7251017bf84ae Reviewed-by: Lars Knoll --- src/quick/items/qquicktextedit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index b99e53b6c8..94da44c00d 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1729,7 +1729,9 @@ void QQuickTextEdit::select(int start, int end) // QTBUG-11100 updateSelection(); +#if QT_CONFIG(im) updateInputMethod(); +#endif } /*! -- cgit v1.2.3 From 0e3380f9c6ab6e3ea7398caccf5aa84f1575f1cd Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 13 Jan 2017 13:31:35 +0100 Subject: Fix crash when C++ QJSValue parameterized signal interacts with JS When converting the parameters of a C++ signal to JS values to provide to a signal handler written in JS, the conversion of a QJSValue to a QV4::Value* may yield a null pointer in case of a default constructed QJSValue for example. This is a regression from commit aa869cbb06bcf005e238059a2cb0205947ff0b5f and we must check for this. Task-number: QTBUG-58133 Change-Id: I528b606b2851dfb3072e54902bd8843d31571a55 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlboundsignal.cpp | 5 ++++- tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml | 2 ++ tests/auto/qml/qqmlecmascript/testtypes.h | 1 + tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index c4af82133a..d207a4908c 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -199,7 +199,10 @@ void QQmlBoundSignalExpression::evaluate(void **a) // for several cases (such as QVariant type and QObject-derived types) //args[ii] = engine->metaTypeToJS(type, a[ii + 1]); if (type == qMetaTypeId()) { - callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast(a[ii + 1])); + if (QV4::Value *v4Value = QJSValuePrivate::getValue(reinterpret_cast(a[ii + 1]))) + callData->args[ii] = *v4Value; + else + callData->args[ii] = QV4::Encode::undefined(); } else if (type == QMetaType::QVariant) { callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1])); } else if (type == QMetaType::Int) { diff --git a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml index 4fc2dab943..676593096c 100644 --- a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml +++ b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml @@ -15,4 +15,6 @@ MyQmlObject onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; enumProperty = e; qtEnumProperty = f; } onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1), MyQmlObject.EnumValue3, Qt.LeftButton) + + onQjsValueEmittingSignal: {} } diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 47fb2a56e7..1f7f3344ef 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -244,6 +244,7 @@ signals: void signalWithGlobalName(int parseInt); void intChanged(); void qjsvalueChanged(); + void qjsValueEmittingSignal(QJSValue value); public slots: void deleteMe() { delete this; } diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 88a8886ecb..b8f12e772d 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -1410,6 +1410,7 @@ void tst_qqmlecmascript::signalParameterTypes() QVERIFY(object != 0); emit object->basicSignal(); + emit object->qjsValueEmittingSignal(QJSValue()); QCOMPARE(object->property("intProperty").toInt(), 10); QCOMPARE(object->property("realProperty").toReal(), 19.2); -- cgit v1.2.3