-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: port upstream fix to qt6-declarative 6.6.0
Signed-off-by: ComixHe <[email protected]>
- Loading branch information
Showing
3 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
qt6-declarative (6.6.0+dfsg-3) UNRELEASED; urgency=medium | ||
|
||
* Port upstream fix to qt6-declarative 6.6.0 | ||
|
||
-- YuMing He <[email protected]> Tue, 19 Dec 2023 10:40:12 +0800 | ||
|
||
qt6-declarative (6.6.0+dfsg-2) UNRELEASED; urgency=medium | ||
|
||
[ Patrick Franz ] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
From a8ab23b67747fd8c2da7fdcc931f6e9d50d961da Mon Sep 17 00:00:00 2001 | ||
From: Fabian Kosmale <[email protected]> | ||
Date: Fri, 06 Oct 2023 16:22:28 +0200 | ||
Subject: [PATCH] Fix regression on singletons where declared != actual type | ||
|
||
For singletons, we can't rely on the static meta-object of the | ||
registered type, as the create function used for a singleton might | ||
return an instance of a derived type instead. | ||
This could lead to crashes or method-overload resolution failures later | ||
on. | ||
Fix this by always querying the actual meta-object of the singleton, | ||
instead of relying on the meta-object of the registered class. | ||
|
||
Leave a comment about the fact that we still have an issue if you have a | ||
derived instance of the registered type when you additionally extend the | ||
type. However, that is pre-existing (given that it only affects QQmlType | ||
itself). | ||
|
||
Fixes: QTBUG-117891 | ||
Pick-to: 6.5 6.2 | ||
Change-Id: Ie12b4c886ace5cc58a5ded59fa48bc425ae58419 | ||
Reviewed-by: Ulf Hermann <[email protected]> | ||
(cherry picked from commit 8c2ea501fdd07e44ee68e22dcc6d820ae93116f2) | ||
Reviewed-by: Fabian Kosmale <[email protected]> | ||
--- | ||
|
||
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp | ||
index 11f454b..8432703 100644 | ||
--- a/src/qml/qml/qqmltypewrapper.cpp | ||
+++ b/src/qml/qml/qqmltypewrapper.cpp | ||
@@ -56,8 +56,25 @@ | ||
if (!type.isValid()) | ||
return nullptr; | ||
|
||
- if (type.isSingleton()) | ||
- return type.metaObject(); | ||
+ if (type.isSingleton()) { | ||
+ auto metaObjectCandidate = type.metaObject(); | ||
+ // if the candidate is the same as te baseMetaObject, we know that | ||
+ // we don't have an extended singleton; in that case the | ||
+ // actual instance might be subclass of type instead of type itself | ||
+ // so we need to query the actual object for it's meta-object | ||
+ if (metaObjectCandidate == type.baseMetaObject()) { | ||
+ QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine()->qmlEngine()); | ||
+ auto object = qmlEngine->singletonInstance<QObject *>(type); | ||
+ if (object) | ||
+ return object->metaObject(); | ||
+ } | ||
+ /* if we instead have an extended singleton, the dynamic proxy | ||
+ meta-object must alreday be set up correctly | ||
+ ### TODO: it isn't, as QQmlTypePrivate::init has no way to | ||
+ query the object | ||
+ */ | ||
+ return metaObjectCandidate; | ||
+ } | ||
|
||
return type.attachedPropertiesType(QQmlEnginePrivate::get(engine()->qmlEngine())); | ||
} | ||
diff --git a/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml | ||
new file mode 100644 | ||
index 0000000..9d2ee43 | ||
--- /dev/null | ||
+++ b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml | ||
@@ -0,0 +1,6 @@ | ||
+import Qt.test | ||
+import QtQml | ||
+ | ||
+QtObject { | ||
+ Component.onCompleted: SingletonInheritanceTest.trackPage("test", {x: 42}) | ||
+} | ||
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp | ||
index d7a585d..ba40b00 100644 | ||
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp | ||
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp | ||
@@ -543,6 +543,8 @@ | ||
qmlRegisterType<Sender>("Qt.test", 1,0, "Sender"); | ||
qmlRegisterTypesAndRevisions<ReadOnlyBindable>("Qt.test", 1); | ||
qmlRegisterTypesAndRevisions<ResettableGadgetHolder>("Qt.test", 1); | ||
+ | ||
+ qmlRegisterTypesAndRevisions<SingletonRegistrationWrapper>("Qt.test", 1); | ||
} | ||
|
||
#include "testtypes.moc" | ||
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h | ||
index 64c079a..99cfb80 100644 | ||
--- a/tests/auto/qml/qqmlecmascript/testtypes.h | ||
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h | ||
@@ -2069,6 +2069,43 @@ | ||
}; | ||
|
||
|
||
+class SingletonBase : public QObject { | ||
+ Q_OBJECT | ||
+ | ||
+public: | ||
+ Q_INVOKABLE virtual void trackPage(const QString&) {} | ||
+ Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) {} | ||
+ | ||
+ bool m_okay = false; | ||
+}; | ||
+ | ||
+class SingletonImpl : public SingletonBase { | ||
+ Q_OBJECT | ||
+ | ||
+public: | ||
+ Q_INVOKABLE virtual void trackPage(const QString&) override {} | ||
+ Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) override | ||
+ { | ||
+ m_okay = true; | ||
+ } | ||
+}; | ||
+ | ||
+class SingletonRegistrationWrapper { | ||
+ Q_GADGET | ||
+ QML_FOREIGN(SingletonBase) | ||
+ QML_NAMED_ELEMENT(SingletonInheritanceTest) | ||
+ QML_SINGLETON | ||
+ | ||
+public: | ||
+ static SingletonBase* create(QQmlEngine*, QJSEngine*) { | ||
+ return new SingletonImpl(); | ||
+ } | ||
+ | ||
+private: | ||
+ SingletonRegistrationWrapper() = default; | ||
+}; | ||
+ | ||
+ | ||
void registerTypes(); | ||
|
||
#endif // TESTTYPES_H | ||
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | ||
index 59d0809..4023824 100644 | ||
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | ||
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | ||
@@ -422,6 +422,8 @@ | ||
|
||
void resetGadet(); | ||
|
||
+ void methodCallOnDerivedSingleton(); | ||
+ | ||
private: | ||
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); | ||
static void verifyContextLifetime(const QQmlRefPointer<QQmlContextData> &ctxt); | ||
@@ -10478,6 +10480,18 @@ | ||
QCOMPARE(resettableGadgetHolder->g().value(), 42); | ||
} | ||
|
||
+void tst_qqmlecmascript::methodCallOnDerivedSingleton() | ||
+{ | ||
+ QQmlEngine engine; | ||
+ QQmlComponent c(&engine, testFile("methodCallOnDerivedSingleton.qml")); | ||
+ QVERIFY2(c.isReady(), qPrintable(c.errorString())); | ||
+ QScopedPointer<QObject> o(c.create()); | ||
+ QVERIFY(o); | ||
+ auto singleton = engine.singletonInstance<SingletonBase *>("Qt.test", "SingletonInheritanceTest"); | ||
+ QVERIFY(singleton); | ||
+ QVERIFY(singleton->m_okay); | ||
+} | ||
+ | ||
QTEST_MAIN(tst_qqmlecmascript) | ||
|
||
#include "tst_qqmlecmascript.moc" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
fix-singleton-emit-signal-crashed.patch |