diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-05-28 07:57:36 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-05-28 07:57:36 (GMT) |
commit | 9667870db5b929c76656f3a4235b9539a1d5de5b (patch) | |
tree | b6b74e837b9f26f113036075fdd9077ab0ff9996 | |
parent | 2101aa8e9ec65864878b027d66d069542da8677f (diff) | |
download | Qt-9667870db5b929c76656f3a4235b9539a1d5de5b.zip Qt-9667870db5b929c76656f3a4235b9539a1d5de5b.tar.gz Qt-9667870db5b929c76656f3a4235b9539a1d5de5b.tar.bz2 |
Don't try to maintain a current and active list of points for the app and widgets/items
Instead, build the list of touchPoints per event. This solves the problem when encountering
releases early in the active/current list while there are still touch points in move/stationary
states (which effectively caused the code to "forget" about the released point).
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 59 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 10 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 10 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 62 |
5 files changed, 30 insertions, 115 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e7a0547..1cd51d6 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5694,13 +5694,12 @@ void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, } } -QGraphicsSceneTouchEvent::TouchPoint *QGraphicsScenePrivate::findClosestTouchPoint(const QList<QGraphicsSceneTouchEvent::TouchPoint *> &sceneActiveTouchPoints, - const QPointF &scenePos) +QGraphicsSceneTouchEvent::TouchPoint *QGraphicsScenePrivate::findClosestTouchPoint(const QPointF &scenePos) { QGraphicsSceneTouchEvent::TouchPoint *closestTouchPoint = 0; qreal closestDistance; - for (int i = 0; i < sceneActiveTouchPoints.count(); ++i) { - QGraphicsSceneTouchEvent::TouchPoint *touchPoint = sceneActiveTouchPoints.at(i); + for (int i = 0; i < sceneCurrentTouchPoints.count(); ++i) { + QGraphicsSceneTouchEvent::TouchPoint *touchPoint = sceneCurrentTouchPoints.at(i); qreal distance = QLineF(scenePos, touchPoint->scenePos()).length(); if (!closestTouchPoint || distance < closestDistance) { closestTouchPoint = touchPoint; @@ -5710,8 +5709,7 @@ QGraphicsSceneTouchEvent::TouchPoint *QGraphicsScenePrivate::findClosestTouchPoi return closestTouchPoint; } -void QGraphicsScenePrivate::appendTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint, - QList<QGraphicsSceneTouchEvent::TouchPoint *> *currentTouchPoints) +void QGraphicsScenePrivate::appendTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint) { // insort touch point (for the app) int at = 0; @@ -5720,16 +5718,9 @@ void QGraphicsScenePrivate::appendTouchPoint(QGraphicsSceneTouchEvent::TouchPoin break; } sceneCurrentTouchPoints.insert(at, touchPoint); - // again, for the items's currentTouchPoints - for (at = 0; at < currentTouchPoints->count(); ++at) { - if (currentTouchPoints->at(at)->id() > touchPoint->id()) - break; - } - currentTouchPoints->insert(at, touchPoint); } -void QGraphicsScenePrivate::removeTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint, - QList<QGraphicsSceneTouchEvent::TouchPoint *> *currentTouchPoints) +void QGraphicsScenePrivate::removeTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint) { // remove touch point from all known touch points for (int i = qMin(sceneCurrentTouchPoints.count() - 1, touchPoint->id()); i >= 0; --i) { @@ -5738,21 +5729,13 @@ void QGraphicsScenePrivate::removeTouchPoint(QGraphicsSceneTouchEvent::TouchPoin break; } } - // again, for the items's currentTouchPoints - for (int i = qMin(currentTouchPoints->count() - 1, touchPoint->id()); i >= 0; --i) { - if (currentTouchPoints->at(i) == touchPoint) { - currentTouchPoints->removeAt(i); - break; - } - } } void QGraphicsScenePrivate::touchEventHandler(QGraphicsSceneTouchEvent *sceneTouchEvent) { - QList<QGraphicsSceneTouchEvent::TouchPoint *> sceneActiveTouchPoints = sceneCurrentTouchPoints; - typedef QPair<Qt::TouchPointStates, QList<QGraphicsSceneTouchEvent::TouchPoint *> > StatesAndTouchPoints; QHash<QGraphicsItem *, StatesAndTouchPoints> itemsNeedingEvents; + for (int i = 0; i < sceneTouchEvent->touchPoints().count(); ++i) { QGraphicsSceneTouchEvent::TouchPoint *touchPoint = sceneTouchEvent->touchPoints().at(i); @@ -5765,7 +5748,7 @@ void QGraphicsScenePrivate::touchEventHandler(QGraphicsSceneTouchEvent *sceneTou touchPoint->scenePos(), sceneTouchEvent->widget()); item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first(); - QGraphicsSceneTouchEvent::TouchPoint *closestTouchPoint = findClosestTouchPoint(sceneActiveTouchPoints, touchPoint->scenePos()); + QGraphicsSceneTouchEvent::TouchPoint *closestTouchPoint = findClosestTouchPoint(touchPoint->scenePos()); if (closestTouchPoint) { QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPoint->id()); if (!item @@ -5779,33 +5762,22 @@ void QGraphicsScenePrivate::touchEventHandler(QGraphicsSceneTouchEvent *sceneTou continue; itemForTouchPointId.insert(touchPoint->id(), item); - - QList<QGraphicsSceneTouchEvent::TouchPoint *> ¤tTouchPoints = itemCurrentTouchPoints[item]; - appendTouchPoint(touchPoint, ¤tTouchPoints); - // make sure new points are added to activeTouchPoints as well - sceneActiveTouchPoints = sceneCurrentTouchPoints; - activeTouchPoints = currentTouchPoints; + appendTouchPoint(touchPoint); } else if (touchPoint->state() == Qt::TouchPointReleased) { item = itemForTouchPointId.take(touchPoint->id()); if (!item) continue; - QList<QGraphicsSceneTouchEvent::TouchPoint *> ¤tTouchPoints = itemCurrentTouchPoints[item]; - sceneActiveTouchPoints = sceneCurrentTouchPoints; - activeTouchPoints = currentTouchPoints; - removeTouchPoint(touchPoint, ¤tTouchPoints); + removeTouchPoint(touchPoint); } else { item = itemForTouchPointId.value(touchPoint->id()); if (!item) continue; - - sceneActiveTouchPoints = sceneCurrentTouchPoints; - activeTouchPoints = itemCurrentTouchPoints.value(item); } StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item]; statesAndTouchPoints.first |= touchPoint->state(); - statesAndTouchPoints.second = activeTouchPoints; + statesAndTouchPoints.second.append(touchPoint); } if (itemsNeedingEvents.isEmpty()) { @@ -5856,14 +5828,6 @@ void QGraphicsScenePrivate::touchEventHandler(QGraphicsSceneTouchEvent *sceneTou acceptSceneTouchEvent = acceptSceneTouchEvent || res; break; } - case QEvent::GraphicsSceneTouchEnd: - { - QList<QGraphicsSceneTouchEvent::TouchPoint *> currentTouchPoints = itemCurrentTouchPoints.take(item); - if (!currentTouchPoints.isEmpty()) { - qFatal("Qt: INTERNAL ERROR, the widget's currentTouchPoints should be empty!"); - } - // fall-through intended - } default: if (item->d_ptr->acceptedTouchBeginEvent) { updateTouchPointsForItem(item, &touchEvent); @@ -5922,9 +5886,6 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QGraphics QGraphicsSceneTouchEvent::TouchPoint *touchPoint = touchEvent->touchPoints().at(i); itemForTouchPointId[touchPoint->id()] = item; } - if (origin != item) - itemCurrentTouchPoints.remove(origin); - itemCurrentTouchPoints[item] = touchEvent->touchPoints(); break; } } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 22feb4c..4af35a0 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -280,15 +280,11 @@ public: mutable QVector<int> freeSceneTransformSlots; QList<QGraphicsSceneTouchEvent::TouchPoint *> sceneCurrentTouchPoints; - QHash<QGraphicsItem *, QList<QGraphicsSceneTouchEvent::TouchPoint *> > itemCurrentTouchPoints; QHash<int, QGraphicsItem *> itemForTouchPointId; static void updateTouchPointsForItem(QGraphicsItem *item, QGraphicsSceneTouchEvent *touchEvent); - static QGraphicsSceneTouchEvent::TouchPoint *findClosestTouchPoint(const QList<QGraphicsSceneTouchEvent::TouchPoint *> &activeTouchPoints, - const QPointF &scenePos); - void appendTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint, - QList<QGraphicsSceneTouchEvent::TouchPoint *> *currentTouchPoints); - void removeTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint, - QList<QGraphicsSceneTouchEvent::TouchPoint *> *currentTouchPoints); + QGraphicsSceneTouchEvent::TouchPoint *findClosestTouchPoint(const QPointF &scenePos); + void appendTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint); + void removeTouchPoint(QGraphicsSceneTouchEvent::TouchPoint *touchPoint); void touchEventHandler(QGraphicsSceneTouchEvent *touchEvent); bool sendTouchBeginEvent(QGraphicsItem *item, QGraphicsSceneTouchEvent *touchEvent); }; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 88b9a66..01c7c4a 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4031,7 +4031,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) // Note: TouchUpdate and TouchEnd events are sent to d->currentMultitouchWidget and never propagated { QWidget *widget = static_cast<QWidget *>(receiver); - QWidget *origin = widget; QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e); bool eventAccepted = touchEvent->isAccepted(); if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) { @@ -4055,9 +4054,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QTouchEvent::TouchPoint *touchPoint = touchEvent->touchPoints().at(i); d->widgetForTouchPointId[touchPoint->id()] = widget; } - if (origin != widget) - d->widgetCurrentTouchPoints.remove(origin); - d->widgetCurrentTouchPoints[widget] = touchEvent->touchPoints(); break; } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) { break; diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 34395c9..1424611 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -435,7 +435,6 @@ public: QMap<QString, int> grabbedGestures; QHash<int, QWidget *> widgetForTouchPointId; - QMap<QWidget *, QList<QTouchEvent::TouchPoint *> > widgetCurrentTouchPoints; static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); #if defined(Q_WS_WIN) @@ -448,12 +447,9 @@ public: QList<QTouchEvent::TouchPoint *> appCurrentTouchPoints; void initializeMultitouch(); - static QTouchEvent::TouchPoint *findClosestTouchPoint(const QList<QTouchEvent::TouchPoint *> &activeTouchPoints, - const QPointF &screenPos); - void appendTouchPoint(QTouchEvent::TouchPoint *touchPoint, - QList<QTouchEvent::TouchPoint *> *currentTouchPoints); - void removeTouchPoint(QTouchEvent::TouchPoint *touchPoint, - QList<QTouchEvent::TouchPoint *> *currentTouchPoints); + QTouchEvent::TouchPoint *findClosestTouchPoint(const QPointF &screenPos); + void appendTouchPoint(QTouchEvent::TouchPoint *touchPoint); + void removeTouchPoint(QTouchEvent::TouchPoint *touchPoint); bool translateTouchEvent(const MSG &msg); #endif diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0fc76ae..f980f8e 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3989,19 +3989,17 @@ void QApplicationPrivate::initializeMultitouch() CloseTouchInputHandle = static_cast<qt_CloseTouchInputHandlePtr>(library.resolve("CloseTouchInputHandle")); widgetForTouchPointId.clear(); - widgetCurrentTouchPoints.clear(); touchInputIDToTouchPointID.clear(); appAllTouchPoints.clear(); appCurrentTouchPoints.clear(); } -QTouchEvent::TouchPoint *QApplicationPrivate::findClosestTouchPoint(const QList<QTouchEvent::TouchPoint *> &appActiveTouchPoints, - const QPointF &screenPos) +QTouchEvent::TouchPoint *QApplicationPrivate::findClosestTouchPoint(const QPointF &screenPos) { QTouchEvent::TouchPoint *closestTouchPoint = 0; qreal closestDistance; - for (int i = 0; i < appActiveTouchPoints.count(); ++i) { - QTouchEvent::TouchPoint *touchPoint = appActiveTouchPoints.at(i); + for (int i = 0; i < appCurrentTouchPoints.count(); ++i) { + QTouchEvent::TouchPoint *touchPoint = appCurrentTouchPoints.at(i); qreal distance = QLineF(screenPos, touchPoint->screenPos()).length(); if (!closestTouchPoint || distance < closestDistance) { closestTouchPoint = touchPoint; @@ -4011,22 +4009,15 @@ QTouchEvent::TouchPoint *QApplicationPrivate::findClosestTouchPoint(const QList< return closestTouchPoint; } -void QApplicationPrivate::appendTouchPoint(QTouchEvent::TouchPoint *touchPoint, - QList<QTouchEvent::TouchPoint *> *currentTouchPoints) -{ - // insort touch point (for the app) +void QApplicationPrivate::appendTouchPoint(QTouchEvent::TouchPoint *touchPoint) +{ + // insort touch point int at = 0; for (; at < appCurrentTouchPoints.count(); ++at) { if (appCurrentTouchPoints.at(at)->id() > touchPoint->id()) break; } appCurrentTouchPoints.insert(at, touchPoint); - // again, for the widget's currentTouchPoints - for (at = 0; at < currentTouchPoints->count(); ++at) { - if (currentTouchPoints->at(at)->id() > touchPoint->id()) - break; - } - currentTouchPoints->insert(at, touchPoint); if (appCurrentTouchPoints.count() > appAllTouchPoints.count()) { qFatal("Qt: INTERNAL ERROR: appCurrentTouchPoints.count() (%d) > appAllTouchPoints.count() (%d)", @@ -4035,8 +4026,7 @@ void QApplicationPrivate::appendTouchPoint(QTouchEvent::TouchPoint *touchPoint, } } -void QApplicationPrivate::removeTouchPoint(QTouchEvent::TouchPoint *touchPoint, - QList<QTouchEvent::TouchPoint *> *currentTouchPoints) +void QApplicationPrivate::removeTouchPoint(QTouchEvent::TouchPoint *touchPoint) { // remove touch point from all known touch points for (int i = qMin(appCurrentTouchPoints.count() - 1, touchPoint->id()); i >= 0; --i) { @@ -4045,13 +4035,6 @@ void QApplicationPrivate::removeTouchPoint(QTouchEvent::TouchPoint *touchPoint, break; } } - // again, for the widget's currentTouchPoints - for (int i = qMin(currentTouchPoints->count() - 1, touchPoint->id()); i >= 0; --i) { - if (currentTouchPoints->at(i) == touchPoint) { - currentTouchPoints->removeAt(i); - break; - } - } } bool QApplicationPrivate::translateTouchEvent(const MSG &msg) @@ -4062,10 +4045,9 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) if (!widgetForHwnd) return false; - QList<QTouchEvent::TouchPoint *> appActiveTouchPoints = appCurrentTouchPoints; - typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint *> > StatesAndTouchPoints; QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents; + QVector<TOUCHINPUT> winTouchInputs(msg.wParam); memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count()); QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); @@ -4090,14 +4072,13 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) bool down = touchPoint->state() != Qt::TouchPointReleased; QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.)); - QList<QTouchEvent::TouchPoint *> activeTouchPoints; if (!down && (touchInput.dwFlags & TOUCHEVENTF_DOWN)) { // determine which widget this event will go to widget = widgetForHwnd->childAt(widgetForHwnd->mapFromGlobal(screenPos.toPoint())); if (!widget) widget = widgetForHwnd; - QTouchEvent::TouchPoint *closestTouchPoint = findClosestTouchPoint(appActiveTouchPoints, screenPos); + QTouchEvent::TouchPoint *closestTouchPoint = findClosestTouchPoint(screenPos); if (closestTouchPoint) { QWidget *closestWidget = widgetForTouchPointId.value(closestTouchPoint->id()); if (closestWidget @@ -4107,11 +4088,7 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) } widgetForTouchPointId[touchPoint->id()] = widget; - QList<QTouchEvent::TouchPoint *> ¤tTouchPoints = widgetCurrentTouchPoints[widget]; - appendTouchPoint(touchPoint, ¤tTouchPoints); - // make sure new points are added to activeTouchPoints as well - appActiveTouchPoints = appCurrentTouchPoints; - activeTouchPoints = currentTouchPoints; + appendTouchPoint(touchPoint); touchPoint->setState(Qt::TouchPointPressed); touchPoint->setScreenPos(screenPos); @@ -4120,10 +4097,8 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) touchPoint->setPressure(qreal(1.)); } else if (down && (touchInput.dwFlags & TOUCHEVENTF_UP)) { widget = widgetForTouchPointId.take(touchPoint->id()); - QList<QTouchEvent::TouchPoint *> ¤tTouchPoints = widgetCurrentTouchPoints[widget]; - appActiveTouchPoints = appCurrentTouchPoints; - activeTouchPoints = currentTouchPoints; - removeTouchPoint(touchPoint, ¤tTouchPoints); + + removeTouchPoint(touchPoint); touchPoint->setState(Qt::TouchPointReleased); touchPoint->setLastScreenPos(touchPoint->screenPos()); @@ -4131,8 +4106,7 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) touchPoint->setPressure(qreal(0.)); } else if (down) { widget = widgetForTouchPointId.value(touchPoint->id()); - appActiveTouchPoints = appCurrentTouchPoints; - activeTouchPoints = widgetCurrentTouchPoints.value(widget); + touchPoint->setState(screenPos == touchPoint->screenPos() ? Qt::TouchPointStationary : Qt::TouchPointMoved); @@ -4144,7 +4118,7 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget]; maskAndPoints.first |= touchPoint->state(); - maskAndPoints.second = activeTouchPoints; + maskAndPoints.second.append(touchPoint); } QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam); @@ -4194,14 +4168,6 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) returnValue = returnValue || (qt_tabletChokeMouse = qt_tabletChokeMouse || res); break; } - case QEvent::TouchEnd: - { - QList<QTouchEvent::TouchPoint *> currentTouchPoints = widgetCurrentTouchPoints.take(widget); - if (!currentTouchPoints.isEmpty()) { - qFatal("Qt: INTERNAL ERROR, the widget's currentTouchPoints should be empty!"); - } - // fall-through intended - } default: if (widget->testAttribute(Qt::WA_AcceptedTouchBeginEvent)) { (void) QApplication::sendSpontaneousEvent(widget, &touchEvent); |