aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp4
-rw-r--r--src/quick/items/qquickflickable.cpp14
-rw-r--r--src/quick/items/qquickflickable_p.h2
-rw-r--r--src/quick/items/qquickflickable_p_p.h4
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml70
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml74
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml79
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml57
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml73
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml79
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp138
-rw-r--r--tests/manual/pointer/pointHandlerOnFlickable.qml74
-rw-r--r--tests/manual/pointer/rubberbandOnTable.qml86
14 files changed, 751 insertions, 5 deletions
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index f24b2bfd7e..c1658ec5d2 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -315,6 +315,8 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi
if (cancel) {
emit canceled(point);
setExclusiveGrab(point, false);
+ // In case there is a filtering parent (Flickable), we should not give up the passive grab,
+ // so that it can continue to filter future events.
reset();
emit pointChanged();
}
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 85045be411..cf882e8c9e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -61,6 +61,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent)
+
// FlickThreshold determines how far the "mouse" must have moved
// before we perform a flick.
static const int FlickThreshold = 15;
@@ -1897,6 +1899,8 @@ void QQuickFlickablePrivate::data_append(QQmlListProperty<QObject> *prop, QObjec
{
if (QQuickItem *i = qmlobject_cast<QQuickItem *>(o)) {
i->setParentItem(static_cast<QQuickFlickablePrivate*>(prop->data)->contentItem);
+ } else if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) {
+ static_cast<QQuickFlickablePrivate*>(prop->data)->addPointerHandler(pointerHandler);
} else {
o->setParent(prop->object); // XXX todo - do we want this?
}
@@ -2356,6 +2360,14 @@ void QQuickFlickablePrivate::cancelInteraction()
}
}
+void QQuickFlickablePrivate::addPointerHandler(QQuickPointerHandler *h)
+{
+ Q_Q(const QQuickFlickable);
+ qCDebug(lcHandlerParent) << "reparenting handler" << h << "to contentItem of" << q;
+ h->setParent(contentItem);
+ QQuickItemPrivate::get(contentItem)->addPointerHandler(h);
+}
+
/*!
QQuickFlickable::filterMouseEvent checks filtered mouse events and potentially steals them.
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index b7c4fa5b67..f21fe94177 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index c538cf7878..835c54170f 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -206,6 +206,8 @@ public:
void cancelInteraction();
+ void addPointerHandler(QQuickPointerHandler *h) override;
+
public:
QQuickItem *contentItem;
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 4ca3a01d02..771228914b 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -281,7 +281,7 @@ public:
bool hasPointerHandlers() const;
bool hasHoverHandlers() const;
- void addPointerHandler(QQuickPointerHandler *h);
+ virtual void addPointerHandler(QQuickPointerHandler *h);
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml
new file mode 100644
index 0000000000..fd32baad10
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Flickable {
+ id: root
+ objectName: "root"
+ width: 800
+ height: 480
+ contentWidth: 1000
+ contentHeight: 600
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.color: "black"
+ }
+
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: buttonDrag.active ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ DragHandler {
+ id: buttonDrag
+ objectName: "buttonDrag"
+ }
+ }
+
+ DragHandler {
+ id: contentItemDrag
+ objectName: "contentItemDrag"
+ }
+ Text {
+ x: 100; y: 100
+ text: "dragging contentItem"
+ visible: contentItemDrag.active
+ }
+
+ Component.onCompleted: contentItem.objectName = "Flickable's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
new file mode 100644
index 0000000000..bb39c2267c
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+ListView {
+ id: root
+ objectName: "root"
+ property Item buttonUnderTest: null
+ property Item delegateUnderTest: null
+ width: 800
+ height: 480
+ model: 10
+ spacing: 2
+
+ delegate: Rectangle {
+ objectName: "itemview delegate"
+ color: delegateDrag.active ? "wheat" : "beige"
+ border.color: "black"
+ width: parent.width; height: 140
+ Rectangle {
+ objectName: "button"
+ x: 350; y: 20
+ border.color: "tomato"
+ border.width: 10
+ color: buttonDrag.active ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ DragHandler {
+ id: buttonDrag
+ objectName: "buttonDrag"
+ }
+ Component.onCompleted: if (!root.buttonUnderTest) {
+ root.buttonUnderTest = this
+ root.delegateUnderTest = parent
+ }
+ }
+ DragHandler {
+ id: delegateDrag
+ objectName: "delegateDrag"
+ }
+ }
+
+ DragHandler {
+ objectName: "contentItemDrag"
+ }
+
+ Component.onCompleted: contentItem.objectName = "ListView's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
new file mode 100644
index 0000000000..43cc44f62e
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+TableView {
+ id: root
+ objectName: "root"
+ property Item buttonUnderTest: null
+ property Item delegateUnderTest: null
+ width: 800
+ height: 480
+ columnSpacing: 2
+ rowSpacing: 2
+ // TODO use TableModel when it's ready, to test with multiple columns
+ model: 10
+
+ delegate: Rectangle {
+ id: tableDelegate
+ objectName: "itemview delegate"
+ color: delegateDrag.active ? "wheat" : "beige"
+ implicitWidth: 200
+ implicitHeight: 140
+
+ Rectangle {
+ objectName: "button"
+ x: 50; y: 20
+ border.color: "tomato"
+ border.width: 10
+ color: buttonDrag.active ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ DragHandler {
+ id: buttonDrag
+ objectName: "buttonDrag"
+ }
+ Component.onCompleted: if (!root.buttonUnderTest) {
+ root.buttonUnderTest = this
+ root.delegateUnderTest = parent
+ }
+ }
+
+ DragHandler {
+ id: delegateDrag
+ objectName: "delegateDrag"
+ }
+ }
+
+ DragHandler {
+ objectName: "contentItemDrag"
+ }
+
+ Component.onCompleted: contentItem.objectName = "TableView's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml
new file mode 100644
index 0000000000..a71db0b4c2
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Flickable {
+ id: root
+ objectName: "root"
+ width: 800
+ height: 480
+ contentWidth: 1000
+ contentHeight: 600
+
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: innerTap.pressed ? "wheat" : "transparent"
+ width: 100
+ height: 100
+ TapHandler {
+ id: innerTap
+ objectName: "buttonTap"
+ }
+ }
+
+ TapHandler {
+ objectName: "contentItemTap"
+ }
+ Component.onCompleted: contentItem.objectName = "Flickable's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
new file mode 100644
index 0000000000..ef27955043
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+ListView {
+ id: root
+ objectName: "root"
+ property Item buttonUnderTest: null
+ property Item delegateUnderTest: null
+ width: 800
+ height: 480
+ model: 10
+ spacing: 2
+
+ delegate: Rectangle {
+ objectName: "itemview delegate"
+ color: delegateTap.pressed ? "wheat" : "beige"
+ width: parent.width; height: 140
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: innerTap.pressed ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ TapHandler {
+ id: innerTap
+ objectName: "buttonTap"
+ }
+ Component.onCompleted: if (!root.buttonUnderTest) {
+ root.buttonUnderTest = this
+ root.delegateUnderTest = parent
+ }
+ }
+ TapHandler {
+ id: delegateTap
+ objectName: "delegateTap"
+ }
+ }
+
+ TapHandler {
+ objectName: "contentItemTap"
+ }
+
+ Component.onCompleted: contentItem.objectName = "ListView's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
new file mode 100644
index 0000000000..6bf1054d7a
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+TableView {
+ id: root
+ objectName: "root"
+ property Item buttonUnderTest: null
+ property Item delegateUnderTest: null
+ width: 800
+ height: 480
+ columnSpacing: 2
+ rowSpacing: 2
+ // TODO use TableModel when it's ready, to test with multiple columns
+ model: 10
+
+ delegate: Rectangle {
+ id: tableDelegate
+ objectName: "itemview delegate"
+ color: delegateTap.pressed ? "wheat" : "beige"
+ implicitWidth: 200
+ implicitHeight: 140
+
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: innerTap.pressed ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ TapHandler {
+ id: innerTap
+ objectName: "buttonTap"
+ }
+ Component.onCompleted: if (!root.buttonUnderTest) {
+ root.buttonUnderTest = this
+ root.delegateUnderTest = parent
+ }
+ }
+
+ TapHandler {
+ id: delegateTap
+ objectName: "delegateTap"
+ }
+ }
+
+ TapHandler {
+ objectName: "contentItemTap"
+ }
+
+ Component.onCompleted: contentItem.objectName = "TableView's contentItem"
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index e544eedf05..e73588bdef 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -33,9 +33,11 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/private/qquickitemview_p.h>
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickdraghandler_p.h>
#include <QtQuick/private/qquicktaphandler_p.h>
+#include <QtQuick/private/qquicktableview_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <private/qquickwindow_p.h>
@@ -75,6 +77,8 @@ private slots:
void mouseDragFlickableBehindItemWithHandlers_data();
void mouseDragFlickableBehindItemWithHandlers();
void touchDragSliderAndFlickable();
+ void touchAndDragHandlerOnFlickable_data();
+ void touchAndDragHandlerOnFlickable();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
@@ -651,6 +655,140 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
touchSeq.release(1, p1, window).release(2, p2, window).commit();
}
+void tst_FlickableInterop::touchAndDragHandlerOnFlickable_data()
+{
+ QTest::addColumn<QByteArray>("qmlFile");
+ QTest::addColumn<bool>("pressDelay");
+ QTest::addColumn<bool>("targetNull");
+ QTest::newRow("tapOnFlickable") << QByteArray("tapOnFlickable.qml") << false << false;
+ QTest::newRow("tapOnList") << QByteArray("tapOnList.qml") << false << false;
+ QTest::newRow("tapOnTable") << QByteArray("tapOnTable.qml") << false << false;
+ QTest::newRow("dragOnFlickable") << QByteArray("dragOnFlickable.qml") << false << false;
+ QTest::newRow("dragOnList") << QByteArray("dragOnList.qml") << false << false;
+ QTest::newRow("dragOnTable") << QByteArray("dragOnTable.qml") << false << false;
+ QTest::newRow("tapDelayOnFlickable") << QByteArray("tapOnFlickable.qml") << true << false;
+ QTest::newRow("tapDelayOnList") << QByteArray("tapOnList.qml") << true << false;
+ QTest::newRow("tapDelayOnTable") << QByteArray("tapOnTable.qml") << true << false;
+ QTest::newRow("dragDelayOnFlickable") << QByteArray("dragOnFlickable.qml") << true << false;
+ QTest::newRow("dragDelayOnList") << QByteArray("dragOnList.qml") << true << false;
+ QTest::newRow("dragDelayOnTable") << QByteArray("dragOnTable.qml") << true << false;
+ QTest::newRow("tapOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << false << true;
+ QTest::newRow("tapOnListWithNullTargets") << QByteArray("tapOnList.qml") << false << true;
+ QTest::newRow("tapOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << false << true;
+ QTest::newRow("dragOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << false << true;
+ QTest::newRow("dragOnListWithNullTargets") << QByteArray("dragOnList.qml") << false << true;
+ QTest::newRow("dragOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << false << true;
+ QTest::newRow("tapDelayOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << true << true;
+ QTest::newRow("tapDelayOnListWithNullTargets") << QByteArray("tapOnList.qml") << true << true;
+ QTest::newRow("tapDelayOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << true << true;
+ QTest::newRow("dragDelayOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << true << true;
+ QTest::newRow("dragDelayOnListWithNullTargets") << QByteArray("dragOnList.qml") << true << true;
+ QTest::newRow("dragDelayOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << true << true;
+}
+
+void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
+{
+ QFETCH(QByteArray, qmlFile);
+ QFETCH(bool, pressDelay);
+ QFETCH(bool, targetNull);
+
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, qmlFile.constData());
+ QQuickView * window = windowPtr.data();
+ QQuickFlickable *flickable = qmlobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+ flickable->setPressDelay(pressDelay ? 5000 : 0);
+ QQuickItem *delegate = nullptr;
+ if (QQuickItemView *itemView = qmlobject_cast<QQuickItemView *>(flickable))
+ delegate = itemView->currentItem();
+ if (!delegate)
+ delegate = flickable->property("delegateUnderTest").value<QQuickItem*>();
+ QQuickItem *button = delegate ? delegate->findChild<QQuickItem*>("button")
+ : flickable->findChild<QQuickItem*>("button");
+ if (!button)
+ button = flickable->property("buttonUnderTest").value<QQuickItem*>();
+ QVERIFY(button);
+ QQuickPointerHandler *buttonHandler = button->findChild<QQuickPointerHandler*>();
+ QVERIFY(buttonHandler);
+ QQuickTapHandler *buttonTapHandler = qmlobject_cast<QQuickTapHandler *>(buttonHandler);
+ QQuickDragHandler *buttonDragHandler = qmlobject_cast<QQuickDragHandler *>(buttonHandler);
+ QQuickPointerHandler *delegateHandler = delegate ? delegate->findChild<QQuickPointerHandler*>() : nullptr;
+ QQuickPointerHandler *contentItemHandler = flickable->findChild<QQuickPointerHandler*>();
+ QVERIFY(contentItemHandler);
+ // a handler declared directly in a Flickable (or item view) must actually be a child of the contentItem,
+ // just as Items declared inside are (QTBUG-71918 and QTBUG-73035)
+ QCOMPARE(contentItemHandler->parentItem(), flickable->contentItem());
+ if (targetNull) {
+ buttonHandler->setTarget(nullptr);
+ if (delegateHandler)
+ delegateHandler->setTarget(nullptr);
+ contentItemHandler->setTarget(nullptr);
+ }
+
+ // Drag one finger on the Flickable and make sure it flicks
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
+ QPoint p1(780, 460);
+ touchSeq.press(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ for (int i = 0; i < 4; ++i) {
+ p1 -= QPoint(dragThreshold, dragThreshold);
+ touchSeq.move(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ }
+ if (!(buttonDragHandler && !pressDelay))
+ QVERIFY(flickable->contentY() >= dragThreshold);
+ if (buttonTapHandler)
+ QCOMPARE(buttonTapHandler->isPressed(), false);
+ touchSeq.release(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+
+ // Drag one finger on the delegate and make sure Flickable flicks
+ if (delegate) {
+ flickable->setContentY(0);
+ QTRY_COMPARE(flickable->isMoving(), false);
+ QVERIFY(delegateHandler);
+ QQuickTapHandler *delegateTapHandler = qmlobject_cast<QQuickTapHandler *>(delegateHandler);
+ p1 = button->mapToScene(button->clipRect().bottomRight()).toPoint() + QPoint(10, 0);
+ touchSeq.press(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ if (delegateTapHandler && !pressDelay)
+ QCOMPARE(delegateTapHandler->isPressed(), true);
+ for (int i = 0; i < 4; ++i) {
+ p1 -= QPoint(dragThreshold, dragThreshold);
+ touchSeq.move(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ if (i > 1)
+ QTRY_VERIFY(delegateHandler->active() || flickable->isMoving());
+ }
+ if (!(buttonDragHandler && !pressDelay))
+ QVERIFY(flickable->contentY() > 0);
+ if (delegateTapHandler)
+ QCOMPARE(delegateTapHandler->isPressed(), false);
+ touchSeq.release(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ }
+
+ // Drag one finger on the button and make sure Flickable flicks
+ flickable->setContentY(0);
+ QTRY_COMPARE(flickable->isMoving(), false);
+ p1 = button->mapToScene(button->clipRect().center()).toPoint();
+ touchSeq.press(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ if (buttonTapHandler && !pressDelay)
+ QTRY_COMPARE(buttonTapHandler->isPressed(), true);
+ for (int i = 0; i < 4; ++i) {
+ p1 -= QPoint(dragThreshold, dragThreshold);
+ touchSeq.move(1, p1, window).commit();
+ QQuickTouchUtils::flush(window);
+ }
+ if (!(buttonDragHandler && !pressDelay))
+ QVERIFY(flickable->contentY() > 0);
+ if (buttonTapHandler)
+ QCOMPARE(buttonTapHandler->isPressed(), false);
+ touchSeq.release(1, p1, window).commit();
+}
+
QTEST_MAIN(tst_FlickableInterop)
#include "tst_flickableinterop.moc"
diff --git a/tests/manual/pointer/pointHandlerOnFlickable.qml b/tests/manual/pointer/pointHandlerOnFlickable.qml
new file mode 100644
index 0000000000..bd39d545ca
--- /dev/null
+++ b/tests/manual/pointer/pointHandlerOnFlickable.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import "content"
+
+Flickable {
+ id: root
+ objectName: "root"
+ width: 800
+ height: 480
+ contentWidth: 1000
+ contentHeight: 600
+
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: innerTap.pressed ? "wheat" : "transparent"
+ width: 100
+ height: 100
+ TapHandler {
+ id: innerTap
+ objectName: "buttonTap"
+ }
+ }
+
+ TapHandler {
+ id: contentItemTap
+ objectName: "contentItemTap"
+ onLongPressed: longPressFeedback.createObject(root.contentItem,
+ {"x": point.position.x, "y": point.position.y,
+ "text": contentItemTap.timeHeld.toFixed(3) + " sec"})
+
+ }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+
+ Component {
+ id: longPressFeedback
+ Text { }
+ }
+
+ Component.onCompleted: contentItem.objectName = "Flickable's contentItem"
+}
diff --git a/tests/manual/pointer/rubberbandOnTable.qml b/tests/manual/pointer/rubberbandOnTable.qml
new file mode 100644
index 0000000000..177568d41e
--- /dev/null
+++ b/tests/manual/pointer/rubberbandOnTable.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+TableView {
+ id: root
+ objectName: "root"
+ width: 480
+ height: 480
+ columnSpacing: 2
+ rowSpacing: 2
+ // TODO use TableModel when it's ready, to test with multiple columns
+ model: 10
+
+ delegate: Rectangle {
+ id: tableDelegate
+ objectName: "itemview delegate"
+ color: delegateTap.pressed ? "wheat" : "beige"
+ implicitWidth: 200
+ implicitHeight: 140
+
+ Rectangle {
+ objectName: "button"
+ anchors.centerIn: parent
+ border.color: "tomato"
+ border.width: 10
+ color: buttonTap.pressed ? "goldenrod" : "beige"
+ width: 100
+ height: 100
+ TapHandler {
+ id: buttonTap
+ objectName: "buttonTap"
+ }
+ }
+
+ TapHandler {
+ id: delegateTap
+ objectName: "delegateTap"
+ }
+ }
+
+ DragHandler {
+ id: rubberBandDrag
+ objectName: "rubberBandDrag"
+ target: null
+ acceptedDevices: PointerDevice.Mouse
+ }
+ Rectangle {
+ visible: rubberBandDrag.active
+ x: Math.min(rubberBandDrag.centroid.position.x, rubberBandDrag.centroid.pressPosition.x)
+ y: Math.min(rubberBandDrag.centroid.position.y, rubberBandDrag.centroid.pressPosition.y)
+ width: Math.abs(rubberBandDrag.centroid.position.x - rubberBandDrag.centroid.pressPosition.x)
+ height: Math.abs(rubberBandDrag.centroid.position.y - rubberBandDrag.centroid.pressPosition.y)
+ color: "transparent"
+ border.color: "black"
+ z: 1000
+ }
+
+ Component.onCompleted: contentItem.objectName = "TableView's contentItem"
+}