aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@viroteck.net>2014-10-15 14:13:53 +0200
committerRobin Burchell <robin.burchell@viroteck.net>2014-10-29 22:25:48 +0100
commit4b73acd49cc4f08a5169efba8169f968094063e0 (patch)
tree38db09cd6bc7bc017d500c237e5d11ed7258bc00 /src/quick
parentaed97ab52133a06f998bf481be2b0d08b2107185 (diff)
Move from a count of cursors, to storing whether or not a subtree has a cursor.
Calculation of this is going to be slower (of course) as we have to recurse the children, but this only happens when unsetting a cursor or removing a child item from a tree that had a cursor. On the other hand, wasting 4 bytes per ExtraData plus padding is quite a large concern, and it was also forcing allocation of ExtraData for an entire tree that had a cursor set. This also reduces the size of ExtraData from 152 down to 144 bytes through reordering of members on x86_64. Change-Id: Iab14ee71c762285bf4448fc86399070263eb118d Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickitem.cpp39
-rw-r--r--src/quick/items/qquickitem_p.h8
-rw-r--r--src/quick/items/qquickwindow.cpp5
3 files changed, 33 insertions, 19 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index b68a9b5455..3aff1f0dfc 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2722,8 +2722,11 @@ void QQuickItemPrivate::addChild(QQuickItem *child)
#ifndef QT_NO_CURSOR
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
- if (childPrivate->extra.isAllocated())
- incrementCursorCount(childPrivate->extra.value().numItemsWithCursor);
+
+ // if the added child has a cursor and we do not currently have any children
+ // with cursors, bubble the notification up
+ if (childPrivate->hasCursorInChild && !hasCursorInChild)
+ setHasCursorInChild(true);
#endif
markSortedChildrenDirty(child);
@@ -2745,8 +2748,10 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
#ifndef QT_NO_CURSOR
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
- if (childPrivate->extra.isAllocated())
- incrementCursorCount(-childPrivate->extra.value().numItemsWithCursor);
+
+ // turn it off, if nothing else is using it
+ if (childPrivate->hasCursorInChild && hasCursorInChild)
+ setHasCursorInChild(false);
#endif
markSortedChildrenDirty(child);
@@ -2948,6 +2953,7 @@ QQuickItemPrivate::QQuickItemPrivate()
, isAccessible(false)
, culled(false)
, hasCursor(false)
+ , hasCursorInChild(false)
, activeFocusOnTab(false)
, implicitAntialiasing(false)
, antialiasingValid(false)
@@ -6731,15 +6737,27 @@ void QQuickItem::setAcceptHoverEvents(bool enabled)
d->hoverEnabled = enabled;
}
-void QQuickItemPrivate::incrementCursorCount(int delta)
+void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
{
#ifndef QT_NO_CURSOR
Q_Q(QQuickItem);
- extra.value().numItemsWithCursor += delta;
+
+ // if we're asked to turn it off (because of an unsetcursor call, or a node
+ // removal) then we should check our children and make sure it's really ok
+ // to turn it off.
+ if (!hasCursor && hasCursorInChild) {
+ foreach (QQuickItem *otherChild, childItems) {
+ QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild);
+ if (otherChildPrivate->hasCursorInChild)
+ return; // nope! sorry, something else wants it kept on.
+ }
+ }
+
+ hasCursorInChild = hasCursor;
QQuickItem *parent = q->parentItem();
if (parent) {
QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
- parentPrivate->incrementCursorCount(delta);
+ parentPrivate->setHasCursorInChild(hasCursor);
}
#endif
}
@@ -6802,7 +6820,7 @@ void QQuickItem::setCursor(const QCursor &cursor)
}
if (!d->hasCursor) {
- d->incrementCursorCount(+1);
+ d->setHasCursorInChild(true);
d->hasCursor = true;
if (d->window) {
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window);
@@ -6825,7 +6843,7 @@ void QQuickItem::unsetCursor()
Q_D(QQuickItem);
if (!d->hasCursor)
return;
- d->incrementCursorCount(-1);
+ d->setHasCursorInChild(false);
d->hasCursor = false;
if (d->extra.isAllocated())
d->extra->cursor = QCursor();
@@ -7807,9 +7825,6 @@ QQuickItemPrivate::ExtraData::ExtraData()
: z(0), scale(1), rotation(0), opacity(1),
contents(0), screenAttached(0), layoutDirectionAttached(0),
keyHandler(0), layer(0),
-#ifndef QT_NO_CURSOR
- numItemsWithCursor(0),
-#endif
effectRefCount(0), hideRefCount(0),
opacityNode(0), clipNode(0), rootNode(0),
acceptedMouseButtons(0), origin(QQuickItem::Center),
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 2ae67c4c23..461b2f3485 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -342,7 +342,6 @@ public:
mutable QQuickItemLayer *layer;
#ifndef QT_NO_CURSOR
QCursor cursor;
- int numItemsWithCursor;
#endif
QPointF userTransformOriginPoint;
@@ -353,6 +352,8 @@ public:
QQuickDefaultClipNode *clipNode;
QSGRootNode *rootNode;
+ QObjectList resourcesList;
+
// Although acceptedMouseButtons is inside ExtraData, we actually store
// the LeftButton flag in the extra.flag() bit. This is because it is
// extremely common to set acceptedMouseButtons to LeftButton, but very
@@ -362,7 +363,7 @@ public:
QQuickItem::TransformOrigin origin:5;
uint transparentForPositioner : 1;
- QObjectList resourcesList;
+ // 26 bits padding
};
QLazilyAllocated<ExtraData> extra;
@@ -414,6 +415,7 @@ public:
bool culled:1;
bool hasCursor:1;
// Bit 32
+ bool hasCursorInChild:1;
bool activeFocusOnTab:1;
bool implicitAntialiasing:1;
bool antialiasingValid:1;
@@ -576,7 +578,7 @@ public:
virtual void mirrorChange() {}
- void incrementCursorCount(int delta);
+ void setHasCursorInChild(bool hasCursor);
// recursive helper to let a visual parent mark its visual children
void markObjects(QV4::ExecutionEngine *e);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index c7dde6d4aa..8bd6adca94 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2277,10 +2277,7 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF
return 0;
}
- const int numCursorsInHierarchy = itemPrivate->extra.isAllocated() ? itemPrivate->extra.value().numItemsWithCursor : 0;
- const int numChildrenWithCursor = itemPrivate->hasCursor ? numCursorsInHierarchy-1 : numCursorsInHierarchy;
-
- if (numChildrenWithCursor > 0) {
+ if (itemPrivate->hasCursorInChild) {
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);