diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-04-16 15:47:14 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2024-12-01 18:41:22 +0100 |
commit | a6c8de2780b6dface7504b5423e064e026a6e564 (patch) | |
tree | 4ff3283315e6679f0550c4d602dc5bce2c9aec2f | |
parent | d8a55297c25ff01ffe371bf83631a69db0f521d8 (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>
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: |