diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-08-17 18:16:41 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-08-18 12:01:24 +0000 |
commit | 7c07c60ff17974621fea932a18cc2e652d17ab78 (patch) | |
tree | 3644adcc9cb1f4862a0fc4d9411d38ddb219a83a /src/quicktemplates2 | |
parent | 1fbc51b4f285692206a4c0cdf132963638919e6e (diff) |
QQuickPopup: don't keep a reference to a destroyed parent
Move the itemDestroyed() listener from QQuickPopupPositioner, which is
only active while the popup is visible, to QQuickPopupPrivate instead.
This way the popup gets a notification when the parent gets destroyed
while the popup is hidden.
Task-number: QTBUG-55347
Change-Id: Ic72206cc05996c23062e814799a030c369fc6288
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r-- | src/quicktemplates2/qquickmenu.cpp | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenu_p_p.h | 3 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 23 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 4 |
4 files changed, 15 insertions, 16 deletions
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index f4fb26e7..bc594c03 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -196,6 +196,7 @@ void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *) void QQuickMenuPrivate::itemDestroyed(QQuickItem *item) { + QQuickPopupPrivate::itemDestroyed(item); int index = contentModel->indexOf(item, nullptr); if (index != -1) removeItem(index, item); diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h index 64260508..c27e6631 100644 --- a/src/quicktemplates2/qquickmenu_p_p.h +++ b/src/quicktemplates2/qquickmenu_p_p.h @@ -50,7 +50,6 @@ #include <QtCore/qvector.h> #include <QtCore/qpointer.h> -#include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQuickTemplates2/private/qquickpopup_p_p.h> @@ -58,7 +57,7 @@ QT_BEGIN_NAMESPACE class QQmlObjectModel; -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate, public QQuickItemChangeListener +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate { Q_DECLARE_PUBLIC(QQuickMenu) diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 57087c0a..2af90d24 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -115,8 +115,7 @@ static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPriv | QQuickItemPrivate::Children; static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry - | QQuickItemPrivate::Parent - | QQuickItemPrivate::Destroyed; + | QQuickItemPrivate::Parent; QQuickPopupPrivate::QQuickPopupPrivate() : QObjectPrivate() @@ -551,14 +550,11 @@ void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child removeAncestorListeners(item); } -void QQuickPopupPositioner::itemDestroyed(QQuickItem *item) +void QQuickPopupPrivate::itemDestroyed(QQuickItem *item) { - Q_ASSERT(m_parentItem == item); - - m_parentItem = nullptr; - m_popup->parentItem = nullptr; - QQuickItemPrivate::get(item)->removeItemChangeListener(this, ItemChangeTypes); - removeAncestorListeners(item->parentItem()); + Q_Q(QQuickPopup); + if (item == parentItem) + q->setParentItem(nullptr); } void QQuickPopupPrivate::reposition() @@ -768,8 +764,7 @@ QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent) QQuickPopup::~QQuickPopup() { Q_D(QQuickPopup); - d->setWindow(nullptr); - d->positioner.setParentItem(nullptr); + setParentItem(nullptr); delete d->popupItem; } @@ -1405,13 +1400,17 @@ void QQuickPopup::setParentItem(QQuickItem *parent) if (d->parentItem == parent) return; - if (d->parentItem) + if (d->parentItem) { QObjectPrivate::disconnect(d->parentItem, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow); + QQuickItemPrivate::get(d->parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Destroyed); + } d->parentItem = parent; if (d->positioner.parentItem()) d->positioner.setParentItem(parent); if (parent) { QObjectPrivate::connect(parent, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow); + QQuickItemPrivate::get(d->parentItem)->addItemChangeListener(d, QQuickItemPrivate::Destroyed); + QQuickControlPrivate *p = QQuickControlPrivate::get(d->popupItem); p->resolveFont(); if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(parent->window())) diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index ee9c83d5..80cb8522 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -136,7 +136,6 @@ protected: void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) override; void itemParentChanged(QQuickItem *, QQuickItem *parent) override; void itemChildRemoved(QQuickItem *, QQuickItem *child) override; - void itemDestroyed(QQuickItem *item) override; private: void removeAncestorListeners(QQuickItem *item); @@ -148,7 +147,7 @@ private: QQuickPopupPrivate *m_popup; }; -class QQuickPopupPrivate : public QObjectPrivate +class QQuickPopupPrivate : public QObjectPrivate, public QQuickItemChangeListener { Q_DECLARE_PUBLIC(QQuickPopup) @@ -177,6 +176,7 @@ public: void setBottomMargin(qreal value, bool reset = false); void setWindow(QQuickWindow *window); + void itemDestroyed(QQuickItem *item) override; bool focus; bool modal; |