aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-04-16 15:47:14 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2024-12-01 18:41:22 +0100
commita6c8de2780b6dface7504b5423e064e026a6e564 (patch)
tree4ff3283315e6679f0550c4d602dc5bce2c9aec2f
parentd8a55297c25ff01ffe371bf83631a69db0f521d8 (diff)
Alert when we are notifying semi-dead change listeners
Add virtual methods "baseDeleted" and "debugName" to QQuickItemChangeListener that let us report whether the object that implements QQuickItemChangeListener is already being destroyed. Add a "safe" version of QQuickItemChangeListener that overrides that virtual method using CRTP: if the derived class that it is instantiated with has a member "inDestructor" (e.g. a QQuickItemPrivate) or "wasDeleted" (e.g. a QObjectPrivate), then return the value of that variable. If the derived type is a QObject or QQuickItem, access the member via QQmlData::wasDeleted. Ignore calls on listeners that are the same object as the caller. Use that new type in those classes where it isn't immediately obvious that they clean up after themselves: classes that don't implement a destructor are a red flag. In addition, add a list to safe listener version to add/remove each item it's listening on. Issue runtime warnings in developer-builds when listeners are called for which baseDestroyed() returns true, and when listeners are destroyed while they still have items on their list. Task-number: QTBUG-98790 Change-Id: I15ed66a36556caa0e6acf5b768dec2ae92b01d64 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/quick/items/qquickanchors_p_p.h3
-rw-r--r--src/quick/items/qquickdrag_p_p.h3
-rw-r--r--src/quick/items/qquickflickable_p_p.h3
-rw-r--r--src/quick/items/qquickitem.cpp25
-rw-r--r--src/quick/items/qquickitem_p.h49
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h107
-rw-r--r--src/quick/items/qquickloader_p_p.h3
-rw-r--r--src/quick/items/qquickpathview_p_p.h3
-rw-r--r--src/quick/items/qquickpositioners_p_p.h3
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h3
-rw-r--r--src/quick/items/qquickview_p.h2
-rw-r--r--src/quickcontrols/qquickattachedpropertypropagator.cpp3
-rw-r--r--src/quickcontrolsimpl/qquickiconlabel_p_p.h3
-rw-r--r--src/quicktemplates/qquickaction_p_p.h3
-rw-r--r--src/quicktemplates/qquickapplicationwindow.cpp2
-rw-r--r--src/quicktemplates/qquickcontrol_p_p.h3
-rw-r--r--src/quicktemplates/qquicklabel_p_p.h3
-rw-r--r--src/quicktemplates/qquickoverlay_p_p.h2
-rw-r--r--src/quicktemplates/qquickpopup_p_p.h2
-rw-r--r--src/quicktemplates/qquickscrollbar_p_p.h3
-rw-r--r--src/quicktemplates/qquickscrollindicator.cpp3
-rw-r--r--src/quicktemplates/qquickstackview_p_p.h2
-rw-r--r--src/quicktemplates/qquicktextarea_p_p.h3
-rw-r--r--src/quickwidgets/qquickwidget_p.h2
24 files changed, 211 insertions, 27 deletions
diff --git a/src/quick/items/qquickanchors_p_p.h b/src/quick/items/qquickanchors_p_p.h
index 12e6dc465a..e478792d55 100644
--- a/src/quick/items/qquickanchors_p_p.h
+++ b/src/quick/items/qquickanchors_p_p.h
@@ -43,7 +43,8 @@ inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b)
return a.item == b.item && a.anchorLine == b.anchorLine;
}
-class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickAnchorsPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickAnchorsPrivate>
{
Q_DECLARE_PUBLIC(QQuickAnchors)
public:
diff --git a/src/quick/items/qquickdrag_p_p.h b/src/quick/items/qquickdrag_p_p.h
index 657dfefb1d..c17bb3b6a7 100644
--- a/src/quick/items/qquickdrag_p_p.h
+++ b/src/quick/items/qquickdrag_p_p.h
@@ -29,7 +29,8 @@
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class Q_AUTOTEST_EXPORT QQuickDragAttachedPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickDragAttachedPrivate>
{
Q_DECLARE_PUBLIC(QQuickDragAttached)
QML_ANONYMOUS
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index ab222fd554..9387073b69 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -34,7 +34,8 @@ class QQuickFlickableVisibleArea;
class QQuickTransition;
class QQuickFlickableReboundTransition;
-class Q_QUICK_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICK_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickFlickablePrivate>
{
Q_DECLARE_PUBLIC(QQuickFlickable)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index c24e3f30e8..0c9fc1f220 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -155,6 +155,7 @@ QQuickContents::QQuickContents(QQuickItem *item)
QQuickContents::~QQuickContents()
{
+ inDestructor = true;
QList<QQuickItem *> children = m_item->childItems();
for (int i = 0; i < children.size(); ++i) {
QQuickItem *child = children.at(i);
@@ -4035,7 +4036,9 @@ while (false)
void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
{
+ Q_Q(QQuickItem);
changeListeners.append(ChangeListener(listener, types));
+ listener->addSourceItem(q);
if (lcChangeListeners().isDebugEnabled())
PRINT_LISTENERS();
@@ -4043,12 +4046,16 @@ void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener
void QQuickItemPrivate::updateOrAddItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
{
+ Q_Q(QQuickItem);
+
const ChangeListener changeListener(listener, types);
const int index = changeListeners.indexOf(changeListener);
- if (index > -1)
+ if (index > -1) {
changeListeners[index].types = changeListener.types;
- else
+ } else {
changeListeners.append(changeListener);
+ listener->addSourceItem(q);
+ }
if (lcChangeListeners().isDebugEnabled())
PRINT_LISTENERS();
@@ -4056,8 +4063,11 @@ void QQuickItemPrivate::updateOrAddItemChangeListener(QQuickItemChangeListener *
void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
{
+ Q_Q(QQuickItem);
+
ChangeListener change(listener, types);
changeListeners.removeOne(change);
+ listener->removeSourceItem(q);
if (lcChangeListeners().isDebugEnabled())
PRINT_LISTENERS();
@@ -4066,12 +4076,16 @@ void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *liste
void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener,
QQuickGeometryChange types)
{
+ Q_Q(QQuickItem);
+
ChangeListener change(listener, types);
int index = changeListeners.indexOf(change);
- if (index > -1)
+ if (index > -1) {
changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
- else
+ } else {
changeListeners.append(change);
+ listener->addSourceItem(q);
+ }
if (lcChangeListeners().isDebugEnabled())
PRINT_LISTENERS();
@@ -4080,9 +4094,12 @@ void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListen
void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
QQuickGeometryChange types)
{
+ Q_Q(QQuickItem);
+
ChangeListener change(listener, types);
if (types.noChange()) {
changeListeners.removeOne(change);
+ listener->removeSourceItem(q);
} else {
int index = changeListeners.indexOf(change);
if (index > -1)
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index dc38c0a405..ad960f5fd2 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -61,7 +61,7 @@ class QQuickEnterKeyAttached;
class QQuickScreenAttached;
class QQuickPointerHandler;
-class QQuickContents : public QQuickItemChangeListener
+class QQuickContents : public QSafeQuickItemChangeListener<QQuickContents>
{
public:
QQuickContents(QQuickItem *item);
@@ -72,6 +72,8 @@ public:
inline void calcGeometry(QQuickItem *changed = nullptr);
void complete();
+ bool inDestructor = false;
+
protected:
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
void itemDestroyed(QQuickItem *item) override;
@@ -109,7 +111,8 @@ public:
#if QT_CONFIG(quick_shadereffect)
-class Q_QUICK_EXPORT QQuickItemLayer : public QObject, public QQuickItemChangeListener
+class Q_QUICK_EXPORT QQuickItemLayer : public QObject,
+ public QSafeQuickItemChangeListener<QQuickItemLayer>
{
Q_OBJECT
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL)
@@ -322,6 +325,30 @@ public:
};
Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
+ friend inline QDebug &operator<<(QDebug &dbg, QQuickItemPrivate::ChangeTypes types) {
+#define CHANGETYPE_OUTPUT(Type) if (types & QQuickItemPrivate::Type) { dbg << first << #Type ; first = '|'; }
+ QDebugStateSaver state(dbg);
+ dbg.noquote().nospace();
+ if (types == QQuickItemPrivate::AllChanges) {
+ dbg << " AllChanges";
+ } else {
+ char first = ' ';
+ CHANGETYPE_OUTPUT(Geometry);
+ CHANGETYPE_OUTPUT(SiblingOrder);
+ CHANGETYPE_OUTPUT(Visibility);
+ CHANGETYPE_OUTPUT(Opacity);
+ CHANGETYPE_OUTPUT(Destroyed);
+ CHANGETYPE_OUTPUT(Parent);
+ CHANGETYPE_OUTPUT(Children);
+ CHANGETYPE_OUTPUT(Rotation);
+ CHANGETYPE_OUTPUT(ImplicitWidth);
+ CHANGETYPE_OUTPUT(ImplicitHeight);
+ CHANGETYPE_OUTPUT(Enabled);
+ CHANGETYPE_OUTPUT(Focus);
+#undef CHANGETYPE_OUTPUT
+ }
+ return dbg;
+ }
struct ChangeListener {
using ChangeTypes = QQuickItemPrivate::ChangeTypes;
@@ -355,17 +382,35 @@ public:
template <typename Fn, typename ...Args>
void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args)
{
+ Q_Q(QQuickItem);
if (changeListeners.isEmpty())
return;
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ Q_ASSERT(change.listener);
if (change.types & changeTypes) {
+#ifdef QT_BUILD_INTERNAL
+ if (changeTypes == AllChanges && change.listener->anchorPrivate() == nullptr) {
+ // Nothing to worry about as long as the lambdas in ~QQuickItem
+ // don't mess around with the change.listener directly!
+ } else if (change.listener->baseDeleted(q)) {
+ auto output = qCritical();
+ output.noquote();
+ output << "Listener already tagged as destroyed when called!"
+ << "\n\tListener:" << change.listener->debugName()
+ << "\n\tChanges:" << change.types
+ << "\n\tCaller: " << q
+ << "\n\tChanges:" << changeTypes;
+ }
+#endif
if constexpr (std::is_member_function_pointer_v<Fn>)
(change.listener->*function)(args...);
else
function(change, args...);
}
+ if (changeTypes & QQuickItemPrivate::Destroyed)
+ change.listener->removeSourceItem(q);
}
}
diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h
index d8056ceb5a..0b7c99b877 100644
--- a/src/quick/items/qquickitemchangelistener_p.h
+++ b/src/quick/items/qquickitemchangelistener_p.h
@@ -15,6 +15,8 @@
// We mean it.
//
+#include <QtCore/qxptype_traits.h>
+#include <QtQml/private/qqmldata_p.h>
#include <QtQuick/private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -103,6 +105,111 @@ public:
virtual void itemTransformChanged(QQuickItem *) {}
virtual QQuickAnchorsPrivate *anchorPrivate() { return nullptr; }
+ virtual bool baseDeleted(const QObject *caller) const
+ {
+ if (auto ptr = dynamic_cast<const QObjectPrivate *>(this))
+ return ptr->q_ptr != caller && QQmlData::wasDeleted(ptr);
+ return false;
+ }
+ virtual QString debugName() const {
+ return QStringLiteral("QQuickItemChangeListener(0x%1)").arg(quintptr(this), 0, 16);
+ }
+ virtual void addSourceItem(QQuickItem *) {}
+ virtual void removeSourceItem(QQuickItem *) {}
+};
+
+/*!
+ \internal
+
+ Helper class using CRTP to add tracking of listeners to a
+ QQuickItemChangeListener implementation. Instantiated with the
+ class that implements the QQuickItemChangeListener interface, like
+
+ \code
+ class QQuickThingPrivate : public QQuickItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickThingPrivate>
+ \endcode
+
+ When destroyed, QSafeQuickItemChangeListener will emit warning messages
+ in \c{-developer-build} configurations when listeners are still registered.
+ As the listener is at this point partially destroyed, any call to the
+ listener interface might result in undefined behavior, such as use-after-free.
+
+ Notifications to registered listeners will in addition check if the listener
+ is already in the destructor, and warn if that's the case. The \c{baseDeleted}
+ override checks for an \c inDestructor or \c wasDeleted data member of the
+ class implementing the QSafeQuickItemChangeListener interface.
+*/
+template<typename Self>
+class QSafeQuickItemChangeListener : public QQuickItemChangeListener
+{
+public:
+ ~QSafeQuickItemChangeListener() override
+ {
+#ifdef QT_BUILD_INTERNAL
+ for (const auto &sourceItem : std::as_const(m_sourceItems)) {
+ if (sourceItem)
+ qCritical() << "Change Listener is still registered with item" << sourceItem;
+ }
+#endif
+ }
+
+ template <typename T>
+ using InDestructorTest = decltype(T::inDestructor);
+ template <typename T>
+ using WasDeletedTest = decltype(T::wasDeleted);
+
+ bool baseDeleted(const QObject *caller) const override
+ {
+ Q_UNUSED(caller);
+ const Self *self = static_cast<const Self *>(this);
+ if constexpr (qxp::is_detected_v<InDestructorTest, Self>) {
+ bool same = false;
+ if constexpr (std::is_convertible_v<Self *, QObjectPrivate *>)
+ same = self->q_ptr == caller;
+ return !same && self->inDestructor;
+ } else if constexpr (qxp::is_detected_v<WasDeletedTest, Self>) {
+ bool same = false;
+ if constexpr (std::is_convertible_v<Self *, QObjectPrivate *>)
+ same = self->q_ptr == caller;
+ return !same && self->wasDeleted;
+ } else if constexpr (std::is_convertible_v<Self *, QQuickItem *>) {
+ return self != caller && QQmlData::wasDeleted(self);
+ } else if constexpr (std::is_convertible_v<Self *, QObject *>) {
+ return self != caller && QQmlData::wasDeleted(self);
+ } else {
+ static_assert(QtPrivate::type_dependent_false<Self>(),
+ "Don't know where destruction state is stored");
+ }
+ }
+
+ QString debugName() const override
+ {
+ QString result;
+ QDebug dbg(&result);
+ dbg.nospace().noquote();
+ const Self *self = static_cast<const Self *>(this);
+ if constexpr (std::is_convertible_v<Self *, QObject *>) {
+ dbg << self;
+ } else if constexpr (std::is_convertible_v<Self *, QObjectPrivate *>) {
+ dbg << self->q_ptr << "::d_ptr";
+ } else {
+ dbg << QMetaType::fromType<Self>().name() << '('
+ << reinterpret_cast<const void *>(self) << ')';
+ }
+ return result;
+ }
+
+#ifdef QT_BUILD_INTERNAL
+ void addSourceItem(QQuickItem *item) override {
+ m_sourceItems << item;
+ }
+ void removeSourceItem(QQuickItem *item) override {
+ m_sourceItems.removeAll(item);
+ }
+
+ QList<QPointer<QQuickItem>> m_sourceItems;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 39011f1162..eba75ca27f 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -41,7 +41,8 @@ private:
};
class QQmlContext;
-class QQuickLoaderPrivate : public QQuickImplicitSizeItemPrivate, public QQuickItemChangeListener
+class QQuickLoaderPrivate : public QQuickImplicitSizeItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickLoaderPrivate>
{
Q_DECLARE_PUBLIC(QQuickLoader)
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index f23b03f6c2..c684cc384c 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -37,7 +37,8 @@ QT_BEGIN_NAMESPACE
class QQmlOpenMetaObjectType;
class QQuickPathViewAttached;
-class QQuickPathViewPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class QQuickPathViewPrivate : public QQuickItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickPathViewPrivate>
{
Q_DECLARE_PUBLIC(QQuickPathView)
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 004a0f5ed1..d09a8351b8 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -32,7 +32,8 @@ QT_BEGIN_NAMESPACE
class QQuickItemViewTransitioner;
-class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate, public QQuickItemChangeListener
+class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickBasePositionerPrivate>
{
Q_DECLARE_PUBLIC(QQuickBasePositioner)
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index ea9a6842e1..a11dca173a 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -39,7 +39,8 @@ class QSGSimpleRectNode;
class QQuickShaderEffectSourceTextureProvider;
-class Q_QUICK_EXPORT QQuickShaderEffectSource : public QQuickItem, public QQuickItemChangeListener
+class Q_QUICK_EXPORT QQuickShaderEffectSource : public QQuickItem,
+ public QSafeQuickItemChangeListener<QQuickShaderEffectSource>
{
Q_OBJECT
Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 1ad1897af3..19f069a193 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -36,7 +36,7 @@ class QQuickItem;
class QQmlComponent;
class Q_QUICK_EXPORT QQuickViewPrivate : public QQuickWindowPrivate,
- public QQuickItemChangeListener
+ public QSafeQuickItemChangeListener<QQuickViewPrivate>
{
Q_DECLARE_PUBLIC(QQuickView)
public:
diff --git a/src/quickcontrols/qquickattachedpropertypropagator.cpp b/src/quickcontrols/qquickattachedpropertypropagator.cpp
index 0d3b4785bf..5485ca86f7 100644
--- a/src/quickcontrols/qquickattachedpropertypropagator.cpp
+++ b/src/quickcontrols/qquickattachedpropertypropagator.cpp
@@ -245,7 +245,8 @@ static QQuickItem *findAttachedItem(QObject *parent)
return item;
}
-class QQuickAttachedPropertyPropagatorPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickAttachedPropertyPropagatorPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickAttachedPropertyPropagatorPrivate>
{
public:
Q_DECLARE_PUBLIC(QQuickAttachedPropertyPropagator)
diff --git a/src/quickcontrolsimpl/qquickiconlabel_p_p.h b/src/quickcontrolsimpl/qquickiconlabel_p_p.h
index 8efdd56e21..e51d2d5309 100644
--- a/src/quickcontrolsimpl/qquickiconlabel_p_p.h
+++ b/src/quickcontrolsimpl/qquickiconlabel_p_p.h
@@ -24,7 +24,8 @@ QT_BEGIN_NAMESPACE
class QQuickIconImage;
class QQuickMnemonicLabel;
-class Q_AUTOTEST_EXPORT QQuickIconLabelPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_AUTOTEST_EXPORT QQuickIconLabelPrivate : public QQuickItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickIconLabelPrivate>
{
Q_DECLARE_PUBLIC(QQuickIconLabel)
diff --git a/src/quicktemplates/qquickaction_p_p.h b/src/quicktemplates/qquickaction_p_p.h
index 8bee904220..a777790dac 100644
--- a/src/quicktemplates/qquickaction_p_p.h
+++ b/src/quicktemplates/qquickaction_p_p.h
@@ -28,7 +28,8 @@ QT_BEGIN_NAMESPACE
class QShortcutEvent;
class QQuickActionGroup;
-class QQuickActionPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickActionPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickActionPrivate>
{
Q_DECLARE_PUBLIC(QQuickAction)
diff --git a/src/quicktemplates/qquickapplicationwindow.cpp b/src/quicktemplates/qquickapplicationwindow.cpp
index 66a264ff66..e43ebc83d8 100644
--- a/src/quicktemplates/qquickapplicationwindow.cpp
+++ b/src/quicktemplates/qquickapplicationwindow.cpp
@@ -93,7 +93,7 @@ static const QQuickItemPrivate::ChangeTypes ItemChanges = QQuickItemPrivate::Vis
class Q_QUICKTEMPLATES2_EXPORT QQuickApplicationWindowPrivate
: public QQuickWindowQmlImplPrivate
- , public QQuickItemChangeListener
+ , public QSafeQuickItemChangeListener<QQuickApplicationWindowPrivate>
{
Q_DECLARE_PUBLIC(QQuickApplicationWindow)
diff --git a/src/quicktemplates/qquickcontrol_p_p.h b/src/quicktemplates/qquickcontrol_p_p.h
index 24d0507670..2bd1bdc095 100644
--- a/src/quicktemplates/qquickcontrol_p_p.h
+++ b/src/quicktemplates/qquickcontrol_p_p.h
@@ -35,7 +35,8 @@ Q_DECLARE_LOGGING_CATEGORY(lcItemManagement)
class QQuickAccessibleAttached;
-class Q_QUICKTEMPLATES2_EXPORT QQuickControlPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICKTEMPLATES2_EXPORT QQuickControlPrivate : public QQuickItemPrivate,
+ public QSafeQuickItemChangeListener<QQuickControlPrivate>
#if QT_CONFIG(accessibility)
, public QAccessible::ActivationObserver
#endif
diff --git a/src/quicktemplates/qquicklabel_p_p.h b/src/quicktemplates/qquicklabel_p_p.h
index 03ee6acef2..1c15fb9e03 100644
--- a/src/quicktemplates/qquicklabel_p_p.h
+++ b/src/quicktemplates/qquicklabel_p_p.h
@@ -27,7 +27,8 @@
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QQuickLabelPrivate : public QQuickTextPrivate, public QQuickItemChangeListener
+class Q_AUTOTEST_EXPORT QQuickLabelPrivate : public QQuickTextPrivate,
+ public QSafeQuickItemChangeListener<QQuickLabelPrivate>
#if QT_CONFIG(accessibility)
, public QAccessible::ActivationObserver
#endif
diff --git a/src/quicktemplates/qquickoverlay_p_p.h b/src/quicktemplates/qquickoverlay_p_p.h
index 3d96540d45..47a7e1b4a9 100644
--- a/src/quicktemplates/qquickoverlay_p_p.h
+++ b/src/quicktemplates/qquickoverlay_p_p.h
@@ -27,7 +27,7 @@ QT_BEGIN_NAMESPACE
class QQuickPopup;
class Q_AUTOTEST_EXPORT QQuickOverlayPrivate : public QQuickItemPrivate,
- public QQuickItemChangeListener
+ public QSafeQuickItemChangeListener<QQuickOverlayPrivate>
{
public:
Q_DECLARE_PUBLIC(QQuickOverlay)
diff --git a/src/quicktemplates/qquickpopup_p_p.h b/src/quicktemplates/qquickpopup_p_p.h
index ceb944a53e..c168ea210a 100644
--- a/src/quicktemplates/qquickpopup_p_p.h
+++ b/src/quicktemplates/qquickpopup_p_p.h
@@ -55,7 +55,7 @@ private:
class Q_QUICKTEMPLATES2_EXPORT QQuickPopupPrivate
: public QObjectPrivate
- , public QQuickItemChangeListener
+ , public QSafeQuickItemChangeListener<QQuickPopupPrivate>
, public QQuickPaletteProviderPrivateBase<QQuickPopup, QQuickPopupPrivate>
{
public:
diff --git a/src/quicktemplates/qquickscrollbar_p_p.h b/src/quicktemplates/qquickscrollbar_p_p.h
index 2a834ce71e..5f5f9ca237 100644
--- a/src/quicktemplates/qquickscrollbar_p_p.h
+++ b/src/quicktemplates/qquickscrollbar_p_p.h
@@ -80,7 +80,8 @@ public:
QQuickScrollBar::Policy policy = QQuickScrollBar::AsNeeded;
};
-class QQuickScrollBarAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickScrollBarAttachedPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickScrollBarAttachedPrivate>
{
public:
static QQuickScrollBarAttachedPrivate *get(QQuickScrollBarAttached *attached)
diff --git a/src/quicktemplates/qquickscrollindicator.cpp b/src/quicktemplates/qquickscrollindicator.cpp
index 5fbf768993..2c94181471 100644
--- a/src/quicktemplates/qquickscrollindicator.cpp
+++ b/src/quicktemplates/qquickscrollindicator.cpp
@@ -396,7 +396,8 @@ qreal QQuickScrollIndicator::visualPosition() const
return d->visualArea().position;
}
-class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate,
+ public QSafeQuickItemChangeListener<QQuickScrollIndicatorAttachedPrivate>
{
public:
void activateHorizontal();
diff --git a/src/quicktemplates/qquickstackview_p_p.h b/src/quicktemplates/qquickstackview_p_p.h
index 7d6ee50b1b..4ae849aa20 100644
--- a/src/quicktemplates/qquickstackview_p_p.h
+++ b/src/quicktemplates/qquickstackview_p_p.h
@@ -90,7 +90,7 @@ public:
class QQuickStackViewAttachedPrivate : public QObjectPrivate
//#if QT_CONFIG(quick_viewtransitions)
- , public QQuickItemChangeListener
+ , public QSafeQuickItemChangeListener<QQuickStackViewAttachedPrivate>
//#endif
{
Q_DECLARE_PUBLIC(QQuickStackViewAttached)
diff --git a/src/quicktemplates/qquicktextarea_p_p.h b/src/quicktemplates/qquicktextarea_p_p.h
index 849c22b97c..0f611302ad 100644
--- a/src/quicktemplates/qquicktextarea_p_p.h
+++ b/src/quicktemplates/qquicktextarea_p_p.h
@@ -28,7 +28,8 @@ QT_BEGIN_NAMESPACE
class QQuickFlickable;
-class QQuickTextAreaPrivate : public QQuickTextEditPrivate, public QQuickItemChangeListener
+class QQuickTextAreaPrivate : public QQuickTextEditPrivate,
+ public QSafeQuickItemChangeListener<QQuickTextAreaPrivate>
{
public:
Q_DECLARE_PUBLIC(QQuickTextArea)
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 958dc4d81e..bde08bfc6a 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -40,7 +40,7 @@ class QQuickRenderControl;
class QQuickWidgetPrivate
: public QWidgetPrivate,
- public QQuickItemChangeListener
+ public QSafeQuickItemChangeListener<QQuickWidgetPrivate>
{
Q_DECLARE_PUBLIC(QQuickWidget)
public: