summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-09-05 14:56:45 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-09-07 07:42:13 +0000
commitdc7e6d14d876cd3ed076b7a7bb542b9be3cbbfee (patch)
tree42722ad827215fe583717c9accfd58a668e13a06
parentf19f512d5e8f12f15fea6f216762af0bba1b4e4b (diff)
Use QVarLengthFlatMap for QPointingDevicePrivate::activePoints
It's good to use a pre-allocated set of points that never changes, because queryPointById() returns a pointer to the stored instance. If the flatmap's values are in a QList, and a mouse event comes in at the wrong time while touchpoints are already stored there, causing the QList to be resized, the returned pointer can become garbage. The pointer returned from queryPointById() is never retained for long, but in practice it turned out this could still happen, at least on X11 (perhaps because of X11 synthesizing mouse events from touch). Using a pre-allocated QVarLengthFlatMap is also an optimization: events on single-user systems are unlikely to ever cause memory allocation in this part of the code. Many touchscreens support up to 10 touchpoints, but the user might have some other input devices, plus the "core pointer" (mouse). The user could also have two touchscreens and try to use them simultaneously. d4611ba3a5b46ee790e6c790ef6c3d771d3507ee added QVarLengthFlatMap along with a test using int keys; so we expect that will keep working now. There was some issue in 2020 which is why I didn't use QVarLengthArray for the QFlatMap key and value containers to begin with. Fixes: QTBUG-106223 Change-Id: I588f66f07126b9551937a369df44f045759b473d Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 83e70c315742c5de964a1fc5f973ad087f5894e2) Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit 88752a13778ad7cb77b8b331187ca6de52d1ab9c) Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
-rw-r--r--src/gui/kernel/qpointingdevice.cpp1
-rw-r--r--src/gui/kernel/qpointingdevice_p.h2
2 files changed, 2 insertions, 1 deletions
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp
index d9ce0b0cf9..cf2ebf0347 100644
--- a/src/gui/kernel/qpointingdevice.cpp
+++ b/src/gui/kernel/qpointingdevice.cpp
@@ -465,6 +465,7 @@ void QPointingDevicePrivate::setExclusiveGrabber(const QPointerEvent *event, con
qWarning() << "point is not in activePoints" << point;
return;
}
+ Q_ASSERT(persistentPoint->eventPoint.id() == point.id());
if (persistentPoint->exclusiveGrabber == exclusiveGrabber)
return;
auto oldGrabber = persistentPoint->exclusiveGrabber;
diff --git a/src/gui/kernel/qpointingdevice_p.h b/src/gui/kernel/qpointingdevice_p.h
index 3638dbc39a..403a54dc4f 100644
--- a/src/gui/kernel/qpointingdevice_p.h
+++ b/src/gui/kernel/qpointingdevice_p.h
@@ -72,7 +72,7 @@ public:
void clearPassiveGrabbers(const QPointerEvent *event, const QEventPoint &point);
void removeGrabber(QObject *grabber, bool cancel = false);
- using EventPointMap = QFlatMap<int, EventPointData>;
+ using EventPointMap = QVarLengthFlatMap<int, EventPointData, 20>;
mutable EventPointMap activePoints;
QPointingDeviceUniqueId uniqueId;