aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-08-17 18:16:41 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-08-18 12:01:24 +0000
commit7c07c60ff17974621fea932a18cc2e652d17ab78 (patch)
tree3644adcc9cb1f4862a0fc4d9411d38ddb219a83a /src/quicktemplates2
parent1fbc51b4f285692206a4c0cdf132963638919e6e (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.cpp1
-rw-r--r--src/quicktemplates2/qquickmenu_p_p.h3
-rw-r--r--src/quicktemplates2/qquickpopup.cpp23
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h4
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;