-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.4
-
-
ae6546c24 (dev), 3dee2840f (6.4), 8b2187829 (6.5)
In QQuickItemLayer::updateOpacity there is a check for the effect which is a debug assert only on the assumption that calling the function with no effect would not be valid.
void QQuickItemLayer::updateOpacity()
{
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
Q_ASSERT(l);
l->setOpacity(m_item->opacity());
}
This assumption may not always be correct.
Here's the valid case where it is broken. The sequence is:
1. Have an item with a layer disabled.
2. Attach a QQuickItemChangeListener instance which looks for opacity changes
3. Enable the layer on the item. This means you have two listeners, and the layer is the second in the internal list (important).
4. Setup the first listener so when it is invoked, it disables the layer on the item.
5. Change the opacity of the item
Sample code that implements this is attached ( qtbug109506.zip
)
The effect is that:
1. The first listener disables the layer on the item
2. QQuickItemLayer::deactivate is called, which removes the layer from the changeListeners list, and deletes the effects it uses.
3. QQuickItemLayer::itemOpacityChanged is called, because the loop takes a copy so #2 is too late.
Can either the assert be changing to a proper release mode check or put the protection inside QQuickItemLayer::itemOpacityChanged()? Other functions in the class are also susceptible to this issue, such as QQuickItemLayer::updateGeometry().
| For Gerrit Dashboard: QTBUG-109506 | ||||||
|---|---|---|---|---|---|---|
| # | Subject | Branch | Project | Status | CR | V |
| 449775,3 | Change asserts to runtime checking | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
| 450183,2 | Change asserts to runtime checking | 6.5 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
| 450184,2 | Change asserts to runtime checking | 6.4 | qt/qtdeclarative | Status: MERGED | +2 | 0 |