From c1d2bcff3dededa5b560713f4fd4874a023c43a2 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 1 Apr 2014 10:05:28 +0200 Subject: On Mac only editable text input should receive tab focus It's for all items with "readOnly: false" and has "text" property. [ChangeLog][QtQuick] Mac: any editable text input will get tab focus when "Text boxes and lists only" option was selected. About "Text boxes and lists only", see commit 06332df7438c8d2215b02f1e01ce2ed28a49a320. Task-number: QTBUG-38004 Change-Id: I73947b71b2fec69a66e122514d440656f4650e99 Reviewed-by: Frederik Gladhorn Reviewed-by: Andy Shaw --- tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 136 ++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'tests/auto/quick/qquickitem2/tst_qquickitem.cpp') diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 3ce18488df..e6fd98ac35 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -73,6 +73,8 @@ private slots: void activeFocusOnTab6(); void activeFocusOnTab7(); void activeFocusOnTab8(); + void activeFocusOnTab9(); + void activeFocusOnTab10(); void nextItemInFocusChain(); void nextItemInFocusChain2(); @@ -838,6 +840,140 @@ void tst_QQuickItem::activeFocusOnTab8() delete window; } +void tst_QQuickItem::activeFocusOnTab9() +{ + if (qt_tab_all_widgets()) + QSKIP("This function doesn't support iterating all."); + + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(300,300)); + + window->setSource(testFileUrl("activeFocusOnTab9.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QVERIFY(content->hasActiveFocus()); + + QQuickItem *textinput1 = findItem(window->rootObject(), "textinput1"); + QVERIFY(textinput1); + QQuickItem *textedit1 = findItem(window->rootObject(), "textedit1"); + QVERIFY(textedit1); + + QVERIFY(!textinput1->hasActiveFocus()); + textinput1->forceActiveFocus(); + QVERIFY(textinput1->hasActiveFocus()); + + // Tab: textinput1->textedit1 + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput1->hasActiveFocus()); + + // BackTab: textinput1->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + delete window; +} + +void tst_QQuickItem::activeFocusOnTab10() +{ + if (!qt_tab_all_widgets()) + QSKIP("This function doesn't support NOT iterating all."); + + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(300,300)); + + window->setSource(testFileUrl("activeFocusOnTab9.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QVERIFY(content->hasActiveFocus()); + + QQuickItem *textinput1 = findItem(window->rootObject(), "textinput1"); + QVERIFY(textinput1); + QQuickItem *textedit1 = findItem(window->rootObject(), "textedit1"); + QVERIFY(textedit1); + QQuickItem *textinput2 = findItem(window->rootObject(), "textinput2"); + QVERIFY(textinput2); + QQuickItem *textedit2 = findItem(window->rootObject(), "textedit2"); + QVERIFY(textedit2); + + QVERIFY(!textinput1->hasActiveFocus()); + textinput1->forceActiveFocus(); + QVERIFY(textinput1->hasActiveFocus()); + + // Tab: textinput1->textinput2 + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + // Tab: textinput2->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + // BackTab: textinput2->textinput1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput1->hasActiveFocus()); + + // BackTab: textinput1->textedit2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit2->hasActiveFocus()); + + // BackTab: textedit2->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + delete window; +} + void tst_QQuickItem::nextItemInFocusChain() { if (!qt_tab_all_widgets()) -- cgit v1.2.3 From 8da17239ed4a68270c74f6a5e5ca04d82d99b547 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 10 Apr 2014 21:18:09 +0200 Subject: 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 Reviewed-by: Alan Alpert Reviewed-by: Gunnar Sletta Reviewed-by: Frederik Gladhorn --- tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 73 +++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'tests/auto/quick/qquickitem2/tst_qquickitem.cpp') 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(window.rootObject()); + QVERIFY(rootItem); + QQuickItem *sourceItem = rootItem->property("source").value(); + QVERIFY(sourceItem); + QQuickItem *primaryTarget = rootItem->property("primaryTarget").value(); + QVERIFY(primaryTarget); + QQuickItem *secondaryTarget = rootItem->property("secondaryTarget").value(); + 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(rootItem, QString(QLatin1String(itemString))); -- cgit v1.2.3