diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 61b475153a..ec2112a53b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -6373,7 +6373,7 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) for (int ii = 0; ii < childItems.count(); ++ii) childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible); - itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible); + itemChange(QQuickItem::ItemVisibleHasChanged, bool(effectiveVisible)); #if QT_CONFIG(accessibility) if (isAccessible) { QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide); @@ -6432,7 +6432,7 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec QQuickDeliveryAgentPrivate::DontChangeSubFocusItem); } - itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable); + itemChange(QQuickItem::ItemEnabledHasChanged, bool(effectiveEnable)); emit q->enabledChanged(); } @@ -6764,7 +6764,7 @@ void QQuickItem::setAntialiasing(bool aa) d->antialiasing = aa; d->dirty(QQuickItemPrivate::Antialiasing); - d->itemChange(ItemAntialiasingHasChanged, d->antialiasing); + d->itemChange(ItemAntialiasingHasChanged, bool(d->antialiasing)); emit antialiasingChanged(antialiasing()); } @@ -8217,12 +8217,13 @@ void QQuickItem::setKeepTouchGrab(bool keep) bool QQuickItem::contains(const QPointF &point) const { Q_D(const QQuickItem); - if (d->mask) { - if (d->quickMask) - return d->quickMask->contains(point - d->quickMask->position()); + if (d->extra.isAllocated() && d->extra->mask) { + if (auto quickMask = qobject_cast(d->extra->mask)) + return quickMask->contains(point - quickMask->position()); bool res = false; - d->extra->maskContains.invoke(d->mask, + QMetaMethod maskContains = d->extra->mask->metaObject()->method(d->extra->maskContainsIndex); + maskContains.invoke(d->extra->mask, Qt::DirectConnection, Q_RETURN_ARG(bool, res), Q_ARG(QPointF, point)); @@ -8300,33 +8301,44 @@ bool QQuickItem::contains(const QPointF &point) const QObject *QQuickItem::containmentMask() const { Q_D(const QQuickItem); - return d->mask.data(); + if (!d->extra.isAllocated()) + return nullptr; + return d->extra->mask.data(); } void QQuickItem::setContainmentMask(QObject *mask) { Q_D(QQuickItem); + const bool extraDataExists = d->extra.isAllocated(); // an Item can't mask itself (to prevent infinite loop in contains()) - if (d->mask.data() == mask || mask == static_cast(this)) + if (mask == static_cast(this)) + return; + // mask is null, and we had no mask + if (!extraDataExists && !mask) + return; + // mask is non-null and the same + if (extraDataExists && d->extra->mask == mask) return; - QQuickItem *quickMask = qobject_cast(d->mask); + QQuickItem *quickMask = d->extra.isAllocated() ? qobject_cast(d->extra->mask) + : nullptr; if (quickMask) { QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); maskPrivate->registerAsContainmentMask(this, false); // removed from use as my mask } + if (!extraDataExists) + d->extra.value(); // ensure extra exists if (mask) { int methodIndex = mask->metaObject()->indexOfMethod(QByteArrayLiteral("contains(QPointF)")); if (methodIndex < 0) { qmlWarning(this) << QStringLiteral("QQuickItem: Object set as mask does not have an invokable contains method, ignoring it."); return; } - d->extra.value().maskContains = mask->metaObject()->method(methodIndex); + d->extra->maskContainsIndex = methodIndex; } - d->mask = mask; + d->extra->mask = mask; quickMask = qobject_cast(mask); - d->quickMask = quickMask; if (quickMask) { QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); maskPrivate->registerAsContainmentMask(this, true); // telling maskPrivate that "this" is using it as mask diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 4e5e5bb34a..f63834be0f 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -378,6 +378,11 @@ public: int hideRefCount; // updated recursively for child items as well int recursiveEffectRefCount; + // Mask contains() method index + int maskContainsIndex; + + // Contains mask + QPointer mask; QSGOpacityNode *opacityNode; QQuickDefaultClipNode *clipNode; @@ -385,9 +390,6 @@ public: // subsceneDeliveryAgent is set only if this item is the root of a subscene, not on all items within. QQuickDeliveryAgent *subsceneDeliveryAgent = nullptr; - // Mask contains() method - QMetaMethod maskContains; - QObjectList resourcesList; // Although acceptedMouseButtons is inside ExtraData, we actually store @@ -397,7 +399,7 @@ public: Qt::MouseButtons acceptedMouseButtons; Qt::MouseButtons acceptedMouseButtonsWithoutHandlers; - QQuickItem::TransformOrigin origin:5; + uint origin:5; // QQuickItem::TransformOrigin uint transparentForPositioner : 1; // 26 bits padding @@ -410,9 +412,6 @@ public: Q_DECLARE_FLAGS(ExtraDataTags, ExtraDataTag) QLazilyAllocated extra; - // Contains mask - QPointer mask; - QPointer quickMask; // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false) virtual void registerAsContainmentMask(QQuickItem * /* maskedItem */, bool /* set */) { } @@ -436,53 +435,53 @@ public: // Bit 0 quint32 flags:7; - bool widthValidFlag:1; - bool heightValidFlag:1; - bool componentComplete:1; - bool keepMouse:1; - bool keepTouch:1; - bool hoverEnabled:1; - bool smooth:1; - bool antialiasing:1; - bool focus:1; + quint32 widthValidFlag:1; + quint32 heightValidFlag:1; + quint32 componentComplete:1; + quint32 keepMouse:1; + quint32 keepTouch:1; + quint32 hoverEnabled:1; + quint32 smooth:1; + quint32 antialiasing:1; + quint32 focus:1; // Bit 16 - bool activeFocus:1; - bool notifiedFocus:1; - bool notifiedActiveFocus:1; - bool filtersChildMouseEvents:1; - bool explicitVisible:1; - bool effectiveVisible:1; - bool explicitEnable:1; - bool effectiveEnable:1; - bool polishScheduled:1; - bool inheritedLayoutMirror:1; - bool effectiveLayoutMirror:1; - bool isMirrorImplicit:1; - bool inheritMirrorFromParent:1; - bool inheritMirrorFromItem:1; - bool isAccessible:1; - bool culled:1; + quint32 activeFocus:1; + quint32 notifiedFocus:1; + quint32 notifiedActiveFocus:1; + quint32 filtersChildMouseEvents:1; + quint32 explicitVisible:1; + quint32 effectiveVisible:1; + quint32 explicitEnable:1; + quint32 effectiveEnable:1; + quint32 polishScheduled:1; + quint32 inheritedLayoutMirror:1; + quint32 effectiveLayoutMirror:1; + quint32 isMirrorImplicit:1; + quint32 inheritMirrorFromParent:1; + quint32 inheritMirrorFromItem:1; + quint32 isAccessible:1; + quint32 culled:1; // Bit 32 - bool hasCursor:1; - bool subtreeCursorEnabled:1; - bool subtreeHoverEnabled:1; - bool activeFocusOnTab:1; - bool implicitAntialiasing:1; - bool antialiasingValid:1; + quint32 hasCursor:1; + quint32 subtreeCursorEnabled:1; + quint32 subtreeHoverEnabled:1; + quint32 activeFocusOnTab:1; + quint32 implicitAntialiasing:1; + quint32 antialiasingValid:1; // isTabFence: When true, the item acts as a fence within the tab focus chain. // This means that the item and its children will be skipped from the tab focus // chain when navigating from its parent or any of its siblings. Similarly, // when any of the item's descendants gets focus, the item constrains the tab // focus chain and prevents tabbing outside. - bool isTabFence:1; - bool replayingPressEvent:1; - bool touchEnabled:1; - bool hasCursorHandler:1; + quint32 isTabFence:1; + quint32 replayingPressEvent:1; + quint32 touchEnabled:1; + quint32 hasCursorHandler:1; // set true when this item does not expect events via a subscene delivery agent; false otherwise - bool maybeHasSubsceneDeliveryAgent:1; + quint32 maybeHasSubsceneDeliveryAgent:1; // set true if this item or any child wants QQuickItemPrivate::transformChanged() to visit all children // (e.g. when parent has ItemIsViewport and child has ItemObservesViewport) - bool subtreeTransformChangedEnabled:1; + quint32 subtreeTransformChangedEnabled:1; enum DirtyType { TransformOrigin = 0x00000001, @@ -1002,7 +1001,8 @@ void QQuickItemPrivate::markSortedChildrenDirty(QQuickItem *child) QQuickItem::TransformOrigin QQuickItemPrivate::origin() const { - return extra.isAllocated()?extra->origin:QQuickItem::Center; + return extra.isAllocated() ? QQuickItem::TransformOrigin(extra->origin) + : QQuickItem::Center; } QSGTransformNode *QQuickItemPrivate::itemNode() diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp index 2bb0d52b09..88d411276f 100644 --- a/src/quick/util/qquickdeliveryagent.cpp +++ b/src/quick/util/qquickdeliveryagent.cpp @@ -555,7 +555,7 @@ void QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(QQuickItem **items, int if (item && itemPrivate->notifiedActiveFocus != itemPrivate->activeFocus) { itemPrivate->notifiedActiveFocus = itemPrivate->activeFocus; - itemPrivate->itemChange(QQuickItem::ItemActiveFocusHasChanged, itemPrivate->activeFocus); + itemPrivate->itemChange(QQuickItem::ItemActiveFocusHasChanged, bool(itemPrivate->activeFocus)); itemPrivate->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, item, reason); emit item->activeFocusChanged(itemPrivate->activeFocus); }