From 8ec25f301d08e981ca066755ffea582c5cbdf1b0 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Wed, 27 Mar 2019 10:35:33 +0100 Subject: Doc: Fix typo in code snippet Fixes: QTBUG-74444 Change-Id: If504fe2a6b4a0d88d69e777d433a6773db5f4df3 Reviewed-by: Michael Brasser --- src/quick/util/qquickanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 02be9daac0..2043b50545 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -812,7 +812,7 @@ QQuickColorAnimation::~QQuickColorAnimation() // States are defined here... ] - transition: Transition { + transitions: Transition { ColorAnimation { from: "#c0c0c0"; duration: 2000 } } } -- cgit v1.2.3 From fbce9202122d227f138a85f3d9b4f39bd8548143 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Mon, 1 Apr 2019 13:35:31 +0300 Subject: Add changes file for Qt 5.12.3 Change-Id: I900dd172973cfc5897c45468bb2eaf9cb41664d4 Reviewed-by: Robert Loehning Reviewed-by: Shawn Rutledge Reviewed-by: Ulf Hermann --- dist/changes-5.12.3 | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 dist/changes-5.12.3 diff --git a/dist/changes-5.12.3 b/dist/changes-5.12.3 new file mode 100644 index 0000000000..ba1cadd039 --- /dev/null +++ b/dist/changes-5.12.3 @@ -0,0 +1,75 @@ +Qt 5.12.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.2. + +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.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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. + +**************************************************************************** +* QtQml * +**************************************************************************** + + - [QTBUG-74677] Avoid redundant slashes and handle redundant enums when + converting resource URLs. + - [QTBUG-74190] Fixed a crash related to freezing properties. + - [QTBUG-58559] Fixed a memory leak when deleting dynamic properties on + JS objects (trigger garbage collection). + - [QTBUG-74532] qmlcachegen output is now independent of TranslationData + and thus more deterministic. + - [QTBUG-69898] Made several performance improvements with property lookups. + - [QTBUG-74476] Fixed a logic bug involving inversion of non-reflexive + comparison binops, which resulted in incorrect evaluation of some if statements. + - [QTBUG-73843] When QQmlAbstractUrlInterceptor intercepts the loading of + the qmldir file, we now use the intercepted URL to load additional files + in that import. + - [QTBUG-74058] Fixed a GC bug resulting in invalid memory read. + - [QTBUG-74148] Fixed a propertyCache memory leak with Loader and PageIndicator. + - [QTBUG-74087] Deeper recursion is now possible, and less stack space is used + during code generation. The "Maximum statement or expression depth exceeded" + error is now less likely when using 3rd party JavaScript libraries. + - [QTBUG-74188] Fixed a crash when deleting properties, due to shared ownership + of SparseArrayNode. + - [QTBUG-72807] Disabled tail calls for functions called with more arguments + than formals. + - [QTBUG-73999] Fixed number to string conversion with radix. + - [QTBUG-73985] Fixed a crash during unwinding in QJSEngine::evaluate. + - [QTBUG-33179] QML revisioning now works for grouped properties. + +**************************************************************************** +* QtQuick * +**************************************************************************** + + - [QT3DS-3238] Fixed a surface format bug on macOS. + - [QTBUG-74508] Fixed incorrect PathView.currentIndex assignment with + StrictlyEnforceRange. + - [QTBUG-72457] Text now renders HTML table cell background colors properly, + and does correct layout of table cells with percentage-based widths. + - [QDS-263] qmlpreview now does better window placement on Windows. + - [QTBUG-71042] Fixed a bug in setting dynamic anchors to parents + in PropertyChanges. + - [QTBUG-73723] Fixed leaking of QML QQuickItemGrabResult objects + afterQQuickItem::grabToImage() is called from QML. + - [QTBUG-74008] Fixed a crash when one touch event contains a point that + begins acting as the synthetic mouse, and then that point is missing + from a subsequent event. (This is unexpected from most touchscreens.) + - [QTBUG-74128] Fixed binding loop warnings while using bi-directional + property bindings with Flickable contentX/Y properties. + - [QTBUG-73819] Fixed a crash when Loader unloads an Item or Event Handler + that currently has a grab. + - [QTBUG-41045] When a window is hidden and the visible content under + the mouse cursor in another window has a different cursor, it will + now change as it should. + - [QTBUG-70031] Fixed issues caused by adding the new row and column + properties in QQmlDelegateModel. -- cgit v1.2.3 From 5ead393eba0fc9d7c05790887c53c3728b023195 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 8 Apr 2019 09:29:34 +0200 Subject: Fix qmlscene command parsing If "QMLSCENE_CORE_PROFILE" is set the command line parsing does not work anymore. Change-Id: I75ffa733562708a412d1ae341b24d1f3bb35c034 Reviewed-by: Tim Jenssen --- tools/qmlscene/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 83d6ce5d72..58a45781a2 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -496,6 +496,9 @@ int main(int argc, char ** argv) QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org")); QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + if (qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE")) + options.coreProfile = true; + const QStringList arguments = QCoreApplication::arguments(); for (int i = 1, size = arguments.size(); i < size; ++i) { if (!arguments.at(i).startsWith(QLatin1Char('-'))) { @@ -522,8 +525,7 @@ int main(int argc, char ** argv) options.resizeViewToRootItem = true; else if (lowerArgument == QLatin1String("--multisample")) options.multisample = true; - else if (lowerArgument == QLatin1String("--core-profile") - || qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE")) + else if (lowerArgument == QLatin1String("--core-profile")) options.coreProfile = true; else if (lowerArgument == QLatin1String("--verbose")) options.verbose = true; -- cgit v1.2.3 From d7b7fed0cddf6236db3cf1bfdf9cc1380929cf5c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 15 Apr 2019 15:59:03 +0200 Subject: Update the QML Runtime icon A new one has been drawn; use it on all platforms, not just on macOS. It is now also used as the default window icon, to be more identifiable when minimized, etc. Of course it can be overridden by plugins that can be loaded from qml. [ChangeLog][QtQml][qml] The QML Runtime tool now has an updated application icon and a default window icon. QtQuick applications can still use QWindow::setIcon() to override the window icon. Task-number: QTBUG-70826 Task-number: QTBUG-74662 Change-Id: I8671d0c99f7f4283dbe2dc4c605abb560f7bf1a1 Reviewed-by: Shawn Rutledge --- tools/qml/Info.plist | 51 ----------------------------------------- tools/qml/main.cpp | 7 +++++- tools/qml/qml.icns | Bin 196156 -> 0 bytes tools/qml/qml.pro | 10 +++++--- tools/qml/qml.qrc | 1 + tools/qml/resources/Info.plist | 51 +++++++++++++++++++++++++++++++++++++++++ tools/qml/resources/qml-64.png | Bin 0 -> 2304 bytes tools/qml/resources/qml.icns | Bin 0 -> 194026 bytes tools/qml/resources/qml.ico | Bin 0 -> 124455 bytes 9 files changed, 65 insertions(+), 55 deletions(-) delete mode 100644 tools/qml/Info.plist delete mode 100644 tools/qml/qml.icns create mode 100644 tools/qml/resources/Info.plist create mode 100644 tools/qml/resources/qml-64.png create mode 100644 tools/qml/resources/qml.icns create mode 100644 tools/qml/resources/qml.ico diff --git a/tools/qml/Info.plist b/tools/qml/Info.plist deleted file mode 100644 index 567c5bf8fd..0000000000 --- a/tools/qml/Info.plist +++ /dev/null @@ -1,51 +0,0 @@ - - - - - NSPrincipalClass - NSApplication - CFBundleIconFile - @ICON@ - CFBundleIdentifier - org.qt-project.qml - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Qt/QMake - CFBundleSignature - @TYPEINFO@ - CFBundleExecutable - @EXECUTABLE@ - UTExportedTypeDeclarations - - - UTTypeIdentifier - org.qt-project.qml - UTTypeDescription - Qt Markup Language - UTTypeConformsTo - - public.plain-text - - UTTypeTagSpecification - - public.filename-extension - - qml - - - - - CFBundleDocumentTypes - - - LSItemContentTypes - - org.qt-project.qml - - CFBundleTypeRole - Viewer - - - - diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 7dfae2b53d..8918de57d4 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -77,6 +77,7 @@ static QQmlApplicationEngine *qae = nullptr; static int exitTimerId = -1; #endif bool verboseMode = false; +static const QString iconResourcePath(QStringLiteral(":/qt-project.org/QmlRuntime/resources/qml-64.png")); static void loadConf(const QString &override, bool quiet) // Terminates app on failure { @@ -134,7 +135,10 @@ void noFilesGiven(); class LoaderApplication : public QGuiApplication { public: - LoaderApplication(int& argc, char **argv) : QGuiApplication(argc, argv) {} + LoaderApplication(int& argc, char **argv) : QGuiApplication(argc, argv) + { + setWindowIcon(QIcon(iconResourcePath)); + } bool event(QEvent *ev) override { @@ -450,6 +454,7 @@ int main(int argc, char *argv[]) #ifdef QT_WIDGETS_LIB case QmlApplicationTypeWidget: app = new QApplication(argc, argv); + static_cast(app)->setWindowIcon(QIcon(iconResourcePath)); break; #endif // QT_WIDGETS_LIB #endif // QT_GUI_LIB diff --git a/tools/qml/qml.icns b/tools/qml/qml.icns deleted file mode 100644 index c76051626a..0000000000 Binary files a/tools/qml/qml.icns and /dev/null differ diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 3f41707275..f086b7bff9 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -8,10 +8,14 @@ RESOURCES += qml.qrc QMAKE_TARGET_DESCRIPTION = QML Runtime +ICON = resources/qml64.png +win32 { + RC_ICONS = resources/qml.ico +} mac { - OTHER_FILES += Info.plist - QMAKE_INFO_PLIST = Info.plist - ICON = qml.icns + OTHER_FILES += resources/Info.plist + QMAKE_INFO_PLIST = resources/Info.plist + ICON = resources/qml.icns } qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING diff --git a/tools/qml/qml.qrc b/tools/qml/qml.qrc index 1f0ffdace2..e4be1793d4 100644 --- a/tools/qml/qml.qrc +++ b/tools/qml/qml.qrc @@ -2,5 +2,6 @@ conf/configuration.qml conf/qtquick.qml + resources/qml-64.png diff --git a/tools/qml/resources/Info.plist b/tools/qml/resources/Info.plist new file mode 100644 index 0000000000..567c5bf8fd --- /dev/null +++ b/tools/qml/resources/Info.plist @@ -0,0 +1,51 @@ + + + + + NSPrincipalClass + NSApplication + CFBundleIconFile + @ICON@ + CFBundleIdentifier + org.qt-project.qml + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @EXECUTABLE@ + UTExportedTypeDeclarations + + + UTTypeIdentifier + org.qt-project.qml + UTTypeDescription + Qt Markup Language + UTTypeConformsTo + + public.plain-text + + UTTypeTagSpecification + + public.filename-extension + + qml + + + + + CFBundleDocumentTypes + + + LSItemContentTypes + + org.qt-project.qml + + CFBundleTypeRole + Viewer + + + + diff --git a/tools/qml/resources/qml-64.png b/tools/qml/resources/qml-64.png new file mode 100644 index 0000000000..83dbeab9af Binary files /dev/null and b/tools/qml/resources/qml-64.png differ diff --git a/tools/qml/resources/qml.icns b/tools/qml/resources/qml.icns new file mode 100644 index 0000000000..b092ffd943 Binary files /dev/null and b/tools/qml/resources/qml.icns differ diff --git a/tools/qml/resources/qml.ico b/tools/qml/resources/qml.ico new file mode 100644 index 0000000000..09ec5ccece Binary files /dev/null and b/tools/qml/resources/qml.ico differ -- cgit v1.2.3 From 9c4174f9f3fa4a0c46b11b3160d1b45d19bf66af Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 16 Apr 2019 16:45:55 +0200 Subject: Debug missing synth-mouse ID in hex, not decimal It's hard to correlate with the other debug messages otherwise. Task-number: QTBUG-74008 Change-Id: I611201cc8ca86739251b72ccc3e1c5860cfdad8a Reviewed-by: Shawn Rutledge --- src/quick/items/qquickwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index bd01e9b3ce..f705f132fc 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2543,7 +2543,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, if (point->grabberPointerHandler()) cancelTouchMouseSynthesis(); } else { - qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << touchMouseId << "is missing from" << event; + qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << hex << touchMouseId << "is missing from" << event; } } for (int i = 0; i < pointCount; ++i) { -- cgit v1.2.3 From 217efe37193ae07d634c88ef8b3ad9369fd433bb Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Apr 2019 11:20:26 +0200 Subject: Blacklist ...::touchDragFlickableBehindButton() on mingw Task-number: QTBUG-75224 Change-Id: Ic7daefa2f0422a0b1cfa112fd5412cafffb2a9ed Reviewed-by: Shawn Rutledge --- tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST index 62aa19a9ae..20f989fc50 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST +++ b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST @@ -2,3 +2,5 @@ windows gcc [touchDragFlickableBehindSlider] windows gcc +[touchDragFlickableBehindButton] +windows gcc -- cgit v1.2.3 From a1b429011df6c04b4ef3731e8d24b4b3b41946a1 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Apr 2019 07:52:28 +0200 Subject: Blacklist tst_qquickapplication::active() on opensuse Task-number: QTBUG-75215 Change-Id: Ia567352a21e9a333df67ad8c87c5732d439af546 Reviewed-by: Shawn Rutledge --- tests/auto/quick/qquickapplication/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/quick/qquickapplication/BLACKLIST diff --git a/tests/auto/quick/qquickapplication/BLACKLIST b/tests/auto/quick/qquickapplication/BLACKLIST new file mode 100644 index 0000000000..1b7464e7c4 --- /dev/null +++ b/tests/auto/quick/qquickapplication/BLACKLIST @@ -0,0 +1,3 @@ +[active] +opensuse-42.3 +opensuse-leap -- cgit v1.2.3 From ea74f0c68cddf706c950d3910cf7b363fe24885b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Apr 2019 12:35:42 +0200 Subject: Don't crash when accessing invalid properties through QObjectWrapper Change-Id: I613bf5dc685bb4235262b429d8f7318ea144fb9d Fixes: QTBUG-75203 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 +- .../data/undefinedPropertiesInObjectWrapper.qml | 20 ++++++++++++++++++++ tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 10 ++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/undefinedPropertiesInObjectWrapper.qml diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 377c30617a..5467e730e3 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -856,7 +856,7 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E if (!ddata || !ddata->propertyCache) { QQmlPropertyData local; QQmlPropertyData *property = QQmlPropertyCache::property(engine->jsEngine(), qobj, name, qmlContext, local); - return getProperty(engine, qobj, property); + return property ? getProperty(engine, qobj, property) : QV4::Encode::undefined(); } QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobj, qmlContext); diff --git a/tests/auto/qml/qqmlecmascript/data/undefinedPropertiesInObjectWrapper.qml b/tests/auto/qml/qqmlecmascript/data/undefinedPropertiesInObjectWrapper.qml new file mode 100644 index 0000000000..7e2f15fc23 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/undefinedPropertiesInObjectWrapper.qml @@ -0,0 +1,20 @@ +import QtQuick 2.12 + +QtObject { + property list entries: [ + QtObject { + readonly property color color: "green" + }, + QtObject { + } + ] + + property Row row: Row { + Repeater { + model: entries + Rectangle { + color: model.color ? model.color : "red" + } + } + } +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 0e8844d23f..85cad8f62c 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -367,6 +367,7 @@ private slots: void deleteSparseInIteration(); void saveAccumulatorBeforeToInt32(); void intMinDividedByMinusOne(); + void undefinedPropertiesInObjectWrapper(); private: // static void propertyVarWeakRefCallback(v8::Persistent object, void* parameter); @@ -8958,6 +8959,15 @@ void tst_qqmlecmascript::intMinDividedByMinusOne() QCOMPARE(object->property("doesNotFitInInt").toUInt(), 2147483648u); } +void tst_qqmlecmascript::undefinedPropertiesInObjectWrapper() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFile("undefinedPropertiesInObjectWrapper.qml")); + QVERIFY(component.isReady()); + QScopedPointer object(component.create()); + QVERIFY(!object.isNull()); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" -- cgit v1.2.3 From c018df5b4075ae962966d4df7653d476dab02840 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Apr 2019 08:38:20 +0200 Subject: QML: Remove static attchedPropertyIds map If the same object is available under two different names it should still have the same attached properties no matter which name you use. This was achieved by having a static map of metaobjects to attached property IDs that would always hold the first attached property ID registered for a given metaobject. This attached property ID was then used as key in the map of attached properties for the actual objects. The obvious downside to that is that we need a global static which gives us thread safety and static initialization (and destruction) problems. It turns out, all the attached properties are created by attached properties functions, registered by the user. Those functions only get the object to be amended as parameter. Therefore, no attached properties function can be registered for multiple attached properties on the same object as it wouldn't know which one to create for a given call. Thus, the whole ID dance is unnecessary as we can as well index the attached property objects by the function that created them. This nicely avoids creating two attached property objects for the same object and function and still makes the global static unnecessary. Fixes: QTBUG-75176 Change-Id: Ie8d53ef0a6f41c9b3d6b9d611cde1603a557901c Reviewed-by: Erik Verbruggen --- src/qml/qml/qqml.h | 9 +++- src/qml/qml/qqmldata_p.h | 3 +- src/qml/qml/qqmlengine.cpp | 60 ++++++++++++++++++------ src/qml/qml/qqmlmetatype.cpp | 35 +++++--------- src/qml/qml/qqmlmetatype_p.h | 2 + src/qml/qml/qqmlobjectcreator.cpp | 4 +- src/qml/qml/qqmlprivate.h | 5 ++ src/qml/qml/qqmlproperty.cpp | 4 +- src/qml/qml/qqmltypewrapper.cpp | 7 ++- tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp | 8 ++-- 10 files changed, 87 insertions(+), 50 deletions(-) diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 05a9f70247..9eacc5bc22 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -582,6 +582,10 @@ namespace QtQml { Q_QML_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true); Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *, const QObject *, const QMetaObject *, bool create); + Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *, + const QMetaObject *); + Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func, + bool create = true); #ifndef Q_QDOC } #endif @@ -601,8 +605,9 @@ Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versi template QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) { - static int idx = -1; - return qmlAttachedPropertiesObject(&idx, obj, &T::staticMetaObject, create); + QObject *mutableObj = const_cast(obj); + return qmlAttachedPropertiesObject( + mutableObj, qmlAttachedPropertiesFunction(mutableObj, &T::staticMetaObject), create); } Q_QML_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor); diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 2468de6857..f4c03fc17c 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -265,7 +266,7 @@ public: } bool hasExtendedData() const { return extendedData != nullptr; } - QHash *attachedProperties() const; + QHash *attachedProperties() const; static inline bool wasDeleted(const QObject *); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 5841a480fc..7cd4bf8579 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1647,29 +1647,38 @@ QQmlEngine *qmlEngine(const QObject *obj) return data->context->engine; } -QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) +static QObject *resolveAttachedProperties(QQmlAttachedPropertiesFunc pf, QQmlData *data, + QObject *object, bool create) { - QQmlData *data = QQmlData::get(object, create); - if (!data) - return nullptr; // Attached properties are only on objects created by QML, unless explicitly requested (create==true) + if (!pf) + return nullptr; - QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0; + QObject *rv = data->hasExtendedData() ? data->attachedProperties()->value(pf) : 0; if (rv || !create) return rv; - QQmlEnginePrivate *engine = QQmlEnginePrivate::get(data->context); - QQmlAttachedPropertiesFunc pf = QQmlMetaType::attachedPropertiesFuncById(engine, id); - if (!pf) - return nullptr; - - rv = pf(const_cast(object)); + rv = pf(object); if (rv) - data->attachedProperties()->insert(id, rv); + data->attachedProperties()->insert(pf, rv); return rv; } +QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) +{ + QQmlData *data = QQmlData::get(object, create); + + // Attached properties are only on objects created by QML, + // unless explicitly requested (create==true) + if (!data) + return nullptr; + + QQmlEnginePrivate *engine = QQmlEnginePrivate::get(data->context); + return resolveAttachedProperties(QQmlMetaType::attachedPropertiesFuncById(engine, id), data, + const_cast(object), create); +} + QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object, const QMetaObject *attachedMetaObject, bool create) { @@ -1684,6 +1693,29 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object, return qmlAttachedPropertiesObjectById(*idCache, object, create); } +QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *object, + const QMetaObject *attachedMetaObject) +{ + QQmlEngine *engine = object ? qmlEngine(object) : nullptr; + return QQmlMetaType::attachedPropertiesFunc(engine ? QQmlEnginePrivate::get(engine) : nullptr, + attachedMetaObject); +} + +QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc func, bool create) +{ + if (!object) + return nullptr; + + QQmlData *data = QQmlData::get(object, create); + + // Attached properties are only on objects created by QML, + // unless explicitly requested (create==true) + if (!data) + return nullptr; + + return resolveAttachedProperties(func, data, object, create); +} + } // namespace QtQml #if QT_DEPRECATED_SINCE(5, 1) @@ -1724,7 +1756,7 @@ public: QQmlDataExtended(); ~QQmlDataExtended(); - QHash attachedProperties; + QHash attachedProperties; }; QQmlDataExtended::QQmlDataExtended() @@ -1870,7 +1902,7 @@ void QQmlData::disconnectNotifiers() } } -QHash *QQmlData::attachedProperties() const +QHash *QQmlData::attachedProperties() const { if (!extendedData) extendedData = new QQmlDataExtended; return &extendedData->attachedProperties; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index f801e9aeba..1873a99a71 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -224,7 +224,6 @@ public: QQmlCustomParser *customParser; QQmlAttachedPropertiesFunc attachedPropertiesFunc; const QMetaObject *attachedPropertiesType; - int attachedPropertiesId; int propertyValueSourceCast; int propertyValueInterceptorCast; bool registerEnumClassesUnscoped; @@ -269,8 +268,6 @@ public: mutable QStringHash scopedEnumIndex; // maps from enum name to index in scopedEnums mutable QList*> scopedEnums; - static QHash attachedPropertyIds; - struct PropertyCacheByMinorVersion { PropertyCacheByMinorVersion() : cache(nullptr), minorVersion(-1) {} @@ -363,8 +360,6 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const return scriptApis.value(e); } -QHash QQmlTypePrivate::attachedPropertyIds; - QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) : refCount(1), regType(type), iid(nullptr), typeId(0), listId(0), revision(0), containsRevisionedAttributes(false), baseMetaObject(nullptr), @@ -498,14 +493,6 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm d->baseMetaObject = type.metaObject; d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction; d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject; - if (d->extraData.cd->attachedPropertiesType) { - auto iter = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject); - if (iter == QQmlTypePrivate::attachedPropertyIds.end()) - iter = QQmlTypePrivate::attachedPropertyIds.insert(d->baseMetaObject, d->index); - d->extraData.cd->attachedPropertiesId = *iter; - } else { - d->extraData.cd->attachedPropertiesId = -1; - } d->extraData.cd->parserStatusCast = type.parserStatusCast; d->extraData.cd->propertyValueSourceCast = type.valueSourceCast; d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast; @@ -571,16 +558,8 @@ QQmlType::QQmlType(QQmlTypePrivate *priv) QQmlType::~QQmlType() { - if (d && !d->refCount.deref()) { - // If attached properties were successfully registered, deregister them. - // (They may not have been registered if some other type used the same baseMetaObject) - if (d->regType == CppType && d->extraData.cd->attachedPropertiesType) { - auto it = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject); - if (it != QQmlTypePrivate::attachedPropertyIds.end() && *it == d->index) - QQmlTypePrivate::attachedPropertyIds.erase(it); - } + if (d && !d->refCount.deref()) delete d; - } } QHashedString QQmlType::module() const @@ -1228,7 +1207,7 @@ int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const if (!d) return -1; if (d->regType == CppType) - return d->extraData.cd->attachedPropertiesId; + return d->extraData.cd->attachedPropertiesType ? d->index : -1; QQmlType base; if (d->regType == CompositeType) @@ -2188,6 +2167,16 @@ QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(QQmlEnginePr return data->types.at(id).attachedPropertiesFunction(engine); } +QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(QQmlEnginePrivate *engine, + const QMetaObject *mo) +{ + QMutexLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + + QQmlType type(data->metaObjectToType.value(mo)); + return type.attachedPropertiesFunction(engine); +} + QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject) { int idx = metaObject->indexOfClassInfo("DefaultProperty"); diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 8256212207..3c1589d19b 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -119,6 +119,8 @@ public: static int listType(int); static int attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMetaObject *); static QQmlAttachedPropertiesFunc attachedPropertiesFuncById(QQmlEnginePrivate *, int); + static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *, + const QMetaObject *); enum TypeCategory { Unknown, Object, List }; static TypeCategory typeCategory(int); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5af658194f..b62b07e39c 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -793,8 +793,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper else return false; } - const int id = attachedType.attachedPropertiesId(QQmlEnginePrivate::get(engine)); - QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject); + QObject *qmlObject = qmlAttachedPropertiesObject( + _qobject, attachedType.attachedPropertiesFunction(QQmlEnginePrivate::get(engine))); if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/nullptr)) return false; return true; diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index c0232a7691..fa05b3fe19 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -77,6 +77,11 @@ typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *) typedef QObject *(*QQmlAttachedPropertiesFunc)(QObject *); +inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0) +{ + return qHash(quintptr(func), seed); +} + template class QQmlTypeInfo { diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 000b88ebaa..c8166695ba 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -277,7 +277,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); if (!func) return; // Not an attachable type - currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); + currentObject = qmlAttachedPropertiesObject(currentObject, func); if (!currentObject) return; // Something is broken with the attachable type } else if (r.importNamespace) { if ((ii + 1) == path.count()) return; // No type following the namespace @@ -289,7 +289,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); if (!func) return; // Not an attachable type - currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject); + currentObject = qmlAttachedPropertiesObject(currentObject, func); if (!currentObject) return; // Something is broken with the attachable type } else if (r.scriptIndex != -1) { diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index d30c225741..246de04316 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -263,7 +263,9 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons // Fall through to base implementation } else if (w->d()->object) { - QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(v4->qmlEngine())), object); + QObject *ao = qmlAttachedPropertiesObject( + object, + type.attachedPropertiesFunction(QQmlEnginePrivate::get(v4->qmlEngine()))); if (ao) return QV4::QObjectWrapper::getQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); @@ -335,7 +337,8 @@ bool QQmlTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value, if (type.isValid() && !type.isSingleton() && w->d()->object) { QObject *object = w->d()->object; QQmlEngine *e = scope.engine->qmlEngine(); - QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(e)), object); + QObject *ao = qmlAttachedPropertiesObject( + object, type.attachedPropertiesFunction(QQmlEnginePrivate::get(e))); if (ao) return QV4::QObjectWrapper::setQmlProperty(scope.engine, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value); return false; diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 7f103dc5ed..a7805922a5 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -550,8 +550,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() c.setData("import QtQuick 2.2\n Item { }", dummy); const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); - QCOMPARE(attachedType.attachedPropertiesId(QQmlEnginePrivate::get(&e)), - attachedType.index()); + QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), + attachedType.metaObject()); QVERIFY(c.create()); } @@ -569,8 +569,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() "Item { KeyNavigation.up: null }", dummy); const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); - QCOMPARE(attachedType.attachedPropertiesId(QQmlEnginePrivate::get(&e)), - attachedType.index()); + QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), + attachedType.metaObject()); QVERIFY(c.create()); } -- cgit v1.2.3