https://bugs.kde.org/show_bug.cgi?id=423643

--- Comment #5 from Friedrich W. H. Kossebau <kosse...@kde.org> ---
(In reply to Fabian Vogt from comment #3)
> (In reply to Friedrich W. H. Kossebau from comment #2)
> > Looking at the code with this bug report I mind I suspect the new method
> > registers this with the namespace instead, that had slipped my
> > eyes/attention.
> 
> Yep, this sounds like a case of https://bugreports.qt.io/browse/QTBUG-50225

That issue you linked finally gave me the clue what could be broken here
(though still unsure what was messed up with my test setup that I saw no issues
or if I was unconcentrated those days without knowing):

The code before my change was this:
```
    qmlRegisterInterface<Plasma::Service>("Service");
    qRegisterMetaType<Plasma::Service*>("Service");
    qmlRegisterInterface<Plasma::ServiceJob>("ServiceJob");
    qRegisterMetaType<Plasma::ServiceJob*>("ServiceJob");
    // [...]
    qmlRegisterInterface<Plasma::DataSource>("DataSource");
    qRegisterMetaType<Plasma::DataSource*>("DataSource");
```
Next to that in the headers of the respective classes there is:
```
Q_DECLARE_METATYPE(Plasma::Service *)
Q_DECLARE_METATYPE(Plasma::ServiceJob *)
// nothing for Plasma::DataSource*
```
There are two issues here:
a)
all three classes are subclasses of QObject, and for that the docs of
Q_DECLARE_METATYPE tell us:
"Some types are registered automatically and do not need this macro:
* Pointers to classes derived from QObject
[...]
"
This seems a change in Qt5 over Qt4, but the code, added at Plasma4 times, was
not updated to remove the now unneeded Q_DECLARE_METATYPE declarations.
So, by itself Qt has already registered metatypes for "Plasma::Service",
"Plasma::Service*", "Plasma::ServiceJob", "Plasma::ServiceJob*",
"Plasma::DataSource" & "Plasma::DataSource*", under these full namespaced
names.

Just, some API which is e.g. tagged with Q_INVOKABLE does not use the full
namespace name, but omits the Plasma namespace, like "ServiceJob
*Service::startOperationCall(const QVariantMap &description, QObject *parent)".
And as said in the referenced bug report, that name has to be explicitly
additionally registered, to allow Qt the mapping to the actual type metadata.
But see the current qRegisterMetaType<T>("name") as given above: they miss the
"*" from the name. So they are registering the wrong incomplete name. And so
e.g.
```
qRegisterMetaType<Plasma::ServiceJob*>("ServiceJob");
```
will not help Qt when it tries to match the type name "ServiceJob*" from the
invokable above to a registered type in the metadata system.

Now why was there no runtime issue with the old code then you ask? Because 
```
qmlRegisterInterface<Plasma::ServiceJob>("ServiceJob");
```
has saved the day, as its implementation also registers the pointer to the
template class automatically, using the passed name string and appending a "*":
```
template<typename T>
int qmlRegisterInterface(const char *typeName)
{
    QByteArray name(typeName);

    QByteArray pointerName(name + '*');
    QByteArray listName("QQmlListProperty<" + name + '>');

    QQmlPrivate::RegisterInterface qmlInterface = {
        1,

        qRegisterNormalizedMetaType<T *>(pointerName.constData()),
        qRegisterNormalizedMetaType<QQmlListProperty<T>
>(listName.constData()),

        qobject_interface_iid<T *>(),
        "",
        0
    };

    return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration,
&qmlInterface);
}
```

Now the code  with Qt 5.15 instead calling the new qmlRegisterInterface<>(const
char *uri, int versionMajor) instead does things using the full name, as
fetched from the metaobject instance:
```
template<typename T>
int qmlRegisterInterface(const char *uri, int versionMajor)
{
    QML_GETTYPENAMES

    QQmlPrivate::RegisterInterface qmlInterface = {
        1,
        qRegisterNormalizedMetaType<T *>(pointerName.constData()),
        qRegisterNormalizedMetaType<QQmlListProperty<T>>(listName.constData()),
        qobject_interface_iid<T *>(),

        uri,
        versionMajor
    };

    return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration,
&qmlInterface);
}
```

Thus the day is no longer saved.

This would be my sleepy analyis of the cause. Not sure if this can be easily
fixed. Possibly better to revert my commit and do a fully experts-checked patch
for 5.73 then?

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to