aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp1
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp5
-rw-r--r--src/qml/qml/qqmlmetatype.cpp4
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc4
-rw-r--r--src/quick/items/qquickitem.cpp4
-rw-r--r--src/quick/items/qquicklistview.cpp8
-rw-r--r--src/quick/items/qquickspriteengine.cpp9
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp2
-rw-r--r--src/quickwidgets/qquickwidget.cpp27
-rw-r--r--tests/auto/qmltest/BLACKLIST5
-rw-r--r--tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml (renamed from tests/auto/qmltest-blacklist/itemgrabber/tst_itemgrabber.qml)4
-rw-r--r--tests/auto/qmltest/textinput/tst_textinput.qml1
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/img100x100.pngbin0 -> 238 bytes
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/img50x50.pngbin0 -> 135 bytes
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/sourceSwitch.qml46
-rw-r--r--tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp39
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp17
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml41
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp55
20 files changed, 253 insertions, 21 deletions
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
index 078d8e7e03..ea6c7f2f9a 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
@@ -40,6 +40,7 @@
#include "mainwindow.h"
#include "fbitem.h"
+#include <QCoreApplication>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QRadioButton>
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index dc215ba8a5..c6a7cde240 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -54,6 +54,7 @@
#include <private/qqmlcompiler_p.h>
#include "qqmlinfo.h"
+#include <private/qjsvalue_p.h>
#include <private/qv4value_p.h>
#include <private/qv4qobjectwrapper_p.h>
@@ -224,7 +225,9 @@ void QQmlBoundSignalExpression::evaluate(void **a)
//### ideally we would use metaTypeToJS, however it currently gives different results
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
- if (type == QMetaType::QVariant) {
+ if (type == qMetaTypeId<QJSValue>()) {
+ callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
+ } else if (type == QMetaType::QVariant) {
callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 576478b729..7b129e2b57 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -490,8 +490,8 @@ QQmlType *QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
Q_ASSERT(isComposite());
if (!engine)
return 0;
- QQmlTypeData *td = engine->typeLoader.getType(sourceUrl());
- if (!td || !td->isComplete())
+ QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt);
+ if (td.isNull() || !td->isComplete())
return 0;
QQmlCompiledData *cd = td->compiledData();
const QMetaObject *mo = cd->rootPropertyCache->firstCppMetaObject();
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index 516630d034..caedd72dc5 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -180,7 +180,7 @@ dedicated thread. Qt attempts to choose a suitable loop based on the
platform and possibly the graphics drivers in use. When this is not
satisfactory, or for testing purposes, the environment variable
\c QSG_RENDER_LOOP can be used to force the usage of a given loop. To
-verify which render loop is in use, enable the \c qt.scenegraph.info
+verify which render loop is in use, enable the \c qt.scenegraph.general
\l {QLoggingCategory}{logging category}.
\note The \c threaded and \c windows render loops rely on the OpenGL
@@ -368,7 +368,7 @@ addition to being helpful to Qt contributors.
\li \c {qt.scenegraph.time.glyph} - logs the time spent preparing distance field glyphs
-\li \c {qt.scenegraph.info} - logs general information about various parts of the scene graph and the graphics stack
+\li \c {qt.scenegraph.general} - logs general information about various parts of the scene graph and the graphics stack
\li \c {qt.scenegraph.renderloop} - creates a detailed log of the various stages involved in rendering. This log mode is primarily useful for developers working on Qt.
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 0ff04ce71c..5676bdb13a 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -5762,6 +5762,8 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
if (windowPriv->mouseGrabberItem == q)
q->ungrabMouse();
+ if (!effectiveVisible)
+ q->ungrabTouchPoints();
}
bool childVisibilityChanged = false;
@@ -5810,6 +5812,8 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
if (windowPriv->mouseGrabberItem == q)
q->ungrabMouse();
+ if (!effectiveEnable)
+ q->ungrabTouchPoints();
if (scope && !effectiveEnable && activeFocus) {
windowPriv->clearFocusInScope(
scope, q, Qt::OtherFocusReason, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 074af7ebdc..4b9b7df98a 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -3147,7 +3147,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
}
- int prevVisibleCount = visibleItems.count();
+ bool visibleAffected = false;
if (insertResult->visiblePos.isValid() && pos < insertResult->visiblePos) {
// Insert items before the visible item.
int insertionIdx = index;
@@ -3170,6 +3170,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
if (!item)
return false;
+ visibleAffected = true;
visibleItems.insert(insertionIdx, item);
if (insertionIdx == 0)
insertResult->changedFirstItem = true;
@@ -3201,6 +3202,9 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
} else {
qreal to = buffer + displayMarginEnd + tempPos + size();
+
+ visibleAffected = count > 0 && pos < to;
+
for (int i = 0; i < count && pos <= to; ++i) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
@@ -3251,7 +3255,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
updateVisibleIndex();
- return visibleItems.count() > prevVisibleCount;
+ return visibleAffected;
}
void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult)
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 60d5e3f6dd..df044988e0 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -405,6 +405,15 @@ QImage QQuickSpriteEngine::assembledImage()
QImage img = state->m_pix.image();
+ {
+ const QSize frameSize(state->m_frameWidth, state->m_frameHeight);
+ if (!(img.size() - frameSize).isValid()) {
+ qmlInfo(state).nospace() << "SpriteEngine: Invalid frame size " << frameSize << "."
+ " It's bigger than image size " << img.size() << ".";
+ return QImage();
+ }
+ }
+
//Check that the frame sizes are the same within one sprite
if (!state->m_frameWidth)
state->m_frameWidth = img.width() / state->frames();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 1064be7178..9a768ab7dd 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -240,8 +240,6 @@ public:
uint clearBeforeRendering : 1;
- // Currently unused in the default implementation, as we're not stopping
- // rendering when obscured as we should...
uint persistentGLContext : 1;
uint persistentSceneGraph : 1;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 6572ceb2ce..25945ad78a 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
// Used for very high-level info about the renderering and gl context
// Includes GL_VERSION, type of render loop, atlas size, etc.
-Q_LOGGING_CATEGORY(QSG_LOG_INFO, "qt.scenegraph.info")
+Q_LOGGING_CATEGORY(QSG_LOG_INFO, "qt.scenegraph.general")
// Used to debug the renderloop logic. Primarily useful for platform integrators
// and when investigating the render loop logic.
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 49e7affa31..b0838e5dc4 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -782,9 +782,10 @@ void QQuickWidget::createFramebufferObject()
return;
}
- if (context->shareContext() != QWidgetPrivate::get(window())->shareContext()) {
- context->setShareContext(QWidgetPrivate::get(window())->shareContext());
- context->setScreen(context->shareContext()->screen());
+ QOpenGLContext *shareWindowContext = QWidgetPrivate::get(window())->shareContext();
+ if (shareWindowContext && context->shareContext() != shareWindowContext) {
+ context->setShareContext(shareWindowContext);
+ context->setScreen(shareWindowContext->screen());
if (!context->create())
qWarning("QQuickWidget: Failed to recreate context");
// The screen may be different so we must recreate the offscreen surface too.
@@ -1112,7 +1113,14 @@ void QQuickWidget::showEvent(QShowEvent *)
d->createContext();
if (d->offscreenWindow->openglContext()) {
d->render(true);
- if (d->updatePending) {
+ // render() may have led to a QQuickWindow::update() call (for
+ // example, having a scene with a QQuickFramebufferObject::Renderer
+ // calling update() in its render()) which in turn results in
+ // renderRequested in the rendercontrol, ending up in
+ // triggerUpdate. In this case just calling update() is not
+ // acceptable, we need the full renderSceneGraph issued from
+ // timerEvent().
+ if (!d->eventPending && d->updatePending) {
d->updatePending = false;
update();
}
@@ -1234,6 +1242,17 @@ bool QQuickWidget::event(QEvent *e)
break;
case QEvent::ScreenChangeInternal:
+ if (QWindow *window = this->window()->windowHandle()) {
+ QScreen *newScreen = window->screen();
+
+ if (d->offscreenWindow)
+ d->offscreenWindow->setScreen(newScreen);
+ if (d->offscreenSurface)
+ d->offscreenSurface->setScreen(newScreen);
+ if (d->context)
+ d->context->setScreen(newScreen);
+ }
+
if (d->fbo) {
// This will check the size taking the devicePixelRatio into account
// and recreate if needed.
diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST
index c472a51a1c..c38347b42a 100644
--- a/tests/auto/qmltest/BLACKLIST
+++ b/tests/auto/qmltest/BLACKLIST
@@ -9,8 +9,3 @@ linux
linux
[ListView::test_listInteractiveCurrentIndexEnforce]
linux
-[Text::test_linecount]
-osx
-windows
-[TextInput::test_doublevalidators]
-osx
diff --git a/tests/auto/qmltest-blacklist/itemgrabber/tst_itemgrabber.qml b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
index 743dad70eb..022e98a202 100644
--- a/tests/auto/qmltest-blacklist/itemgrabber/tst_itemgrabber.qml
+++ b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
@@ -102,7 +102,7 @@ Item {
property int callCount: 0;
property bool ready: false;
function handleGrab(result) {
- if (!result.saveToFile("image.png"))
+ if (!result.saveToFile("itemgrabber/image.png"))
print("Error: Failed to save image to disk...");
source = "image.png";
ready = true;
@@ -116,7 +116,7 @@ Item {
y: 0
property bool ready: false;
function handleGrab(result) {
- if (!result.saveToFile("image_small.png"))
+ if (!result.saveToFile("itemgrabber/image_small.png"))
print("Error: Failed to save image to disk...");
source = "image_small.png";
ready = true;
diff --git a/tests/auto/qmltest/textinput/tst_textinput.qml b/tests/auto/qmltest/textinput/tst_textinput.qml
index 62659a2188..51868ec8aa 100644
--- a/tests/auto/qmltest/textinput/tst_textinput.qml
+++ b/tests/auto/qmltest/textinput/tst_textinput.qml
@@ -277,6 +277,7 @@ Item {
}
function test_doublevalidators(row) {
+ txtdoublevalidator.validator.locale = "C"
compare(txtdoublevalidator.validator.top, 2.0)
compare(txtdoublevalidator.validator.bottom, 1.0)
txtdoublevalidator.text = row.testnumber;
diff --git a/tests/auto/quick/qquickanimatedsprite/data/img100x100.png b/tests/auto/quick/qquickanimatedsprite/data/img100x100.png
new file mode 100644
index 0000000000..9dd1990780
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/img100x100.png
Binary files differ
diff --git a/tests/auto/quick/qquickanimatedsprite/data/img50x50.png b/tests/auto/quick/qquickanimatedsprite/data/img50x50.png
new file mode 100644
index 0000000000..5cbb47981a
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/img50x50.png
Binary files differ
diff --git a/tests/auto/quick/qquickanimatedsprite/data/sourceSwitch.qml b/tests/auto/quick/qquickanimatedsprite/data/sourceSwitch.qml
new file mode 100644
index 0000000000..18a8f52661
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/sourceSwitch.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+AnimatedSprite {
+ id: animatedSprite
+ source: big ? "img100x100.png" : "img50x50.png"
+ frameWidth: 100
+ frameHeight: 100
+ property bool big: true
+ MouseArea {
+ anchors.fill: parent
+ onClicked: animatedSprite.big = !animatedSprite.big
+ }
+}
diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
index 27ce46d163..820c804065 100644
--- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
+++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
@@ -35,6 +35,7 @@
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
#include <QtGui/qoffscreensurface.h>
+#include <QtQml/qqmlproperty.h>
class tst_qquickanimatedsprite : public QQmlDataTest
{
@@ -50,6 +51,7 @@ private slots:
void test_largeAnimation_data();
void test_largeAnimation();
void test_reparenting();
+ void test_changeSourceToSmallerImgKeepingBigFrameSize();
};
void tst_qquickanimatedsprite::initTestCase()
@@ -286,6 +288,43 @@ void tst_qquickanimatedsprite::test_reparenting()
QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, false);
}
+class KillerThread : public QThread
+{
+ Q_OBJECT
+protected:
+ void run() Q_DECL_OVERRIDE {
+ sleep(3);
+ qFatal("Either the GUI or the render thread is stuck in an infinite loop.");
+ }
+};
+
+// Regression test for QTBUG-53937
+void tst_qquickanimatedsprite::test_changeSourceToSmallerImgKeepingBigFrameSize()
+{
+ QQuickView window;
+ window.setSource(testFileUrl("sourceSwitch.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QVERIFY(window.rootObject());
+ QQuickAnimatedSprite* sprite = qobject_cast<QQuickAnimatedSprite*>(window.rootObject());
+ QVERIFY(sprite);
+
+ QQmlProperty big(sprite, "big");
+ big.write(QVariant::fromValue(false));
+
+ KillerThread *killer = new KillerThread;
+ killer->start(); // will kill us in case the GUI or render thread enters an infinite loop
+
+ QTest::qWait(50); // let it draw with the new source.
+
+ // If we reach this point it's because we didn't hit QTBUG-53937
+
+ killer->terminate();
+ killer->wait();
+ delete killer;
+}
+
QTEST_MAIN(tst_qquickanimatedsprite)
#include "tst_qquickanimatedsprite.moc"
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index f5e79614df..b83edec996 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -629,6 +629,8 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
}
listview->setContentY(contentY);
+ QQuickItemViewPrivate::get(listview)->layout();
+
QList<QPair<QString, QString> > newData;
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
@@ -650,6 +652,16 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
QCOMPARE(item0->y(), itemsOffsetAfterMove);
#endif
+ QList<FxViewItem *> visibleItems = QQuickItemViewPrivate::get(listview)->visibleItems;
+ for (QList<FxViewItem *>::const_iterator itemIt = visibleItems.begin(); itemIt != visibleItems.end(); ++itemIt)
+ {
+ FxViewItem *item = *itemIt;
+ if (item->item->position().y() >= 0 && item->item->position().y() < listview->height())
+ {
+ QVERIFY(!QQuickItemPrivate::get(item->item)->culled);
+ }
+ }
+
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
for (int i=0; i<items.count(); i++) {
@@ -770,6 +782,11 @@ void tst_QQuickListView::inserted_more_data()
<< 80.0 // show 4-19
<< 20 << 3
<< 0.0;
+
+ QTest::newRow("add multiple, within visible, content at start")
+ << 0.0
+ << 2 << 50
+ << 0.0;
}
void tst_QQuickListView::insertBeforeVisible()
diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml b/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml
new file mode 100644
index 0000000000..e108003bca
--- /dev/null
+++ b/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml
@@ -0,0 +1,41 @@
+import QtQuick 2.0
+
+MultiPointTouchArea {
+ width: 240
+ height: 320
+
+ minimumTouchPoints: 1
+ maximumTouchPoints: 5
+ touchPoints: [
+ TouchPoint { objectName: "point1" },
+ TouchPoint { objectName: "point2" },
+ TouchPoint { objectName: "point3" },
+ TouchPoint { objectName: "point4" },
+ TouchPoint { objectName: "point5" }
+ ]
+
+ function clearCounts() {
+ touchPointPressCount = 0;
+ touchPointUpdateCount = 0;
+ touchPointReleaseCount = 0;
+ touchPointCancelCount = 0;
+ touchCount = 0;
+ touchUpdatedHandled = false;
+ }
+
+ property int touchPointPressCount: 0
+ property int touchPointUpdateCount: 0
+ property int touchPointReleaseCount: 0
+ property int touchPointCancelCount: 0
+ property int touchCount: 0
+ property bool touchUpdatedHandled: false
+
+ onPressed: { touchPointPressCount = touchPoints.length }
+ onUpdated: { touchPointUpdateCount = touchPoints.length }
+ onReleased: { touchPointReleaseCount = touchPoints.length }
+ onCanceled: { touchPointCancelCount = touchPoints.length }
+ onTouchUpdated: {
+ touchCount = touchPoints.length
+ touchUpdatedHandled = true
+ }
+}
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 8320d899f9..c3981c466f 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -69,6 +69,7 @@ private slots:
void transformedTouchArea();
void mouseInteraction();
void mouseInteraction_data();
+ void cancel();
private:
QQuickView *createAndShowView(const QString &file);
@@ -1195,6 +1196,60 @@ void tst_QQuickMultiPointTouchArea::mouseInteraction()
QCOMPARE(area->property("touchCount").toInt(), 0);
}
+void tst_QQuickMultiPointTouchArea::cancel()
+{
+ QScopedPointer<QQuickView> window(createAndShowView("cancel.qml"));
+ QVERIFY(window->rootObject() != 0);
+
+ QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
+ QQuickTouchPoint *point1 = area->findChild<QQuickTouchPoint*>("point1");
+
+ QPoint p1(20,100);
+ sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(point1->pressed(), true);
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointCancelCount").toInt(), 0);
+ QCOMPARE(area->property("touchCount").toInt(), 1);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ area->setVisible(false);
+ // we should get a onCancel signal
+ QCOMPARE(point1->pressed(), false);
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointCancelCount").toInt(), 1);
+ QCOMPARE(area->property("touchCount").toInt(), 0);
+ QMetaObject::invokeMethod(area, "clearCounts");
+ area->setVisible(true);
+
+
+ sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(point1->pressed(), true);
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointCancelCount").toInt(), 0);
+ QCOMPARE(area->property("touchCount").toInt(), 1);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ area->setEnabled(false);
+ // we should get a onCancel signal
+ QCOMPARE(point1->pressed(), false);
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointCancelCount").toInt(), 1);
+ QCOMPARE(area->property("touchCount").toInt(), 0);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+}
+
QTEST_MAIN(tst_QQuickMultiPointTouchArea)