summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-05-28 07:57:36 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-05-28 07:57:36 (GMT)
commit9667870db5b929c76656f3a4235b9539a1d5de5b (patch)
treeb6b74e837b9f26f113036075fdd9077ab0ff9996
parent2101aa8e9ec65864878b027d66d069542da8677f (diff)
downloadQt-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.cpp59
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h10
-rw-r--r--src/gui/kernel/qapplication.cpp4
-rw-r--r--src/gui/kernel/qapplication_p.h10
-rw-r--r--src/gui/kernel/qapplication_win.cpp62
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 *> &currentTouchPoints = itemCurrentTouchPoints[item];
- appendTouchPoint(touchPoint, &currentTouchPoints);
- // 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 *> &currentTouchPoints = itemCurrentTouchPoints[item];
- sceneActiveTouchPoints = sceneCurrentTouchPoints;
- activeTouchPoints = currentTouchPoints;
- removeTouchPoint(touchPoint, &currentTouchPoints);
+ 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 *> &currentTouchPoints = widgetCurrentTouchPoints[widget];
- appendTouchPoint(touchPoint, &currentTouchPoints);
- // 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 *> &currentTouchPoints = widgetCurrentTouchPoints[widget];
- appActiveTouchPoints = appCurrentTouchPoints;
- activeTouchPoints = currentTouchPoints;
- removeTouchPoint(touchPoint, &currentTouchPoints);
+
+ 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);