aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@digia.com>2014-04-10 21:18:09 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-12 06:31:42 +0200
commit8da17239ed4a68270c74f6a5e5ca04d82d99b547 (patch)
tree9c9882364d9be9349f631a2c8fc027bc6c36d68c
parent7254e09442278f9e083a423c832c24b58e8fedec (diff)
Avoid event propagation with Keys.forwardTo
[ChangeLog][QtQuick][Important Behavior Changes] Keys.forwardTo no longer propagates key events to the target item's parents. This makes Keys.forwardTo act more as expected, like an event filter. This way Keys.forwardTo becomes usable for composite types that want to enable the Keys attached property handling by forwarding key events from an internal editor. Task-number: QTBUG-37924 Change-Id: I66d1b7245df39678767e79d4bdd46fc15e5c5c3f Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Alan Alpert <aalpert@blackberry.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
-rw-r--r--src/quick/items/qquickitem.cpp4
-rw-r--r--tests/auto/quick/qquickitem2/data/keysforward.qml84
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp73
3 files changed, 159 insertions, 2 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 691fea21e1..6afdc69291 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1333,7 +1333,7 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inPress = false;
return;
@@ -1375,7 +1375,7 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inRelease = false;
return;
diff --git a/tests/auto/quick/qquickitem2/data/keysforward.qml b/tests/auto/quick/qquickitem2/data/keysforward.qml
new file mode 100644
index 0000000000..f0cb4d9508
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/keysforward.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ property alias source: source
+ property alias primaryTarget: primaryTarget
+ property alias secondaryTarget: secondaryTarget
+
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+
+ Item {
+ id: primaryTarget
+ objectName: "primary"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.forwardTo: secondaryTarget
+ Keys.onPressed: { event.accepted = event.key === Qt.Key_P; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { event.accepted = event.key === Qt.Key_P; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+
+ Item {
+ id: source
+ objectName: "source"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.forwardTo: primaryTarget
+ Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+ }
+ }
+
+ Item {
+ id: secondaryTarget
+ objectName: "secondary"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.onPressed: { event.accepted = event.key === Qt.Key_S; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { event.accepted = event.key === Qt.Key_S; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index e6fd98ac35..6778d6a8b6 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -85,6 +85,7 @@ private slots:
void standardKeys();
void keysProcessingOrder();
void keysim();
+ void keysForward();
void keyNavigation_data();
void keyNavigation();
void keyNavigation_RightToLeft();
@@ -1386,6 +1387,78 @@ void tst_QQuickItem::keysim()
delete window;
}
+void tst_QQuickItem::keysForward()
+{
+ QQuickView window;
+ window.setBaseSize(QSize(240,320));
+
+ window.setSource(testFileUrl("keysforward.qml"));
+ window.show();
+ window.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QVERIFY(QGuiApplication::focusWindow() == &window);
+
+ QQuickItem *rootItem = qobject_cast<QQuickItem *>(window.rootObject());
+ QVERIFY(rootItem);
+ QQuickItem *sourceItem = rootItem->property("source").value<QQuickItem *>();
+ QVERIFY(sourceItem);
+ QQuickItem *primaryTarget = rootItem->property("primaryTarget").value<QQuickItem *>();
+ QVERIFY(primaryTarget);
+ QQuickItem *secondaryTarget = rootItem->property("secondaryTarget").value<QQuickItem *>();
+ QVERIFY(secondaryTarget);
+
+ // primary target accepts/consumes Key_P
+ QKeyEvent pressKeyP(QEvent::KeyPress, Qt::Key_P, Qt::NoModifier, "P");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyP);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QVERIFY(pressKeyP.isAccepted());
+
+ QKeyEvent releaseKeyP(QEvent::KeyRelease, Qt::Key_P, Qt::NoModifier, "P");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyP);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QVERIFY(releaseKeyP.isAccepted());
+
+ // secondary target accepts/consumes Key_S
+ QKeyEvent pressKeyS(QEvent::KeyPress, Qt::Key_S, Qt::NoModifier, "S");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyS);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S);
+ QVERIFY(pressKeyS.isAccepted());
+
+ QKeyEvent releaseKeyS(QEvent::KeyRelease, Qt::Key_S, Qt::NoModifier, "S");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyS);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S);
+ QVERIFY(releaseKeyS.isAccepted());
+
+ // neither target accepts/consumes Key_Q
+ QKeyEvent pressKeyQ(QEvent::KeyPress, Qt::Key_Q, Qt::NoModifier, "Q");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyQ);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList() << Qt::Key_Q);
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q);
+ QVERIFY(!pressKeyQ.isAccepted());
+
+ QKeyEvent releaseKeyQ(QEvent::KeyRelease, Qt::Key_Q, Qt::NoModifier, "Q");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyQ);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList() << Qt::Key_Q);
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q);
+ QVERIFY(!releaseKeyQ.isAccepted());
+}
+
QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString)
{
QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));