1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include <QTouchEvent>
45 #include <QtQuick/QQuickItem>
46 #include <QtQuick/QQuickCanvas>
47 #include <QtDeclarative/QDeclarativeEngine>
48 #include <QtDeclarative/QDeclarativeComponent>
49 #include <QtQuick/private/qquickrectangle_p.h>
50 #include <QtGui/QWindowSystemInterface>
51 #include "../../shared/util.h"
54 struct TouchEventData {
58 Qt::TouchPointStates states;
59 QList<QTouchEvent::TouchPoint> touchPoints;
62 static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF())
64 QPointF last = lastPoint.isNull() ? p : lastPoint;
66 QTouchEvent::TouchPoint tp;
70 tp.setScenePos(item->mapToScene(p));
71 tp.setLastScenePos(item->mapToScene(last));
72 tp.setScreenPos(item->canvas()->mapToGlobal(tp.scenePos().toPoint()));
73 tp.setLastScreenPos(item->canvas()->mapToGlobal(tp.lastScenePos().toPoint()));
77 static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint>& touchPoints)
79 TouchEventData d = { type, 0, w, states, touchPoints };
82 static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
84 QList<QTouchEvent::TouchPoint> points;
86 return makeTouchData(type, w, states, points);
89 #define COMPARE_TOUCH_POINTS(tp1, tp2) \
91 QCOMPARE(tp1.pos(), tp2.pos()); \
92 QCOMPARE(tp1.lastPos(), tp2.lastPos()); \
93 QCOMPARE(tp1.scenePos(), tp2.scenePos()); \
94 QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \
95 QCOMPARE(tp1.screenPos(), tp2.screenPos()); \
96 QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \
99 #define COMPARE_TOUCH_DATA(d1, d2) \
101 QCOMPARE((int)d1.type, (int)d2.type); \
102 QCOMPARE(d1.widget, d2.widget); \
103 QCOMPARE((int)d1.states, (int)d2.states); \
104 QCOMPARE(d1.touchPoints.count(), d2.touchPoints.count()); \
105 for (int i=0; i<d1.touchPoints.count(); i++) { \
106 COMPARE_TOUCH_POINTS(d1.touchPoints[i], d2.touchPoints[i]); \
110 class TestTouchItem : public QQuickRectangle
114 TestTouchItem(QQuickItem *parent = 0)
115 : QQuickRectangle(parent), acceptEvents(true), mousePressId(0)
117 border()->setWidth(1);
118 setAcceptedMouseButtons(Qt::LeftButton);
119 setFiltersChildMouseEvents(true);
127 lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
130 static void clearMousePressCounter()
136 TouchEventData lastEvent;
139 virtual void touchEvent(QTouchEvent *event) {
144 lastEvent = makeTouchData(event->type(), event->window(), event->touchPointStates(), event->touchPoints());
148 virtual void mousePressEvent(QMouseEvent *) {
149 mousePressId = ++mousePressNum;
152 bool childMouseEventFilter(QQuickItem *, QEvent *event) {
153 if (event->type() == QEvent::MouseButtonPress)
154 mousePressId = ++mousePressNum;
158 static int mousePressNum;
161 int TestTouchItem::mousePressNum = 0;
163 class ConstantUpdateItem : public QQuickItem
167 ConstantUpdateItem(QQuickItem *parent = 0) : QQuickItem(parent), iterations(0) {setFlag(ItemHasContents);}
171 QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){
178 class tst_qquickcanvas : public QDeclarativeDataTest
186 QDeclarativeDataTest::initTestCase();
187 touchDevice = new QTouchDevice();
188 touchDevice->setType(QTouchDevice::TouchScreen);
189 QWindowSystemInterface::registerTouchDevice(touchDevice);
193 void constantUpdates();
194 void mouseFiltering();
197 void touchEvent_basic();
198 void touchEvent_propagation();
199 void touchEvent_propagation_data();
207 void multipleWindows();
209 void animationsWhileHidden();
214 QTouchDevice *touchDevice;
217 //If the item calls update inside updatePaintNode, it should schedule another update
218 void tst_qquickcanvas::constantUpdates()
221 canvas.resize(250, 250);
222 ConstantUpdateItem item(canvas.rootItem());
224 QTRY_VERIFY(item.iterations > 60);
227 void tst_qquickcanvas::touchEvent_basic()
229 TestTouchItem::clearMousePressCounter();
231 QQuickCanvas *canvas = new QQuickCanvas;
232 canvas->resize(250, 250);
233 canvas->move(100, 100);
236 TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
237 bottomItem->setObjectName("Bottom Item");
238 bottomItem->setSize(QSizeF(150, 150));
240 TestTouchItem *middleItem = new TestTouchItem(bottomItem);
241 middleItem->setObjectName("Middle Item");
242 middleItem->setPos(QPointF(50, 50));
243 middleItem->setSize(QSizeF(150, 150));
245 TestTouchItem *topItem = new TestTouchItem(middleItem);
246 topItem->setObjectName("Top Item");
247 topItem->setPos(QPointF(50, 50));
248 topItem->setSize(QSizeF(150, 150));
252 // press single point
253 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),canvas);
256 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
258 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
259 QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
260 TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos));
261 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
264 // press multiple points
265 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),canvas)
266 .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
268 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
269 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
270 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
271 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
272 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
276 // touch point on top item moves to bottom item, but top item should still receive the event
277 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), canvas);
279 QTest::touchEvent(canvas, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
281 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
282 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
283 makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
286 // touch point on bottom item moves to top item, but bottom item should still receive the event
287 QTest::touchEvent(canvas, touchDevice).press(0, bottomItem->mapToScene(pos).toPoint(), canvas);
289 QTest::touchEvent(canvas, touchDevice).move(0, topItem->mapToScene(pos).toPoint(), canvas);
291 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
292 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
293 makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
296 // a single stationary press on an item shouldn't cause an event
297 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), canvas);
299 QTest::touchEvent(canvas, touchDevice).stationary(0)
300 .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
302 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary
303 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
304 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
305 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
306 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
310 // move touch point from top item to bottom, and release
311 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),canvas);
313 QTest::touchEvent(canvas, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(),canvas);
315 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
316 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
317 makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
320 // release while another point is pressed
321 QTest::touchEvent(canvas, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),canvas)
322 .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
324 QTest::touchEvent(canvas, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
326 QTest::touchEvent(canvas, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), canvas)
329 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
330 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
331 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
332 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
333 makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos))));
334 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
344 void tst_qquickcanvas::touchEvent_propagation()
346 TestTouchItem::clearMousePressCounter();
348 QFETCH(bool, acceptEvents);
349 QFETCH(bool, enableItem);
350 QFETCH(qreal, itemOpacity);
352 QQuickCanvas *canvas = new QQuickCanvas;
353 canvas->resize(250, 250);
354 canvas->move(100, 100);
357 TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
358 bottomItem->setObjectName("Bottom Item");
359 bottomItem->setSize(QSizeF(150, 150));
361 TestTouchItem *middleItem = new TestTouchItem(bottomItem);
362 middleItem->setObjectName("Middle Item");
363 middleItem->setPos(QPointF(50, 50));
364 middleItem->setSize(QSizeF(150, 150));
366 TestTouchItem *topItem = new TestTouchItem(middleItem);
367 topItem->setObjectName("Top Item");
368 topItem->setPos(QPointF(50, 50));
369 topItem->setSize(QSizeF(150, 150));
372 QPoint pointInBottomItem = bottomItem->mapToScene(pos).toPoint(); // (10, 10)
373 QPoint pointInMiddleItem = middleItem->mapToScene(pos).toPoint(); // (60, 60) overlaps with bottomItem
374 QPoint pointInTopItem = topItem->mapToScene(pos).toPoint(); // (110, 110) overlaps with bottom & top items
377 topItem->acceptEvents = acceptEvents;
378 topItem->setEnabled(enableItem);
379 topItem->setOpacity(itemOpacity);
381 // single touch to top item, should be received by middle item
382 QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
384 QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
385 QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1);
386 QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
387 COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
388 makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))));
390 // touch top and middle items, middle item should get both events
391 QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
392 .press(1, pointInMiddleItem, canvas);
394 QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
395 QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2);
396 QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
397 COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
398 (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
399 << makeTouchPoint(middleItem, pos) )));
402 // disable middleItem as well
403 middleItem->acceptEvents = acceptEvents;
404 middleItem->setEnabled(enableItem);
405 middleItem->setOpacity(itemOpacity);
407 // touch top and middle items, bottom item should get all events
408 QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
409 .press(1, pointInMiddleItem, canvas);
411 QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
412 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
413 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2);
414 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
415 (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))
416 << makeTouchPoint(bottomItem, bottomItem->mapFromItem(middleItem, pos)) )));
419 // disable bottom item as well
420 bottomItem->acceptEvents = acceptEvents;
421 bottomItem->setEnabled(enableItem);
422 bottomItem->setOpacity(itemOpacity);
424 // no events should be received
425 QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
426 .press(1, pointInMiddleItem, canvas)
427 .press(2, pointInBottomItem, canvas);
429 QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
430 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
431 QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
437 // disable middle item, touch on top item
438 middleItem->acceptEvents = acceptEvents;
439 middleItem->setEnabled(enableItem);
440 middleItem->setOpacity(itemOpacity);
441 QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
443 if (!enableItem || itemOpacity == 0) {
444 // middle item is disabled or has 0 opacity, bottom item receives the event
445 QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
446 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
447 QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
448 COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
449 makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))));
451 // middle item ignores event, sends it to the top item (top-most child)
452 QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
453 QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
454 QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
455 COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
456 makeTouchPoint(topItem, pos)));
465 void tst_qquickcanvas::touchEvent_propagation_data()
467 QTest::addColumn<bool>("acceptEvents");
468 QTest::addColumn<bool>("enableItem");
469 QTest::addColumn<qreal>("itemOpacity");
471 QTest::newRow("disable events") << false << true << 1.0;
472 QTest::newRow("disable item") << true << false << 1.0;
473 QTest::newRow("opacity of 0") << true << true << 0.0;
476 void tst_qquickcanvas::clearCanvas()
478 QQuickCanvas *canvas = new QQuickCanvas;
479 QQuickItem *item = new QQuickItem;
480 item->setParentItem(canvas->rootItem());
482 QVERIFY(item->canvas() == canvas);
486 QVERIFY(item->canvas() == 0);
491 void tst_qquickcanvas::mouseFiltering()
493 TestTouchItem::clearMousePressCounter();
495 QQuickCanvas *canvas = new QQuickCanvas;
496 canvas->resize(250, 250);
497 canvas->move(100, 100);
500 TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
501 bottomItem->setObjectName("Bottom Item");
502 bottomItem->setSize(QSizeF(150, 150));
504 TestTouchItem *middleItem = new TestTouchItem(bottomItem);
505 middleItem->setObjectName("Middle Item");
506 middleItem->setPos(QPointF(50, 50));
507 middleItem->setSize(QSizeF(150, 150));
509 TestTouchItem *topItem = new TestTouchItem(middleItem);
510 topItem->setObjectName("Top Item");
511 topItem->setPos(QPointF(50, 50));
512 topItem->setSize(QSizeF(150, 150));
514 QPoint pos(100, 100);
516 QTest::mousePress(canvas, Qt::LeftButton, 0, pos);
518 // Mouse filtering propagates down the stack, so the
520 // 1. middleItem filters event
521 // 2. bottomItem filters event
522 // 3. topItem receives event
523 QTRY_COMPARE(middleItem->mousePressId, 1);
524 QTRY_COMPARE(bottomItem->mousePressId, 2);
525 QTRY_COMPARE(topItem->mousePressId, 3);
530 void tst_qquickcanvas::qmlCreation()
532 QDeclarativeEngine engine;
533 QDeclarativeComponent component(&engine);
534 component.loadUrl(testFileUrl("window.qml"));
535 QObject* created = component.create();
538 QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created);
540 QCOMPARE(canvas->clearColor(), QColor(Qt::green));
542 QQuickItem* item = canvas->findChild<QQuickItem*>("item");
544 QCOMPARE(item->canvas(), canvas);
549 void tst_qquickcanvas::clearColor()
551 //### Can we examine rendering to make sure it is really blue?
552 QQuickCanvas *canvas = new QQuickCanvas;
553 canvas->resize(250, 250);
554 canvas->move(100, 100);
555 canvas->setClearColor(Qt::blue);
557 QTest::qWaitForWindowShown(canvas);
558 QCOMPARE(canvas->clearColor(), QColor(Qt::blue));
562 void tst_qquickcanvas::grab()
565 canvas.setClearColor(Qt::red);
567 canvas.resize(250, 250);
570 QImage content = canvas.grabFrameBuffer();
571 QCOMPARE(content.width(), canvas.width());
572 QCOMPARE(content.height(), canvas.height());
573 QCOMPARE((uint) content.convertToFormat(QImage::Format_RGB32).pixel(0, 0), (uint) 0xffff0000);
576 void tst_qquickcanvas::multipleWindows()
578 QList<QQuickCanvas *> windows;
579 for (int i=0; i<6; ++i) {
580 QQuickCanvas *c = new QQuickCanvas();
581 c->setClearColor(Qt::GlobalColor(Qt::red + i));
583 c->setPos(100 + i * 30, 100 + i * 20);
586 QVERIFY(c->visible());
590 for (int i=0; i<windows.size(); ++i) {
591 QQuickCanvas *c = windows.at(i);
592 c->setPos(c->x() - 10, c->y() - 10);
596 for (int i=0; i<windows.size(); ++i) {
597 QQuickCanvas *c = windows.at(i);
604 void tst_qquickcanvas::animationsWhileHidden()
606 QDeclarativeEngine engine;
607 QDeclarativeComponent component(&engine);
608 component.loadUrl(testFileUrl("AnimationsWhileHidden.qml"));
609 QObject* created = component.create();
611 QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created);
613 QVERIFY(canvas->visible());
615 // Now hide the window and verify that it went off screen
618 QVERIFY(!canvas->visible());
620 // Running animaiton should cause it to become visible again shortly.
621 QTRY_VERIFY(canvas->visible());
627 void tst_qquickcanvas::headless()
629 QDeclarativeEngine engine;
630 QDeclarativeComponent component(&engine);
631 component.loadUrl(testFileUrl("Headless.qml"));
632 QObject* created = component.create();
634 QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created);
637 QTest::qWaitForWindowShown(canvas);
638 QVERIFY(canvas->visible());
640 QSignalSpy initialized(canvas, SIGNAL(sceneGraphInitialized()));
641 QSignalSpy invalidated(canvas, SIGNAL(sceneGraphInvalidated()));
643 // Verify that the canvas is alive and kicking
644 QVERIFY(canvas->openglContext() != 0);
646 // Store the visual result
647 QImage originalContent = canvas->grabFrameBuffer();
649 // Hide the canvas and verify signal emittion and GL context deletion
651 QCOMPARE(invalidated.size(), 1);
652 QVERIFY(canvas->openglContext() == 0);
654 // Destroy the native windowing system buffers
656 QVERIFY(canvas->handle() == 0);
658 // Show and verify that we are back and running
660 QTest::qWaitForWindowShown(canvas);
662 QCOMPARE(initialized.size(), 1);
663 QVERIFY(canvas->openglContext() != 0);
665 // Verify that the visual output is the same
666 QImage newContent = canvas->grabFrameBuffer();
668 QCOMPARE(originalContent, newContent);
673 void tst_qquickcanvas::focusObject()
675 QDeclarativeEngine engine;
676 QDeclarativeComponent component(&engine);
677 component.loadUrl(testFileUrl("focus.qml"));
678 QObject *created = component.create();
681 QQuickCanvas *canvas = qobject_cast<QQuickCanvas*>(created);
684 QQuickItem *item1 = canvas->findChild<QQuickItem*>("item1");
686 item1->setFocus(true);
687 QCOMPARE(item1, canvas->focusObject());
689 QQuickItem *item2 = canvas->findChild<QQuickItem*>("item2");
691 item2->setFocus(true);
692 QCOMPARE(item2, canvas->focusObject());
697 QTEST_MAIN(tst_qquickcanvas)
699 #include "tst_qquickcanvas.moc"