aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-12-03 13:27:51 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-12-04 13:49:07 +0100
commit79c3cbe54eac3612bfe28232a765cf93d4abd665 (patch)
tree31f0753c564f698fea8d36ebb9ff63376d5f4d4b /src/quick
parent6254b383309a0c3cd273264466105a7e3599a1ed (diff)
Refactor: move change listener notification logic into helpers
A dozen loops doing more or less the same, all with the comment "intentional copy (QTBUG-54732)", are best factored out into a helper. Most of the loops call a different QQuickItemChangeListener member, so provide a template that expects a pointer to a QQuickItemChangeListener member function. Some loops have some additional logic, so provide a second template that just calls a functor. No functional change, but needed for follow-up fixes to focus reason handling in Qt Quick Controls. Pick-to: 6.2 Change-Id: I6b11e06331da44b288315fc0732009d5f34f539a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickitem.cpp153
-rw-r--r--src/quick/items/qquickitem_p.h27
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h1
3 files changed, 60 insertions, 121 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index fffee1afa0..a6a14d7ce3 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2355,31 +2355,22 @@ QQuickItem::~QQuickItem()
while (!d->childItems.isEmpty())
d->childItems.constFirst()->setParentItem(nullptr);
- if (!d->changeListeners.isEmpty()) {
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor)
- anchor->clearItem(this);
- }
-
- /*
+ d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->clearItem(this);
+ });
+ /*
update item anchors that depended on us unless they are our child (and will also be destroyed),
or our sibling, and our parent is also being destroyed.
*/
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
- anchor->update();
- }
-
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Destroyed)
- change.listener->itemDestroyed(this);
- }
-
- d->changeListeners.clear();
- }
+ d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
+ anchor->update();
+ });
+ d->notifyChangeListeners(QQuickItemPrivate::Destroyed, &QQuickItemChangeListener::itemDestroyed, this);
+ d->changeListeners.clear();
/*
Remove any references our transforms have to us, in case they try to
@@ -3663,14 +3654,7 @@ QQuickAnchors *QQuickItemPrivate::anchors() const
void QQuickItemPrivate::siblingOrderChanged()
{
Q_Q(QQuickItem);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::SiblingOrder) {
- change.listener->itemSiblingOrderChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::SiblingOrder, &QQuickItemChangeListener::itemSiblingOrderChanged, q);
}
QQmlListProperty<QObject> QQuickItemPrivate::data()
@@ -3801,15 +3785,10 @@ void QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeom
change.setWidthChange(newGeometry.width() != oldGeometry.width());
change.setHeightChange(newGeometry.height() != oldGeometry.height());
- if (!d->changeListeners.isEmpty()) {
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &listener : listeners) {
- if (listener.types & QQuickItemPrivate::Geometry) {
- if (change.matches(listener.gTypes))
- listener.listener->itemGeometryChanged(this, change, oldGeometry);
- }
- }
- }
+ d->notifyChangeListeners(QQuickItemPrivate::Geometry, [&](const QQuickItemPrivate::ChangeListener &listener){
+ if (change.matches(listener.gTypes))
+ listener.listener->itemGeometryChanged(this, change, oldGeometry);
+ });
// The notify method takes care of emitting the signal, and also notifies any
// property observers.
@@ -4439,16 +4418,11 @@ void QQuickItem::setBaselineOffset(qreal offset)
d->baselineOffset = offset;
- if (!d->changeListeners.isEmpty()) {
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Geometry) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor)
- anchor->updateVerticalAnchors();
- }
- }
- }
+ d->notifyChangeListeners(QQuickItemPrivate::Geometry, [](const QQuickItemPrivate::ChangeListener &change){
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->updateVerticalAnchors();
+ });
if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
@@ -6617,26 +6591,12 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
q->itemChange(change, data);
if (!subtreeTransformChangedEnabled)
subtreeTransformChangedEnabled = true;
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Children) {
- change.listener->itemChildAdded(q, data.item);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildAdded, q, data.item);
break;
}
case QQuickItem::ItemChildRemovedChange: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Children) {
- change.listener->itemChildRemoved(q, data.item);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildRemoved, q, data.item);
break;
}
case QQuickItem::ItemSceneChange:
@@ -6644,50 +6604,22 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break;
case QQuickItem::ItemVisibleHasChanged: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Visibility) {
- change.listener->itemVisibilityChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Visibility, &QQuickItemChangeListener::itemVisibilityChanged, q);
break;
}
case QQuickItem::ItemEnabledHasChanged: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Enabled) {
- change.listener->itemEnabledChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Enabled, &QQuickItemChangeListener::itemEnabledChanged, q);
break;
}
case QQuickItem::ItemParentHasChanged: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Parent) {
- change.listener->itemParentChanged(q, data.item);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Parent, &QQuickItemChangeListener::itemParentChanged, q, data.item);
break;
}
case QQuickItem::ItemOpacityHasChanged: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Opacity) {
- change.listener->itemOpacityChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Opacity, &QQuickItemChangeListener::itemOpacityChanged, q);
break;
}
case QQuickItem::ItemActiveFocusHasChanged:
@@ -6695,14 +6627,7 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break;
case QQuickItem::ItemRotationHasChanged: {
q->itemChange(change, data);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Rotation) {
- change.listener->itemRotationChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::Rotation, &QQuickItemChangeListener::itemRotationChanged, q);
break;
}
case QQuickItem::ItemAntialiasingHasChanged:
@@ -7114,14 +7039,7 @@ void QQuickItem::resetWidth()
void QQuickItemPrivate::implicitWidthChanged()
{
Q_Q(QQuickItem);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::ImplicitWidth) {
- change.listener->itemImplicitWidthChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::ImplicitWidth, &QQuickItemChangeListener::itemImplicitWidthChanged, q);
emit q->implicitWidthChanged();
}
@@ -7330,14 +7248,7 @@ void QQuickItem::resetHeight()
void QQuickItemPrivate::implicitHeightChanged()
{
Q_Q(QQuickItem);
- if (!changeListeners.isEmpty()) {
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::ImplicitHeight) {
- change.listener->itemImplicitHeightChanged(q);
- }
- }
- }
+ notifyChangeListeners(QQuickItemPrivate::ImplicitHeight, &QQuickItemChangeListener::itemImplicitHeightChanged, q);
emit q->implicitHeightChanged();
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 51ef850d5f..576d392a26 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -331,6 +331,7 @@ public:
ImplicitWidth = 0x100,
ImplicitHeight = 0x200,
Enabled = 0x400,
+ AllChanges = 0xFFFFFFFF
};
Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
@@ -358,6 +359,32 @@ public:
QQuickGeometryChange gTypes; //NOTE: not used for ==
};
+ // call QQuickItemChangeListener PMF
+ template <typename Fn, typename ...Args>
+ void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args)
+ {
+ if (changeListeners.isEmpty())
+ return;
+
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & changeTypes)
+ (change.listener->*function)(args...);
+ }
+ }
+ // call functor
+ template <typename Fn>
+ void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function) {
+ if (changeListeners.isEmpty())
+ return;
+
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & changeTypes)
+ function(change);
+ }
+ }
+
struct ExtraData {
ExtraData();
diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h
index 31d06c9983..91e2d69cc0 100644
--- a/src/quick/items/qquickitemchangelistener_p.h
+++ b/src/quick/items/qquickitemchangelistener_p.h
@@ -134,6 +134,7 @@ public:
virtual void itemRotationChanged(QQuickItem *) {}
virtual void itemImplicitWidthChanged(QQuickItem *) {}
virtual void itemImplicitHeightChanged(QQuickItem *) {}
+ virtual void itemFocusChanged(QQuickItem *, Qt::FocusReason /* reason */) {}
virtual QQuickAnchorsPrivate *anchorPrivate() { return nullptr; }
};