From d2c16a3e7e090c667dbbd409e35df29b498914e0 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Tue, 3 Mar 2020 15:10:32 +0200 Subject: Add changes file for Qt 5.14.2 + 9f056f7902350106d992d43cb04a9e2f6b6b299b Bump version Change-Id: I83144083326956792554642898a6cc5863a396ea Reviewed-by: Jani Heikkinen --- dist/changes-5.14.2 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 dist/changes-5.14.2 diff --git a/dist/changes-5.14.2 b/dist/changes-5.14.2 new file mode 100644 index 0000000..68a0051 --- /dev/null +++ b/dist/changes-5.14.2 @@ -0,0 +1,20 @@ +Qt 5.14.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0 through 5.14.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. -- cgit v1.2.1 From bdec52548ca739e5533792c3bf656b8e2cf9fcb6 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Fri, 13 Dec 2019 16:38:59 +0100 Subject: Restore compatibility with custom QVariantList/QVariantMap converters QVariant::toValue does not honor explicit custom converters for a sequentially iterable container to a QVariantList. This breaks compatibility with Qt 5.12.3 and before, where the old code path using QVariant::toList() used the custom converter. Do the same for QVariantMap. This patch restores the compatibility with old code. The real fix will target the QVariantList converter code in QtCore - this is just a hotfix within Qt WebChannel for now. Task-number: QTBUG-80751 Change-Id: Ic70c6a353aad43ddbaefbc6626a0af87bd0d024f Reviewed-by: Fabian Kosmale --- src/webchannel/qmetaobjectpublisher.cpp | 13 +++++++++++-- tests/auto/webchannel/tst_webchannel.cpp | 25 +++++++++++++++++++++++++ tests/auto/webchannel/tst_webchannel.h | 13 +++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index e23921d..ea7ddc9 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -788,10 +788,19 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA // *don't* use result.toList() as that *only* works for QVariantList and QStringList! // Also, don't use QSequentialIterable (yet), since that seems to trigger QTBUG-42016 // in certain cases. - return wrapList(result.value(), transport); + // additionally, when there's a direct converter to QVariantList, use that one via convert + // but recover when conversion fails and fall back to the .value conversion + // see also: https://bugreports.qt.io/browse/QTBUG-80751 + auto list = result; + if (!list.convert(qMetaTypeId())) + list = result; + return wrapList(list.value(), transport); } else if (result.canConvert()) { // recurse and potentially wrap contents of the map - return wrapMap(result.toMap(), transport); + auto map = result; + if (!map.convert(qMetaTypeId())) + map = result; + return wrapMap(map.value(), transport); } return QJsonValue::fromVariant(result); diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp index c47cd6b..f9719cf 100644 --- a/tests/auto/webchannel/tst_webchannel.cpp +++ b/tests/auto/webchannel/tst_webchannel.cpp @@ -183,6 +183,20 @@ void TestJSEngine::initWebChannelJS() #endif // WEBCHANNEL_TESTS_CAN_USE_JS_ENGINE +namespace { +QVariantList convert_to_js(const TestStructVector &list) +{ + QVariantList ret; + ret.reserve(list.size()); + std::transform(list.begin(), list.end(), std::back_inserter(ret), [](const TestStruct &value) -> QVariant { + QVariantMap map; + map["foo"] = value.foo; + map["bar"] = value.bar; + return map; + }); + return ret; +} +} TestWebChannel::TestWebChannel(QObject *parent) : QObject(parent) @@ -191,6 +205,9 @@ TestWebChannel::TestWebChannel(QObject *parent) , m_lastBool(false) , m_lastDouble(0) { + qRegisterMetaType(); + qRegisterMetaType(); + QMetaType::registerConverter(convert_to_js); } TestWebChannel::~TestWebChannel() @@ -864,6 +881,14 @@ void TestWebChannel::testWrapValues() QVERIFY(value.isArray()); QCOMPARE(value.toArray(), QJsonArray({1, 2, 3})); } + { + TestStructVector vec{{1, 2}, {3, 4}}; + QVariant variant = QVariant::fromValue(vec); + QJsonValue value = channel.d_func()->publisher->wrapResult(variant, m_dummyTransport); + QVERIFY(value.isArray()); + QCOMPARE(value.toArray(), QJsonArray({QJsonObject{{"foo", 1}, {"bar", 2}}, + QJsonObject{{"foo", 3}, {"bar", 4}}})); + } } void TestWebChannel::testWrapObjectWithMultipleTransports() diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h index 7cfce06..eae21f4 100644 --- a/tests/auto/webchannel/tst_webchannel.h +++ b/tests/auto/webchannel/tst_webchannel.h @@ -39,6 +39,19 @@ #include +struct TestStruct +{ + TestStruct(int foo = 0, int bar = 0) + : foo(foo) + , bar(bar) + {} + int foo; + int bar; +}; +Q_DECLARE_METATYPE(TestStruct) +using TestStructVector = std::vector; +Q_DECLARE_METATYPE(TestStructVector) + QT_BEGIN_NAMESPACE class DummyTransport : public QWebChannelAbstractTransport -- cgit v1.2.1 From cbbb6c38fa9b64e9e4eb98af0bf687ef469aa327 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Thu, 12 Dec 2019 14:40:29 +0100 Subject: tst_webchannel: Don't use QSignalSpy for inter-thread signals Fixes data races reported by helgrind due to direct signal connection within QSignalSpy without any sort of serialization. ``` ==840094== Possible data race during write of size 4 at 0x1FFEFFD160 by thread #3 ==840094== Locks held: none ==840094== at 0x4F7DE5C: QListData::detach_grow(int*, int) (qlist.cpp:121) ==840094== by 0x125380: QList >::detach_helper_grow(int, int) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x125598: QList >::append(QList const&) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x127CEC: QSignalSpy::qt_metacall(QMetaObject::Call, int, void**) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x5149278: QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) (qmetaobject.cpp:316) ==840094== by 0x518BE13: QMetaObject::activate(QObject*, int, int, void**) (qobject.cpp:3825) ==840094== by 0x518B571: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (qobject.cpp:3660) ==840094== by 0x1281F5: TestObject::propChanged(QString const&) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x1298BB: TestObject::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x5183FEC: QMetaCallEvent::placeMetaCall(QObject*) (qobject.cpp:520) ==840094== by 0x5184FFB: QObject::event(QEvent*) (qobject.cpp:1260) ==840094== by 0x513F8D7: QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) (qcoreapplication.cpp:1256) ==840094== ==840094== This conflicts with a previous read of size 4 by thread #1 ==840094== Locks held: none ==840094== at 0x1213FF: TestWebChannel::testAsyncObject() (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x128E03: TestWebChannel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (in /ssd2/milian/projects/qt5/src/qtwebchannel/build/tests/auto/webchannel/tst_webchannel) ==840094== by 0x514D345: QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (qmetaobject.cpp:2308) ==840094== by 0x4DBE6E2: QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (qmetaobject.h:122) ==840094== by 0x4DB735A: QTest::TestMethods::invokeTestOnData(int) const (qtestcase.cpp:941) ==840094== by 0x4DB7EA8: QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const (qtestcase.cpp:1140) ==840094== by 0x4DB92DE: QTest::TestMethods::invokeTests(QObject*) const (qtestcase.cpp:1484) ==840094== by 0x4DB9F3F: QTest::qRun() (qtestcase.cpp:1922) ==840094== Address 0x1ffeffd160 is on thread #1's stack ==840094== in frame #3, created by TestWebChannel::testAsyncObject() (???:) ``` Change-Id: Ie0d18e1d7ec970fd7fb46a5ef10699d239008f53 Reviewed-by: Kirill Burtsev --- tests/auto/webchannel/tst_webchannel.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp index f9719cf..a1e824b 100644 --- a/tests/auto/webchannel/tst_webchannel.cpp +++ b/tests/auto/webchannel/tst_webchannel.cpp @@ -955,10 +955,13 @@ void TestWebChannel::testAsyncObject() args.append(QJsonValue("message")); { - QSignalSpy spy(&obj, &TestObject::propChanged); + int received = 0; + connect(&obj, &TestObject::propChanged, this, [&](const QString &arg) { + QCOMPARE(arg, args.at(0).toString()); + ++received; + }); channel.d_func()->publisher->invokeMethod(&obj, "setProp", args); - QTRY_COMPARE(spy.count(), 1); - QCOMPARE(spy.at(0).at(0).toString(), args.at(0).toString()); + QTRY_COMPARE(received, 1); } channel.registerObject("myObj", &obj); @@ -971,12 +974,13 @@ void TestWebChannel::testAsyncObject() channel.d_func()->publisher->handleMessage(connectMessage, m_dummyTransport); { - QSignalSpy spy(&obj, &TestObject::replay); + int received = 0; + connect(&obj, &TestObject::replay, this, [&]() { ++received; }); QMetaObject::invokeMethod(&obj, "fire"); - QTRY_COMPARE(spy.count(), 1); + QTRY_COMPARE(received, 1); channel.deregisterObject(&obj); QMetaObject::invokeMethod(&obj, "fire"); - QTRY_COMPARE(spy.count(), 2); + QTRY_COMPARE(received, 2); } thread.quit(); -- cgit v1.2.1 From 4af709df207bf7c98ae5ffd699a66d33767d6300 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 15 Apr 2020 15:51:11 +0200 Subject: Fix deprecation warning Change-Id: Ieb3f0ef5e5b752613d664731e250dba14fb42f0a Reviewed-by: Milian Wolff --- src/webchannel/qmetaobjectpublisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index ea7ddc9..677f79c 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -869,7 +869,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel transport->sendMessage(createResponse(message.value(KEY_ID), initializeClient(transport))); } else if (type == TypeDebug) { static QTextStream out(stdout); - out << "DEBUG: " << message.value(KEY_DATA).toString() << endl; + out << "DEBUG: " << message.value(KEY_DATA).toString() << Qt::endl; } else if (message.contains(KEY_OBJECT)) { const QString &objectName = message.value(KEY_OBJECT).toString(); QObject *object = registeredObjects.value(objectName); -- cgit v1.2.1 From 35c72dda7a791fdb21215743dc78ee12d4a550e2 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Fri, 17 Apr 2020 10:05:39 +0300 Subject: Add changes file for Qt 5.15.0 + 869a1a5f7321dcd3fdd57735fb503a6d3506c616 Bump version + 2f5e7d048f291580a83677b415f4758aab04882a Fix documentation to use commonly working syntax for property changes + 1f793c887773f9b7477a73467aa1e2497ffef25c Update plugins.qmltypes for 5.15 + bdec52548ca739e5533792c3bf656b8e2cf9fcb6 Restore compatibility with custom QVariantList/QVariantMap converters + cbbb6c38fa9b64e9e4eb98af0bf687ef469aa327 tst_webchannel: Don't use QSignalSpy for inter-thread signals + 4af709df207bf7c98ae5ffd699a66d33767d6300 Fix deprecation warning Change-Id: I86de18c94bf12b9b8bcd11b780e34e00f8c464df Reviewed-by: Milian Wolff --- dist/changes-5.15.0 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 dist/changes-5.15.0 diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0 new file mode 100644 index 0000000..40076ce --- /dev/null +++ b/dist/changes-5.15.0 @@ -0,0 +1,18 @@ +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. -- cgit v1.2.1