1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the $MODULE$ of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 class tst_QTouchEventWidget : public QWidget
49 QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints;
50 bool seenTouchBegin, seenTouchUpdate, seenTouchEnd;
51 bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
52 bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd;
54 QTouchDevice *deviceFromEvent;
56 tst_QTouchEventWidget()
64 touchBeginPoints.clear();
65 touchUpdatePoints.clear();
66 touchEndPoints.clear();
67 seenTouchBegin = seenTouchUpdate = seenTouchEnd = false;
68 acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true;
69 deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false;
72 bool event(QEvent *event)
74 switch (event->type()) {
75 case QEvent::TouchBegin:
76 if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin");
77 if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin");
78 if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin");
79 seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
80 touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
81 timestamp = static_cast<QTouchEvent *>(event)->timestamp();
82 deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
83 event->setAccepted(acceptTouchBegin);
84 if (deleteInTouchBegin)
87 case QEvent::TouchUpdate:
88 if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin");
89 if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate");
90 seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
91 touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
92 timestamp = static_cast<QTouchEvent *>(event)->timestamp();
93 deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
94 event->setAccepted(acceptTouchUpdate);
95 if (deleteInTouchUpdate)
98 case QEvent::TouchEnd:
99 if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin");
100 if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd");
101 seenTouchEnd = seenTouchBegin && !seenTouchEnd;
102 touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
103 timestamp = static_cast<QTouchEvent *>(event)->timestamp();
104 deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
105 event->setAccepted(acceptTouchEnd);
106 if (deleteInTouchEnd)
110 return QWidget::event(event);
116 class tst_QTouchEventGraphicsItem : public QGraphicsItem
119 QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints;
120 bool seenTouchBegin, seenTouchUpdate, seenTouchEnd;
121 int touchBeginCounter, touchUpdateCounter, touchEndCounter;
122 bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
123 bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd;
124 tst_QTouchEventGraphicsItem **weakpointer;
126 tst_QTouchEventGraphicsItem()
127 : QGraphicsItem(), weakpointer(0)
132 ~tst_QTouchEventGraphicsItem()
140 touchBeginPoints.clear();
141 touchUpdatePoints.clear();
142 touchEndPoints.clear();
143 seenTouchBegin = seenTouchUpdate = seenTouchEnd = false;
144 touchBeginCounter = touchUpdateCounter = touchEndCounter = 0;
145 acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true;
146 deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false;
149 QRectF boundingRect() const { return QRectF(0, 0, 10, 10); }
150 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) { }
152 bool sceneEvent(QEvent *event)
154 switch (event->type()) {
155 case QEvent::TouchBegin:
156 if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin");
157 if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin");
158 if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin");
159 seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
161 touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
162 event->setAccepted(acceptTouchBegin);
163 if (deleteInTouchBegin)
166 case QEvent::TouchUpdate:
167 if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin");
168 if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate");
169 seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
170 ++touchUpdateCounter;
171 touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
172 event->setAccepted(acceptTouchUpdate);
173 if (deleteInTouchUpdate)
176 case QEvent::TouchEnd:
177 if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin");
178 if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd");
179 seenTouchEnd = seenTouchBegin && !seenTouchEnd;
181 touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
182 event->setAccepted(acceptTouchEnd);
183 if (deleteInTouchEnd)
187 return QGraphicsItem::sceneEvent(event);
193 class tst_QTouchEvent : public QObject
198 ~tst_QTouchEvent() { }
201 void touchDisabledByDefault();
202 void touchEventAcceptedByDefault();
203 void touchBeginPropagatesWhenIgnored();
204 void touchUpdateAndEndNeverPropagate();
205 void basicRawEventTranslation();
206 void multiPointRawEventTranslationOnTouchScreen();
207 void multiPointRawEventTranslationOnTouchPad();
208 void deleteInEventHandler();
209 void deleteInRawEventTranslation();
210 void crashInQGraphicsSceneAfterNotHandlingTouchBegin();
211 void touchBeginWithGraphicsWidget();
212 void testQGuiAppDelivery();
213 void testMultiDevice();
216 QTouchDevice *touchScreenDevice;
217 QTouchDevice *touchPadDevice;
220 tst_QTouchEvent::tst_QTouchEvent()
222 touchScreenDevice = new QTouchDevice;
223 touchPadDevice = new QTouchDevice;
224 touchPadDevice->setType(QTouchDevice::TouchPad);
225 QWindowSystemInterface::registerTouchDevice(touchScreenDevice);
226 QWindowSystemInterface::registerTouchDevice(touchPadDevice);
229 void tst_QTouchEvent::touchDisabledByDefault()
233 // the widget attribute is not enabled by default
235 QVERIFY(!widget.testAttribute(Qt::WA_AcceptTouchEvents));
237 // events should not be accepted since they are not enabled
238 QList<QTouchEvent::TouchPoint> touchPoints;
239 touchPoints.append(QTouchEvent::TouchPoint(0));
240 QTouchEvent touchEvent(QEvent::TouchBegin,
243 Qt::TouchPointPressed,
245 bool res = QApplication::sendEvent(&widget, &touchEvent);
247 QVERIFY(!touchEvent.isAccepted());
252 QGraphicsScene scene;
253 tst_QTouchEventGraphicsItem item;
254 QGraphicsView view(&scene);
255 scene.addItem(&item);
256 item.setPos(100, 100);
257 view.resize(200, 200);
258 view.fitInView(scene.sceneRect());
260 // touch events are not accepted by default
261 QVERIFY(!item.acceptTouchEvents());
263 // compose an event to the scene that is over the item
264 QTouchEvent::TouchPoint touchPoint(0);
265 touchPoint.setState(Qt::TouchPointPressed);
266 touchPoint.setPos(view.mapFromScene(item.mapToScene(item.boundingRect().center())));
267 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
268 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
269 QTouchEvent touchEvent(QEvent::TouchBegin,
272 Qt::TouchPointPressed,
273 (QList<QTouchEvent::TouchPoint>() << touchPoint));
274 bool res = QApplication::sendEvent(view.viewport(), &touchEvent);
276 QVERIFY(!touchEvent.isAccepted());
277 QVERIFY(!item.seenTouchBegin);
281 void tst_QTouchEvent::touchEventAcceptedByDefault()
285 // enabling touch events should automatically accept touch events
287 widget.setAttribute(Qt::WA_AcceptTouchEvents);
289 // QWidget handles touch event by converting them into a mouse event, so the event is both
290 // accepted and handled (res == true)
291 QList<QTouchEvent::TouchPoint> touchPoints;
292 touchPoints.append(QTouchEvent::TouchPoint(0));
293 QTouchEvent touchEvent(QEvent::TouchBegin,
296 Qt::TouchPointPressed,
298 bool res = QApplication::sendEvent(&widget, &touchEvent);
300 QVERIFY(touchEvent.isAccepted());
302 // tst_QTouchEventWidget does handle, sending succeeds
303 tst_QTouchEventWidget touchWidget;
304 touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
306 res = QApplication::sendEvent(&touchWidget, &touchEvent);
308 QVERIFY(touchEvent.isAccepted());
313 QGraphicsScene scene;
314 tst_QTouchEventGraphicsItem item;
315 QGraphicsView view(&scene);
316 scene.addItem(&item);
317 item.setPos(100, 100);
318 view.resize(200, 200);
319 view.fitInView(scene.sceneRect());
321 // enabling touch events on the item also enables events on the viewport
322 item.setAcceptTouchEvents(true);
323 QVERIFY(view.viewport()->testAttribute(Qt::WA_AcceptTouchEvents));
325 // compose an event to the scene that is over the item
326 QTouchEvent::TouchPoint touchPoint(0);
327 touchPoint.setState(Qt::TouchPointPressed);
328 touchPoint.setPos(view.mapFromScene(item.mapToScene(item.boundingRect().center())));
329 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
330 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
331 QTouchEvent touchEvent(QEvent::TouchBegin,
334 Qt::TouchPointPressed,
335 (QList<QTouchEvent::TouchPoint>() << touchPoint));
336 bool res = QApplication::sendEvent(view.viewport(), &touchEvent);
338 QVERIFY(touchEvent.isAccepted());
339 QVERIFY(item.seenTouchBegin);
343 void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
347 tst_QTouchEventWidget window, child, grandchild;
348 child.setParent(&window);
349 grandchild.setParent(&child);
351 // all widgets accept touch events, grandchild ignores, so child sees the event, but not window
352 window.setAttribute(Qt::WA_AcceptTouchEvents);
353 child.setAttribute(Qt::WA_AcceptTouchEvents);
354 grandchild.setAttribute(Qt::WA_AcceptTouchEvents);
355 grandchild.acceptTouchBegin = false;
357 QList<QTouchEvent::TouchPoint> touchPoints;
358 touchPoints.append(QTouchEvent::TouchPoint(0));
359 QTouchEvent touchEvent(QEvent::TouchBegin,
362 Qt::TouchPointPressed,
364 bool res = QApplication::sendEvent(&grandchild, &touchEvent);
366 QVERIFY(touchEvent.isAccepted());
367 QVERIFY(grandchild.seenTouchBegin);
368 QVERIFY(child.seenTouchBegin);
369 QVERIFY(!window.seenTouchBegin);
371 // disable touch on grandchild. even though it doesn't accept it, child should still get the
376 grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false);
379 res = QApplication::sendEvent(&grandchild, &touchEvent);
381 QVERIFY(touchEvent.isAccepted());
382 QVERIFY(!grandchild.seenTouchBegin);
383 QVERIFY(child.seenTouchBegin);
384 QVERIFY(!window.seenTouchBegin);
389 QGraphicsScene scene;
390 tst_QTouchEventGraphicsItem root, child, grandchild;
391 QGraphicsView view(&scene);
392 scene.addItem(&root);
393 root.setPos(100, 100);
394 child.setParentItem(&root);
395 grandchild.setParentItem(&child);
396 view.resize(200, 200);
397 view.fitInView(scene.sceneRect());
399 // all items accept touch events, grandchild ignores, so child sees the event, but not root
400 root.setAcceptTouchEvents(true);
401 child.setAcceptTouchEvents(true);
402 grandchild.setAcceptTouchEvents(true);
403 grandchild.acceptTouchBegin = false;
405 // compose an event to the scene that is over the grandchild
406 QTouchEvent::TouchPoint touchPoint(0);
407 touchPoint.setState(Qt::TouchPointPressed);
408 touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
409 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
410 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
411 QTouchEvent touchEvent(QEvent::TouchBegin,
414 Qt::TouchPointPressed,
415 (QList<QTouchEvent::TouchPoint>() << touchPoint));
416 bool res = QApplication::sendEvent(view.viewport(), &touchEvent);
418 QVERIFY(touchEvent.isAccepted());
419 QVERIFY(grandchild.seenTouchBegin);
420 QVERIFY(child.seenTouchBegin);
421 QVERIFY(!root.seenTouchBegin);
426 QGraphicsScene scene;
427 tst_QTouchEventGraphicsItem root, child, grandchild;
428 QGraphicsView view(&scene);
429 scene.addItem(&root);
430 root.setPos(100, 100);
431 child.setParentItem(&root);
432 grandchild.setParentItem(&child);
433 view.resize(200, 200);
434 view.fitInView(scene.sceneRect());
436 // leave touch disabled on grandchild. even though it doesn't accept it, child should
437 // still get the TouchBegin
438 root.setAcceptTouchEvents(true);
439 child.setAcceptTouchEvents(true);
441 // compose an event to the scene that is over the grandchild
442 QTouchEvent::TouchPoint touchPoint(0);
443 touchPoint.setState(Qt::TouchPointPressed);
444 touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
445 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
446 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
447 QTouchEvent touchEvent(QEvent::TouchBegin,
450 Qt::TouchPointPressed,
451 (QList<QTouchEvent::TouchPoint>() << touchPoint));
452 bool res = QApplication::sendEvent(view.viewport(), &touchEvent);
454 QVERIFY(touchEvent.isAccepted());
455 QVERIFY(!grandchild.seenTouchBegin);
456 QVERIFY(child.seenTouchBegin);
457 QVERIFY(!root.seenTouchBegin);
461 void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
465 tst_QTouchEventWidget window, child;
466 child.setParent(&window);
468 window.setAttribute(Qt::WA_AcceptTouchEvents);
469 child.setAttribute(Qt::WA_AcceptTouchEvents);
470 child.acceptTouchUpdate = false;
471 child.acceptTouchEnd = false;
473 QList<QTouchEvent::TouchPoint> touchPoints;
474 touchPoints.append(QTouchEvent::TouchPoint(0));
475 QTouchEvent touchBeginEvent(QEvent::TouchBegin,
478 Qt::TouchPointPressed,
480 bool res = QApplication::sendEvent(&child, &touchBeginEvent);
482 QVERIFY(touchBeginEvent.isAccepted());
483 QVERIFY(child.seenTouchBegin);
484 QVERIFY(!window.seenTouchBegin);
486 // send the touch update to the child, but ignore it, it doesn't propagate
487 QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
492 res = QApplication::sendEvent(&child, &touchUpdateEvent);
494 QVERIFY(!touchUpdateEvent.isAccepted());
495 QVERIFY(child.seenTouchUpdate);
496 QVERIFY(!window.seenTouchUpdate);
498 // send the touch end, same thing should happen as with touch update
499 QTouchEvent touchEndEvent(QEvent::TouchEnd,
502 Qt::TouchPointReleased,
504 res = QApplication::sendEvent(&child, &touchEndEvent);
506 QVERIFY(!touchEndEvent.isAccepted());
507 QVERIFY(child.seenTouchEnd);
508 QVERIFY(!window.seenTouchEnd);
513 QGraphicsScene scene;
514 tst_QTouchEventGraphicsItem root, child, grandchild;
515 QGraphicsView view(&scene);
516 scene.addItem(&root);
517 root.setPos(100, 100);
518 child.setParentItem(&root);
519 grandchild.setParentItem(&child);
520 view.resize(200, 200);
521 view.fitInView(scene.sceneRect());
523 root.setAcceptTouchEvents(true);
524 child.setAcceptTouchEvents(true);
525 child.acceptTouchUpdate = false;
526 child.acceptTouchEnd = false;
528 // compose an event to the scene that is over the child
529 QTouchEvent::TouchPoint touchPoint(0);
530 touchPoint.setState(Qt::TouchPointPressed);
531 touchPoint.setPos(view.mapFromScene(grandchild.mapToScene(grandchild.boundingRect().center())));
532 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
533 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
534 QTouchEvent touchBeginEvent(QEvent::TouchBegin,
537 Qt::TouchPointPressed,
538 (QList<QTouchEvent::TouchPoint>() << touchPoint));
539 bool res = QApplication::sendEvent(view.viewport(), &touchBeginEvent);
541 QVERIFY(touchBeginEvent.isAccepted());
542 QVERIFY(child.seenTouchBegin);
543 QVERIFY(!root.seenTouchBegin);
545 // send the touch update to the child, but ignore it, it doesn't propagate
546 touchPoint.setState(Qt::TouchPointMoved);
547 QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
551 (QList<QTouchEvent::TouchPoint>() << touchPoint));
552 res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent);
554 // the scene accepts the event, since it found an item to send the event to
555 QVERIFY(!touchUpdateEvent.isAccepted());
556 QVERIFY(child.seenTouchUpdate);
557 QVERIFY(!root.seenTouchUpdate);
559 // send the touch end, same thing should happen as with touch update
560 touchPoint.setState(Qt::TouchPointReleased);
561 QTouchEvent touchEndEvent(QEvent::TouchEnd,
564 Qt::TouchPointReleased,
565 (QList<QTouchEvent::TouchPoint>() << touchPoint));
566 res = QApplication::sendEvent(view.viewport(), &touchEndEvent);
568 // the scene accepts the event, since it found an item to send the event to
569 QVERIFY(!touchEndEvent.isAccepted());
570 QVERIFY(child.seenTouchEnd);
571 QVERIFY(!root.seenTouchEnd);
575 QPointF normalized(const QPointF &pos, const QRectF &rect)
577 return QPointF(pos.x() / rect.width(), pos.y() / rect.height());
580 void tst_QTouchEvent::basicRawEventTranslation()
582 tst_QTouchEventWidget touchWidget;
583 touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
584 touchWidget.setGeometry(100, 100, 400, 300);
586 QPointF pos = touchWidget.rect().center();
587 QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint());
588 QPointF delta(10, 10);
589 QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
591 QTouchEvent::TouchPoint rawTouchPoint;
592 rawTouchPoint.setId(0);
594 // this should be translated to a TouchBegin
595 rawTouchPoint.setState(Qt::TouchPointPressed);
596 rawTouchPoint.setScreenPos(screenPos);
597 rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
598 QVector<QPointF> rawPosList;
599 rawPosList << QPointF(12, 34) << QPointF(56, 78);
600 rawTouchPoint.setRawScreenPositions(rawPosList);
601 const ulong timestamp = 1234;
602 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
605 QTest::QTouchEventSequence::touchPointList(
606 QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
607 QCoreApplication::processEvents();
608 QVERIFY(touchWidget.seenTouchBegin);
609 QVERIFY(!touchWidget.seenTouchUpdate);
610 QVERIFY(!touchWidget.seenTouchEnd);
611 QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
612 QCOMPARE(touchWidget.timestamp, timestamp);
613 QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
614 QCOMPARE(touchBeginPoint.id(), rawTouchPoint.id());
615 QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state());
616 QCOMPARE(touchBeginPoint.pos(), pos);
617 QCOMPARE(touchBeginPoint.startPos(), pos);
618 QCOMPARE(touchBeginPoint.lastPos(), pos);
619 QCOMPARE(touchBeginPoint.scenePos(), rawTouchPoint.screenPos());
620 QCOMPARE(touchBeginPoint.startScenePos(), rawTouchPoint.screenPos());
621 QCOMPARE(touchBeginPoint.lastScenePos(), rawTouchPoint.screenPos());
622 QCOMPARE(touchBeginPoint.screenPos(), rawTouchPoint.screenPos());
623 QCOMPARE(touchBeginPoint.startScreenPos(), rawTouchPoint.screenPos());
624 QCOMPARE(touchBeginPoint.lastScreenPos(), rawTouchPoint.screenPos());
625 QCOMPARE(touchBeginPoint.normalizedPos(), rawTouchPoint.normalizedPos());
626 QCOMPARE(touchBeginPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
627 QCOMPARE(touchBeginPoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
628 QCOMPARE(touchBeginPoint.rect(), QRectF(pos, QSizeF(0, 0)));
629 QCOMPARE(touchBeginPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
630 QCOMPARE(touchBeginPoint.sceneRect(), touchBeginPoint.screenRect());
631 QCOMPARE(touchBeginPoint.pressure(), qreal(1.));
632 QCOMPARE(touchBeginPoint.velocity(), QVector2D());
633 QCOMPARE(touchBeginPoint.rawScreenPositions(), rawPosList);
635 // moving the point should translate to TouchUpdate
636 rawTouchPoint.setState(Qt::TouchPointMoved);
637 rawTouchPoint.setScreenPos(screenPos + delta);
638 rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
639 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
642 QTest::QTouchEventSequence::touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
643 QCoreApplication::processEvents();
644 QVERIFY(touchWidget.seenTouchBegin);
645 QVERIFY(touchWidget.seenTouchUpdate);
646 QVERIFY(!touchWidget.seenTouchEnd);
647 QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
648 QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
649 QCOMPARE(touchUpdatePoint.id(), rawTouchPoint.id());
650 QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state());
651 QCOMPARE(touchUpdatePoint.pos(), pos + delta);
652 QCOMPARE(touchUpdatePoint.startPos(), pos);
653 QCOMPARE(touchUpdatePoint.lastPos(), pos);
654 QCOMPARE(touchUpdatePoint.scenePos(), rawTouchPoint.screenPos());
655 QCOMPARE(touchUpdatePoint.startScenePos(), screenPos);
656 QCOMPARE(touchUpdatePoint.lastScenePos(), screenPos);
657 QCOMPARE(touchUpdatePoint.screenPos(), rawTouchPoint.screenPos());
658 QCOMPARE(touchUpdatePoint.startScreenPos(), screenPos);
659 QCOMPARE(touchUpdatePoint.lastScreenPos(), screenPos);
660 QCOMPARE(touchUpdatePoint.normalizedPos(), rawTouchPoint.normalizedPos());
661 QCOMPARE(touchUpdatePoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
662 QCOMPARE(touchUpdatePoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
663 QCOMPARE(touchUpdatePoint.rect(), QRectF(pos + delta, QSizeF(0, 0)));
664 QCOMPARE(touchUpdatePoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
665 QCOMPARE(touchUpdatePoint.sceneRect(), touchUpdatePoint.screenRect());
666 QCOMPARE(touchUpdatePoint.pressure(), qreal(1.));
668 // releasing the point translates to TouchEnd
669 rawTouchPoint.setState(Qt::TouchPointReleased);
670 rawTouchPoint.setScreenPos(screenPos + delta + delta);
671 rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
672 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
675 QTest::QTouchEventSequence::touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
676 QCoreApplication::processEvents();
677 QVERIFY(touchWidget.seenTouchBegin);
678 QVERIFY(touchWidget.seenTouchUpdate);
679 QVERIFY(touchWidget.seenTouchEnd);
680 QCOMPARE(touchWidget.touchEndPoints.count(), 1);
681 QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
682 QCOMPARE(touchEndPoint.id(), rawTouchPoint.id());
683 QCOMPARE(touchEndPoint.state(), rawTouchPoint.state());
684 QCOMPARE(touchEndPoint.pos(), pos + delta + delta);
685 QCOMPARE(touchEndPoint.startPos(), pos);
686 QCOMPARE(touchEndPoint.lastPos(), pos + delta);
687 QCOMPARE(touchEndPoint.scenePos(), rawTouchPoint.screenPos());
688 QCOMPARE(touchEndPoint.startScenePos(), screenPos);
689 QCOMPARE(touchEndPoint.lastScenePos(), screenPos + delta);
690 QCOMPARE(touchEndPoint.screenPos(), rawTouchPoint.screenPos());
691 QCOMPARE(touchEndPoint.startScreenPos(), screenPos);
692 QCOMPARE(touchEndPoint.lastScreenPos(), screenPos + delta);
693 QCOMPARE(touchEndPoint.normalizedPos(), rawTouchPoint.normalizedPos());
694 QCOMPARE(touchEndPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
695 QCOMPARE(touchEndPoint.lastNormalizedPos(), touchUpdatePoint.normalizedPos());
696 QCOMPARE(touchEndPoint.rect(), QRectF(pos + delta + delta, QSizeF(0, 0)));
697 QCOMPARE(touchEndPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
698 QCOMPARE(touchEndPoint.sceneRect(), touchEndPoint.screenRect());
699 QCOMPARE(touchEndPoint.pressure(), qreal(0.));
702 void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
704 tst_QTouchEventWidget touchWidget;
705 touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
706 touchWidget.setGeometry(100, 100, 400, 300);
708 tst_QTouchEventWidget leftWidget;
709 leftWidget.setParent(&touchWidget);
710 leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
711 leftWidget.setGeometry(0, 100, 100, 100);
714 tst_QTouchEventWidget rightWidget;
715 rightWidget.setParent(&touchWidget);
716 rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
717 rightWidget.setGeometry(300, 100, 100, 100);
720 QPointF leftPos = leftWidget.rect().center();
721 QPointF rightPos = rightWidget.rect().center();
722 QPointF centerPos = touchWidget.rect().center();
723 QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
724 QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
725 QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
726 QPointF delta(10, 10);
727 QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
729 QList<QTouchEvent::TouchPoint> rawTouchPoints;
730 rawTouchPoints.append(QTouchEvent::TouchPoint(0));
731 rawTouchPoints.append(QTouchEvent::TouchPoint(1));
733 // generate TouchBegins on both leftWidget and rightWidget
734 rawTouchPoints[0].setState(Qt::TouchPointPressed);
735 rawTouchPoints[0].setScreenPos(leftScreenPos);
736 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
737 rawTouchPoints[1].setState(Qt::TouchPointPressed);
738 rawTouchPoints[1].setScreenPos(rightScreenPos);
739 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
740 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
743 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
744 QCoreApplication::processEvents();
745 QVERIFY(!touchWidget.seenTouchBegin);
746 QVERIFY(!touchWidget.seenTouchUpdate);
747 QVERIFY(!touchWidget.seenTouchEnd);
748 QVERIFY(leftWidget.seenTouchBegin);
749 QVERIFY(!leftWidget.seenTouchUpdate);
750 QVERIFY(!leftWidget.seenTouchEnd);
751 QVERIFY(rightWidget.seenTouchBegin);
752 QVERIFY(!rightWidget.seenTouchUpdate);
753 QVERIFY(!rightWidget.seenTouchEnd);
754 QCOMPARE(leftWidget.touchBeginPoints.count(), 1);
755 QCOMPARE(rightWidget.touchBeginPoints.count(), 1);
757 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.first();
758 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
759 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
760 QCOMPARE(leftTouchPoint.pos(), leftPos);
761 QCOMPARE(leftTouchPoint.startPos(), leftPos);
762 QCOMPARE(leftTouchPoint.lastPos(), leftPos);
763 QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
764 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
765 QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
766 QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
767 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
768 QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
769 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
770 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
771 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
772 QCOMPARE(leftTouchPoint.rect(), QRectF(leftPos, QSizeF(0, 0)));
773 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
774 QCOMPARE(leftTouchPoint.screenRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
775 QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
777 QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchBeginPoints.first();
778 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
779 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
780 QCOMPARE(rightTouchPoint.pos(), rightPos);
781 QCOMPARE(rightTouchPoint.startPos(), rightPos);
782 QCOMPARE(rightTouchPoint.lastPos(), rightPos);
783 QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
784 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
785 QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
786 QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
787 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
788 QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
789 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
790 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
791 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
792 QCOMPARE(rightTouchPoint.rect(), QRectF(rightPos, QSizeF(0, 0)));
793 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
794 QCOMPARE(rightTouchPoint.screenRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
795 QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
798 // generate TouchUpdates on both leftWidget and rightWidget
799 rawTouchPoints[0].setState(Qt::TouchPointMoved);
800 rawTouchPoints[0].setScreenPos(centerScreenPos);
801 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
802 rawTouchPoints[1].setState(Qt::TouchPointMoved);
803 rawTouchPoints[1].setScreenPos(centerScreenPos);
804 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
805 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
808 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
809 QCoreApplication::processEvents();
810 QVERIFY(!touchWidget.seenTouchBegin);
811 QVERIFY(!touchWidget.seenTouchUpdate);
812 QVERIFY(!touchWidget.seenTouchEnd);
813 QVERIFY(leftWidget.seenTouchBegin);
814 QVERIFY(leftWidget.seenTouchUpdate);
815 QVERIFY(!leftWidget.seenTouchEnd);
816 QVERIFY(rightWidget.seenTouchBegin);
817 QVERIFY(rightWidget.seenTouchUpdate);
818 QVERIFY(!rightWidget.seenTouchEnd);
819 QCOMPARE(leftWidget.touchUpdatePoints.count(), 1);
820 QCOMPARE(rightWidget.touchUpdatePoints.count(), 1);
822 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.first();
823 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
824 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
825 QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
826 QCOMPARE(leftTouchPoint.startPos(), leftPos);
827 QCOMPARE(leftTouchPoint.lastPos(), leftPos);
828 QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
829 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
830 QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
831 QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
832 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
833 QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
834 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
835 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
836 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
837 QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
838 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
839 QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
840 QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
842 QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchUpdatePoints.first();
843 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
844 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
845 QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
846 QCOMPARE(rightTouchPoint.startPos(), rightPos);
847 QCOMPARE(rightTouchPoint.lastPos(), rightPos);
848 QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
849 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
850 QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
851 QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
852 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
853 QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
854 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
855 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
856 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
857 QCOMPARE(rightTouchPoint.rect(), QRectF(rightWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
858 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
859 QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
860 QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
863 // generate TouchEnds on both leftWidget and rightWidget
864 rawTouchPoints[0].setState(Qt::TouchPointReleased);
865 rawTouchPoints[0].setScreenPos(centerScreenPos);
866 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
867 rawTouchPoints[1].setState(Qt::TouchPointReleased);
868 rawTouchPoints[1].setScreenPos(centerScreenPos);
869 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
870 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
873 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
874 QCoreApplication::processEvents();
875 QVERIFY(!touchWidget.seenTouchBegin);
876 QVERIFY(!touchWidget.seenTouchUpdate);
877 QVERIFY(!touchWidget.seenTouchEnd);
878 QVERIFY(leftWidget.seenTouchBegin);
879 QVERIFY(leftWidget.seenTouchUpdate);
880 QVERIFY(leftWidget.seenTouchEnd);
881 QVERIFY(rightWidget.seenTouchBegin);
882 QVERIFY(rightWidget.seenTouchUpdate);
883 QVERIFY(rightWidget.seenTouchEnd);
884 QCOMPARE(leftWidget.touchEndPoints.count(), 1);
885 QCOMPARE(rightWidget.touchEndPoints.count(), 1);
887 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.first();
888 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
889 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
890 QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
891 QCOMPARE(leftTouchPoint.startPos(), leftPos);
892 QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
893 QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
894 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
895 QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
896 QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
897 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
898 QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
899 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
900 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
901 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
902 QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
903 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
904 QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
905 QCOMPARE(leftTouchPoint.pressure(), qreal(0.));
907 QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchEndPoints.first();
908 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
909 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
910 QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
911 QCOMPARE(rightTouchPoint.startPos(), rightPos);
912 QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
913 QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
914 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
915 QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
916 QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
917 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
918 QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
919 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
920 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
921 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
922 QCOMPARE(rightTouchPoint.rect(), QRectF(rightWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
923 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
924 QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
925 QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
929 void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
931 tst_QTouchEventWidget touchWidget;
932 touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
933 touchWidget.setGeometry(100, 100, 400, 300);
935 tst_QTouchEventWidget leftWidget;
936 leftWidget.setParent(&touchWidget);
937 leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
938 leftWidget.setGeometry(0, 100, 100, 100);
941 tst_QTouchEventWidget rightWidget;
942 rightWidget.setParent(&touchWidget);
943 rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
944 rightWidget.setGeometry(300, 100, 100, 100);
947 QPointF leftPos = leftWidget.rect().center();
948 QPointF rightPos = rightWidget.rect().center();
949 QPointF centerPos = touchWidget.rect().center();
950 QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
951 QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
952 QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
953 QPointF delta(10, 10);
954 QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
956 QList<QTouchEvent::TouchPoint> rawTouchPoints;
957 rawTouchPoints.append(QTouchEvent::TouchPoint(0));
958 rawTouchPoints.append(QTouchEvent::TouchPoint(1));
960 // generate TouchBegin on leftWidget only
961 rawTouchPoints[0].setState(Qt::TouchPointPressed);
962 rawTouchPoints[0].setScreenPos(leftScreenPos);
963 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
964 rawTouchPoints[1].setState(Qt::TouchPointPressed);
965 rawTouchPoints[1].setScreenPos(rightScreenPos);
966 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
967 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
970 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
971 QCoreApplication::processEvents();
972 QVERIFY(!touchWidget.seenTouchBegin);
973 QVERIFY(!touchWidget.seenTouchUpdate);
974 QVERIFY(!touchWidget.seenTouchEnd);
975 QVERIFY(leftWidget.seenTouchBegin);
976 QVERIFY(!leftWidget.seenTouchUpdate);
977 QVERIFY(!leftWidget.seenTouchEnd);
978 QVERIFY(!rightWidget.seenTouchBegin);
979 QVERIFY(!rightWidget.seenTouchUpdate);
980 QVERIFY(!rightWidget.seenTouchEnd);
981 QCOMPARE(leftWidget.touchBeginPoints.count(), 2);
982 QCOMPARE(rightWidget.touchBeginPoints.count(), 0);
984 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.at(0);
985 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
986 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
987 QCOMPARE(leftTouchPoint.pos(), leftPos);
988 QCOMPARE(leftTouchPoint.startPos(), leftPos);
989 QCOMPARE(leftTouchPoint.lastPos(), leftPos);
990 QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
991 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
992 QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
993 QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
994 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
995 QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
996 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
997 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
998 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
999 QCOMPARE(leftTouchPoint.rect(), QRectF(leftPos, QSizeF(0, 0)));
1000 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
1001 QCOMPARE(leftTouchPoint.screenRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
1002 QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
1004 QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchBeginPoints.at(1);
1005 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
1006 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
1007 QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1008 QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1009 QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1010 QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
1011 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
1012 QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
1013 QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
1014 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
1015 QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
1016 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
1017 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
1018 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
1019 QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromGlobal(rightScreenPos.toPoint()), QSizeF(0, 0)));
1020 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
1021 QCOMPARE(rightTouchPoint.screenRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
1022 QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
1025 // generate TouchUpdate on leftWidget
1026 rawTouchPoints[0].setState(Qt::TouchPointMoved);
1027 rawTouchPoints[0].setScreenPos(centerScreenPos);
1028 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
1029 rawTouchPoints[1].setState(Qt::TouchPointMoved);
1030 rawTouchPoints[1].setScreenPos(centerScreenPos);
1031 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
1032 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
1035 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
1036 QCoreApplication::processEvents();
1037 QVERIFY(!touchWidget.seenTouchBegin);
1038 QVERIFY(!touchWidget.seenTouchUpdate);
1039 QVERIFY(!touchWidget.seenTouchEnd);
1040 QVERIFY(leftWidget.seenTouchBegin);
1041 QVERIFY(leftWidget.seenTouchUpdate);
1042 QVERIFY(!leftWidget.seenTouchEnd);
1043 QVERIFY(!rightWidget.seenTouchBegin);
1044 QVERIFY(!rightWidget.seenTouchUpdate);
1045 QVERIFY(!rightWidget.seenTouchEnd);
1046 QCOMPARE(leftWidget.touchUpdatePoints.count(), 2);
1047 QCOMPARE(rightWidget.touchUpdatePoints.count(), 0);
1049 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.at(0);
1050 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
1051 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
1052 QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
1053 QCOMPARE(leftTouchPoint.startPos(), leftPos);
1054 QCOMPARE(leftTouchPoint.lastPos(), leftPos);
1055 QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
1056 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
1057 QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
1058 QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
1059 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
1060 QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
1061 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
1062 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
1063 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
1064 QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
1065 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1066 QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1067 QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
1069 QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchUpdatePoints.at(1);
1070 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
1071 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
1072 QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
1073 QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1074 QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1075 QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
1076 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
1077 QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
1078 QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
1079 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
1080 QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
1081 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
1082 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
1083 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
1084 QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
1085 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1086 QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1087 QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
1090 // generate TouchEnd on leftWidget
1091 rawTouchPoints[0].setState(Qt::TouchPointReleased);
1092 rawTouchPoints[0].setScreenPos(centerScreenPos);
1093 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
1094 rawTouchPoints[1].setState(Qt::TouchPointReleased);
1095 rawTouchPoints[1].setScreenPos(centerScreenPos);
1096 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
1097 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
1100 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
1101 QCoreApplication::processEvents();
1102 QVERIFY(!touchWidget.seenTouchBegin);
1103 QVERIFY(!touchWidget.seenTouchUpdate);
1104 QVERIFY(!touchWidget.seenTouchEnd);
1105 QVERIFY(leftWidget.seenTouchBegin);
1106 QVERIFY(leftWidget.seenTouchUpdate);
1107 QVERIFY(leftWidget.seenTouchEnd);
1108 QVERIFY(!rightWidget.seenTouchBegin);
1109 QVERIFY(!rightWidget.seenTouchUpdate);
1110 QVERIFY(!rightWidget.seenTouchEnd);
1111 QCOMPARE(leftWidget.touchEndPoints.count(), 2);
1112 QCOMPARE(rightWidget.touchEndPoints.count(), 0);
1114 QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.at(0);
1115 QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
1116 QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
1117 QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
1118 QCOMPARE(leftTouchPoint.startPos(), leftPos);
1119 QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
1120 QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
1121 QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
1122 QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
1123 QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
1124 QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
1125 QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
1126 QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
1127 QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
1128 QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
1129 QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
1130 QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1131 QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1132 QCOMPARE(leftTouchPoint.pressure(), qreal(0.));
1134 QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchEndPoints.at(1);
1135 QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
1136 QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
1137 QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
1138 QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
1139 QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
1140 QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
1141 QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
1142 QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
1143 QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
1144 QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
1145 QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
1146 QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
1147 QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
1148 QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
1149 QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
1150 QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1151 QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
1152 QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
1156 void tst_QTouchEvent::deleteInEventHandler()
1161 tst_QTouchEventWidget *child1, *child2, *child3;
1162 child1 = new tst_QTouchEventWidget;
1163 child2 = new tst_QTouchEventWidget;
1164 child3 = new tst_QTouchEventWidget;
1165 child1->setParent(&window);
1166 child2->setParent(&window);
1167 child3->setParent(&window);
1168 child1->setAttribute(Qt::WA_AcceptTouchEvents);
1169 child2->setAttribute(Qt::WA_AcceptTouchEvents);
1170 child3->setAttribute(Qt::WA_AcceptTouchEvents);
1171 child1->deleteInTouchBegin = true;
1172 child2->deleteInTouchUpdate = true;
1173 child3->deleteInTouchEnd = true;
1175 QList<QTouchEvent::TouchPoint> touchPoints;
1176 touchPoints.append(QTouchEvent::TouchPoint(0));
1177 QTouchEvent touchBeginEvent(QEvent::TouchBegin,
1180 Qt::TouchPointPressed,
1182 QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
1185 Qt::TouchPointStationary,
1187 QTouchEvent touchEndEvent(QEvent::TouchEnd,
1190 Qt::TouchPointReleased,
1192 QPointer<QWidget> p;
1195 touchBeginEvent.ignore();
1197 res = QApplication::sendEvent(child1, &touchBeginEvent);
1198 // event is handled, but widget should be deleted
1199 QVERIFY(res && touchBeginEvent.isAccepted() && p.isNull());
1201 touchBeginEvent.ignore();
1203 res = QApplication::sendEvent(child2, &touchBeginEvent);
1204 QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull());
1205 touchUpdateEvent.ignore();
1206 res = QApplication::sendEvent(child2, &touchUpdateEvent);
1207 QVERIFY(res && touchUpdateEvent.isAccepted() && p.isNull());
1209 touchBeginEvent.ignore();
1211 res = QApplication::sendEvent(child3, &touchBeginEvent);
1212 QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull());
1213 touchUpdateEvent.ignore();
1214 res = QApplication::sendEvent(child3, &touchUpdateEvent);
1215 QVERIFY(res && touchUpdateEvent.isAccepted() && !p.isNull());
1216 touchEndEvent.ignore();
1217 res = QApplication::sendEvent(child3, &touchEndEvent);
1218 QVERIFY(res && touchEndEvent.isAccepted() && p.isNull());
1223 QGraphicsScene scene;
1224 QGraphicsView view(&scene);
1225 tst_QTouchEventGraphicsItem *root, *child1, *child2, *child3;
1226 root = new tst_QTouchEventGraphicsItem;
1227 child1 = new tst_QTouchEventGraphicsItem;
1228 child2 = new tst_QTouchEventGraphicsItem;
1229 child3 = new tst_QTouchEventGraphicsItem;
1230 child1->setParentItem(root);
1231 child2->setParentItem(root);
1232 child3->setParentItem(root);
1233 child1->setZValue(1.);
1234 child2->setZValue(0.);
1235 child3->setZValue(-1.);
1236 child1->setAcceptTouchEvents(true);
1237 child2->setAcceptTouchEvents(true);
1238 child3->setAcceptTouchEvents(true);
1239 child1->deleteInTouchBegin = true;
1240 child2->deleteInTouchUpdate = true;
1241 child3->deleteInTouchEnd = true;
1243 scene.addItem(root);
1244 view.resize(200, 200);
1245 view.fitInView(scene.sceneRect());
1247 QTouchEvent::TouchPoint touchPoint(0);
1248 touchPoint.setState(Qt::TouchPointPressed);
1249 touchPoint.setPos(view.mapFromScene(child1->mapToScene(child1->boundingRect().center())));
1250 touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint()));
1251 touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint()));
1252 QList<QTouchEvent::TouchPoint> touchPoints;
1253 touchPoints.append(touchPoint);
1254 QTouchEvent touchBeginEvent(QEvent::TouchBegin,
1257 Qt::TouchPointPressed,
1259 touchPoints[0].setState(Qt::TouchPointMoved);
1260 QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
1263 Qt::TouchPointMoved,
1265 touchPoints[0].setState(Qt::TouchPointReleased);
1266 QTouchEvent touchEndEvent(QEvent::TouchEnd,
1269 Qt::TouchPointReleased,
1273 child1->weakpointer = &child1;
1274 touchBeginEvent.ignore();
1275 res = QApplication::sendEvent(view.viewport(), &touchBeginEvent);
1276 QVERIFY(res && touchBeginEvent.isAccepted() && !child1);
1277 touchUpdateEvent.ignore();
1278 res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent);
1279 QVERIFY(res && touchUpdateEvent.isAccepted() && !child1);
1280 touchEndEvent.ignore();
1281 res = QApplication::sendEvent(view.viewport(), &touchEndEvent);
1282 QVERIFY(res && touchUpdateEvent.isAccepted() && !child1);
1284 child2->weakpointer = &child2;
1285 touchBeginEvent.ignore();
1286 res = QApplication::sendEvent(view.viewport(), &touchBeginEvent);
1287 QVERIFY(res && touchBeginEvent.isAccepted() && child2);
1288 touchUpdateEvent.ignore();
1289 res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent);
1290 QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2);
1291 touchEndEvent.ignore();
1292 res = QApplication::sendEvent(view.viewport(), &touchEndEvent);
1293 QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2);
1295 child3->weakpointer = &child3;
1296 res = QApplication::sendEvent(view.viewport(), &touchBeginEvent);
1297 QVERIFY(res && touchBeginEvent.isAccepted() && child3);
1298 res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent);
1299 QVERIFY(res && !touchUpdateEvent.isAccepted() && child3);
1300 res = QApplication::sendEvent(view.viewport(), &touchEndEvent);
1301 QVERIFY(res && !touchEndEvent.isAccepted() && !child3);
1307 void tst_QTouchEvent::deleteInRawEventTranslation()
1309 tst_QTouchEventWidget touchWidget;
1310 touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
1311 touchWidget.setGeometry(100, 100, 300, 300);
1313 tst_QTouchEventWidget *leftWidget = new tst_QTouchEventWidget;
1314 leftWidget->setParent(&touchWidget);
1315 leftWidget->setAttribute(Qt::WA_AcceptTouchEvents);
1316 leftWidget->setGeometry(0, 100, 100, 100);
1317 leftWidget->deleteInTouchBegin = true;
1320 tst_QTouchEventWidget *centerWidget = new tst_QTouchEventWidget;
1321 centerWidget->setParent(&touchWidget);
1322 centerWidget->setAttribute(Qt::WA_AcceptTouchEvents);
1323 centerWidget->setGeometry(100, 100, 100, 100);
1324 centerWidget->deleteInTouchUpdate = true;
1325 centerWidget->show();
1327 tst_QTouchEventWidget *rightWidget = new tst_QTouchEventWidget;
1328 rightWidget->setParent(&touchWidget);
1329 rightWidget->setAttribute(Qt::WA_AcceptTouchEvents);
1330 rightWidget->setGeometry(200, 100, 100, 100);
1331 rightWidget->deleteInTouchEnd = true;
1332 rightWidget->show();
1334 QPointF leftPos = leftWidget->rect().center();
1335 QPointF centerPos = centerWidget->rect().center();
1336 QPointF rightPos = rightWidget->rect().center();
1337 QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint());
1338 QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint());
1339 QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint());
1340 QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
1342 QPointer<QWidget> pl = leftWidget, pc = centerWidget, pr = rightWidget;
1344 QList<QTouchEvent::TouchPoint> rawTouchPoints;
1345 rawTouchPoints.append(QTouchEvent::TouchPoint(0));
1346 rawTouchPoints.append(QTouchEvent::TouchPoint(1));
1347 rawTouchPoints.append(QTouchEvent::TouchPoint(2));
1348 rawTouchPoints[0].setState(Qt::TouchPointPressed);
1349 rawTouchPoints[0].setScreenPos(leftScreenPos);
1350 rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
1351 rawTouchPoints[1].setState(Qt::TouchPointPressed);
1352 rawTouchPoints[1].setScreenPos(centerScreenPos);
1353 rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
1354 rawTouchPoints[2].setState(Qt::TouchPointPressed);
1355 rawTouchPoints[2].setScreenPos(rightScreenPos);
1356 rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry));
1358 // generate begin events on all widgets, the left widget should die
1359 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
1362 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
1363 QCoreApplication::processEvents();
1364 QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull());
1366 // generate update events on all widget, the center widget should die
1367 rawTouchPoints[0].setState(Qt::TouchPointMoved);
1368 rawTouchPoints[1].setState(Qt::TouchPointMoved);
1369 rawTouchPoints[2].setState(Qt::TouchPointMoved);
1370 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
1373 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
1374 QCoreApplication::processEvents();
1376 // generate end events on all widget, the right widget should die
1377 rawTouchPoints[0].setState(Qt::TouchPointReleased);
1378 rawTouchPoints[1].setState(Qt::TouchPointReleased);
1379 rawTouchPoints[2].setState(Qt::TouchPointReleased);
1380 QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
1383 QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
1384 QCoreApplication::processEvents();
1387 void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin()
1389 QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100);
1390 rect->setAcceptTouchEvents(true);
1392 QGraphicsRectItem *mainRect = new QGraphicsRectItem(0, 0, 100, 100, rect);
1393 mainRect->setBrush(Qt::lightGray);
1395 QGraphicsRectItem *button = new QGraphicsRectItem(-20, -20, 40, 40, mainRect);
1396 button->setPos(50, 50);
1397 button->setBrush(Qt::darkGreen);
1400 QGraphicsScene scene;
1401 scene.addItem(rect);
1402 scene.setSceneRect(0,0,100,100);
1403 view.setScene(&scene);
1406 QVERIFY(QTest::qWaitForWindowExposed(&view));
1408 QPoint centerPos = view.mapFromScene(rect->boundingRect().center());
1410 QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, centerPos, static_cast<QWindow *>(0));
1411 QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, centerPos, static_cast<QWindow *>(0));
1412 // Touch outside of the button
1413 QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, view.mapFromScene(QPoint(10, 10)), static_cast<QWindow *>(0));
1414 QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, view.mapFromScene(QPoint(10, 10)), static_cast<QWindow *>(0));
1417 void tst_QTouchEvent::touchBeginWithGraphicsWidget()
1419 QGraphicsScene scene;
1420 QGraphicsView view(&scene);
1421 tst_QTouchEventGraphicsItem *root;
1422 root = new tst_QTouchEventGraphicsItem;
1423 root->setAcceptTouchEvents(true);
1424 scene.addItem(root);
1426 QGraphicsWidget *glassWidget = new QGraphicsWidget;
1427 glassWidget->setMinimumSize(100, 100);
1428 scene.addItem(glassWidget);
1430 view.resize(200, 200);
1432 QVERIFY(QTest::qWaitForWindowExposed(&view));
1433 view.fitInView(scene.sceneRect());
1435 QTest::touchEvent(&view, touchScreenDevice)
1436 .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
1437 QTest::touchEvent(&view, touchScreenDevice)
1439 .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
1440 QTest::touchEvent(&view, touchScreenDevice)
1441 .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
1442 .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
1444 QCOMPARE(root->touchBeginCounter, 1);
1445 QCOMPARE(root->touchUpdateCounter, 1);
1446 QCOMPARE(root->touchEndCounter, 1);
1447 QCOMPARE(root->touchUpdatePoints.size(), 2);
1450 glassWidget->setWindowFlags(Qt::Window); // make the glassWidget a panel
1452 QTest::touchEvent(&view, touchScreenDevice)
1453 .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
1454 QTest::touchEvent(&view, touchScreenDevice)
1456 .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
1457 QTest::touchEvent(&view, touchScreenDevice)
1458 .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
1459 .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
1461 QCOMPARE(root->touchBeginCounter, 0);
1462 QCOMPARE(root->touchUpdateCounter, 0);
1463 QCOMPARE(root->touchEndCounter, 0);
1470 class WindowTouchEventFilter : public QObject
1474 bool eventFilter(QObject *obj, QEvent *event);
1476 QList<QTouchEvent::TouchPoint> points;
1477 QEvent::Type lastSeenType;
1479 QMap<QTouchDevice *, TouchInfo> d;
1482 bool WindowTouchEventFilter::eventFilter(QObject *, QEvent *event)
1484 if (event->type() == QEvent::TouchBegin
1485 || event->type() == QEvent::TouchUpdate
1486 || event->type() == QEvent::TouchEnd) {
1487 QTouchEvent *te = static_cast<QTouchEvent *>(event);
1488 TouchInfo &td = d[te->device()];
1489 if (event->type() == QEvent::TouchBegin)
1491 td.points.append(te->touchPoints());
1492 td.lastSeenType = event->type();
1497 void tst_QTouchEvent::testQGuiAppDelivery()
1499 QTouchDevice *device = new QTouchDevice;
1500 device->setType(QTouchDevice::TouchScreen);
1501 QWindowSystemInterface::registerTouchDevice(device);
1503 QWindow *w = new QWindow;
1504 w->setGeometry(100, 100, 100, 100);
1506 QVERIFY(QTest::qWaitForWindowExposed(w));
1508 WindowTouchEventFilter filter;
1509 w->installEventFilter(&filter);
1511 QList<QWindowSystemInterface::TouchPoint> points;
1513 // Pass empty list, should be ignored.
1514 QWindowSystemInterface::handleTouchEvent(w, 0, points);
1515 QCoreApplication::processEvents();
1516 QCOMPARE(filter.d.isEmpty(), true);
1518 QWindowSystemInterface::TouchPoint tp;
1520 tp.state = Qt::TouchPointPressed;
1521 tp.area = QRectF(120, 120, 20, 20);
1524 // Pass 0 as device, should be ignored.
1525 QWindowSystemInterface::handleTouchEvent(w, 0, points);
1526 QCoreApplication::processEvents();
1527 QCOMPARE(filter.d.isEmpty(), true);
1529 // Now the real thing.
1530 QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchBegin
1531 QCoreApplication::processEvents();
1532 QCOMPARE(filter.d.count(), 1);
1533 QCOMPARE(filter.d.contains(device), true);
1534 QCOMPARE(filter.d.value(device).points.count(), 1);
1535 QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchBegin);
1537 points[0].state = Qt::TouchPointMoved;
1538 QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchUpdate
1539 QCoreApplication::processEvents();
1540 QCOMPARE(filter.d.count(), 1);
1541 QCOMPARE(filter.d.contains(device), true);
1542 QCOMPARE(filter.d.value(device).points.count(), 2);
1543 QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchUpdate);
1545 points[0].state = Qt::TouchPointReleased;
1546 QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchEnd
1547 QCoreApplication::processEvents();
1548 QCOMPARE(filter.d.count(), 1);
1549 QCOMPARE(filter.d.contains(device), true);
1550 QCOMPARE(filter.d.value(device).points.count(), 3);
1551 QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchEnd);
1554 void tst_QTouchEvent::testMultiDevice()
1556 QTouchDevice *deviceOne = new QTouchDevice;
1557 deviceOne->setType(QTouchDevice::TouchScreen);
1558 QWindowSystemInterface::registerTouchDevice(deviceOne);
1559 QTouchDevice *deviceTwo = new QTouchDevice;
1560 deviceTwo->setType(QTouchDevice::TouchScreen);
1561 QWindowSystemInterface::registerTouchDevice(deviceTwo);
1563 QWindow *w = new QWindow;
1564 w->setGeometry(100, 100, 100, 100);
1566 QVERIFY(QTest::qWaitForWindowExposed(w));
1568 WindowTouchEventFilter filter;
1569 w->installEventFilter(&filter);
1571 QList<QWindowSystemInterface::TouchPoint> pointsOne, pointsTwo;
1573 // deviceOne reports a single point, deviceTwo reports the beginning of a multi-point sequence.
1574 // Even though there is a point with id 0 for both devices, they should be delivered cleanly, independently.
1575 QWindowSystemInterface::TouchPoint tp;
1577 tp.state = Qt::TouchPointPressed;
1578 tp.area = QRectF(120, 120, 20, 20);
1579 pointsOne.append(tp);
1581 pointsTwo.append(tp);
1583 tp.area = QRectF(140, 140, 20, 20);
1584 pointsTwo.append(tp);
1586 QWindowSystemInterface::handleTouchEvent(w, deviceOne, pointsOne);
1587 QWindowSystemInterface::handleTouchEvent(w, deviceTwo, pointsTwo);
1588 QCoreApplication::processEvents();
1590 QCOMPARE(filter.d.contains(deviceOne), true);
1591 QCOMPARE(filter.d.contains(deviceTwo), true);
1593 QCOMPARE(filter.d.value(deviceOne).lastSeenType, QEvent::TouchBegin);
1594 QCOMPARE(filter.d.value(deviceTwo).lastSeenType, QEvent::TouchBegin);
1595 QCOMPARE(filter.d.value(deviceOne).points.count(), 1);
1596 QCOMPARE(filter.d.value(deviceTwo).points.count(), 2);
1598 QCOMPARE(filter.d.value(deviceOne).points.at(0).screenRect(), pointsOne[0].area);
1599 QCOMPARE(filter.d.value(deviceOne).points.at(0).state(), pointsOne[0].state);
1601 QCOMPARE(filter.d.value(deviceTwo).points.at(0).screenRect(), pointsTwo[0].area);
1602 QCOMPARE(filter.d.value(deviceTwo).points.at(0).state(), pointsTwo[0].state);
1603 QCOMPARE(filter.d.value(deviceTwo).points.at(1).screenRect(), pointsTwo[1].area);
1604 QCOMPARE(filter.d.value(deviceTwo).points.at(1).state(), pointsTwo[1].state);
1607 QTEST_MAIN(tst_QTouchEvent)
1609 #include "tst_qtouchevent.moc"