aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-02-02 09:32:17 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-02-02 09:50:13 +0000
commit61a32b78db418936ca7987ff859f9e62f84cbd06 (patch)
treeffc64e668b1fb52c777c702411cfcb6f88582eb7 /src/qml/qml/qqmlmetatype.cpp
parentb82296f825daf0ba110fea4aa1b61f96d63f371b (diff)
Lift restriction for type registrations in QML module plugins
During the registerTypes() callback in a QML module plugin we only allow types to be registered that match the module URI specified in the qmldir. We can observe in QtQuickControls 2 that sometimes we need to register types outside of the namespace of the module itself. QQC2 is in QtQuick.Controls but the module has internal types that are in QtQuick.Controls.impl. Types are intended to be registered once in the virtual registerTypes() function. However as we don't allow for the registration of .impl to happen in registerTypes(), QQC2 works around this by registering the types in initializeEngine(), during which the namespace restriction is not in place. This workaround means that every time an application creates a QQuickView (and thus new QML engine) and loads a QML file that imports QQC2, we end up calling initializeEngine(), as opposed to registerTypes() that is called only one single time in the application process. As a consequence each time this happens we and up calling qmlRegisterTypes() with the same times and leak memory this way, as qmlRegisterType*() is supposed to register a new type and return a new type id that can be passed to qmlUnregisterType. To solve this this patch lifts the restriction on namespaces for registered types during registerTypes(). The real world case of QQC2 shows that the restriction is limiting and also easy to work around. With the restriction lifted QQC2 can now register all types once in registerTypes() instead. [ChangeLog][QtQml][Important Behavior Changes] QML module plugins used to be limited to type registrations in the primary module namespace in the virtual registerTypes() function. Module authors worked around this limitation by placing necessary internal type registrations into initializeEngine() that may cause memory leaks. Therefore this restriction has been moved and types in any (non-protected) namespaces can be registered in the registerTypes() function. Change-Id: I5baf9718a0b0a591f6eb6d7e2dc83e13b204800d Reviewed-by: J-P Nurmi <jpnurmi@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r--src/qml/qml/qqmlmetatype.cpp10
1 files changed, 1 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 40864de366..b324386bf5 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1579,15 +1579,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (uri && !typeName.isEmpty()) {
QString nameSpace = QString::fromUtf8(uri);
- if (!data->typeRegistrationNamespace.isEmpty()) {
- // We can only install types into the registered namespace
- if (nameSpace != data->typeRegistrationNamespace) {
- QString failure(QCoreApplication::translate("qmlRegisterType",
- "Cannot install %1 '%2' into unregistered namespace '%3'"));
- data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
- return false;
- }
- } else if (data->typeRegistrationNamespace != nameSpace) {
+ if (data->typeRegistrationNamespace.isEmpty() && !nameSpace.isEmpty()) {
// Is the target namespace protected against further registrations?
if (data->protectedNamespaces.contains(nameSpace)) {
QString failure(QCoreApplication::translate("qmlRegisterType",