QWidget: fix expensive iteration over QMap::keys()

... with iteration over the hash itself.

Can't keep the call to ungrabGesture() in the loop,
because it removes the current element from the very
hash being iterated over. Instead, inline the call
and optimize based on the context:

- don't remove element by element, but clear the
  hash completely at the end.
- drag the check for QGestureManager::instance()
  out of the loop.
- drop the check for presence of the key in the
  hash, since it would be always true.

Change-Id: I6bf7cc8a59a51ccc8046a5b6d1cab5784e79fd55
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
Marc Mutz 2015-06-21 12:42:35 +02:00
parent 49a61f35f3
commit 198768cbba

View File

@ -1543,8 +1543,12 @@ QWidget::~QWidget()
#endif
#ifndef QT_NO_GESTURES
foreach (Qt::GestureType type, d->gestureContext.keys())
ungrabGesture(type);
if (QGestureManager *manager = QGestureManager::instance()) {
// \forall Qt::GestureType type : ungrabGesture(type) (inlined)
for (auto it = d->gestureContext.keyBegin(), end = d->gestureContext.keyEnd(); it != end; ++it)
manager->cleanupCachedGestures(this, *it);
}
d->gestureContext.clear();
#endif
// force acceptDrops false before winId is destroyed.
@ -12253,6 +12257,7 @@ void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
*/
void QWidget::ungrabGesture(Qt::GestureType gesture)
{
// if you modify this function, check the inlined version in ~QWidget, too
Q_D(QWidget);
if (d->gestureContext.remove(gesture)) {
if (QGestureManager *manager = QGestureManager::instance())