{
bool result = true;
- if (item->window() && item == item->window()->contentItem())
+ if (!item->window())
+ return false;
+
+ if (item == item->window()->contentItem())
return true;
#ifndef QT_NO_ACCESSIBILITY
QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
{
Q_ASSERT(item);
- Q_ASSERT(item->activeFocusOnTab());
bool all = QQuickItemPrivate::qt_tab_all_widgets();
from = item->parentItem();
}
bool skip = false;
+ const QQuickItem * const contentItem = item->window()->contentItem();
+ const QQuickItem * const originalItem = item;
+ QQuickItem * startItem = item;
+ QQuickItem * firstFromItem = from;
QQuickItem *current = item;
do {
skip = false;
skip = true;
}
}
-
from = last;
+ if (current == startItem && from == firstFromItem) {
+ // wrapped around, avoid endless loops
+ if (originalItem == contentItem) {
+#ifdef FOCUS_DEBUG
+ qDebug() << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+#endif
+ return item->window()->contentItem();
+ } else {
+#ifdef FOCUS_DEBUG
+ qDebug() << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return " << startItem;
+#endif
+ return startItem;
+ }
+ }
+ if (!firstFromItem) { //start from root
+ startItem = current;
+ firstFromItem = from;
+ }
} while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()
|| !(all || QQuickItemPrivate::canAcceptTabFocus(current)));
return;
//only care about KeyPress now
- if (q->activeFocusOnTab() && e->type() == QEvent::KeyPress) {
+ if ((q == q->window()->contentItem() || q->activeFocusOnTab())
+ && e->type() == QEvent::KeyPress) {
bool res = false;
if (!(e->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
if (e->key() == Qt::Key_Backtab
void activeFocusOnTab4();
void activeFocusOnTab5();
void activeFocusOnTab6();
+ void activeFocusOnTab7();
+ void activeFocusOnTab8();
void nextItemInFocusChain();
void nextItemInFocusChain2();
delete window;
}
+void tst_QQuickItem::activeFocusOnTab7()
+{
+ 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("activeFocusOnTab7.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button1");
+ QVERIFY(item);
+ item->forceActiveFocus();
+ QVERIFY(item->hasActiveFocus());
+
+ // Tab: button1->button1
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(!key.isAccepted());
+
+ QVERIFY(item->hasActiveFocus());
+
+ // BackTab: button1->button1
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(!key.isAccepted());
+
+ QVERIFY(item->hasActiveFocus());
+
+ delete window;
+}
+
+void tst_QQuickItem::activeFocusOnTab8()
+{
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(300,300));
+
+ window->setSource(testFileUrl("activeFocusOnTab8.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *content = window->contentItem();
+ QVERIFY(content);
+ QVERIFY(content->hasActiveFocus());
+
+ QQuickItem *button1 = findItem<QQuickItem>(window->rootObject(), "button1");
+ QVERIFY(button1);
+ QVERIFY(!button1->hasActiveFocus());
+
+ QQuickItem *button2 = findItem<QQuickItem>(window->rootObject(), "button2");
+ QVERIFY(button2);
+ QVERIFY(!button2->hasActiveFocus());
+
+ // Tab: contentItem->button1
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button1->hasActiveFocus());
+
+ // Tab: button1->button2
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button2->hasActiveFocus());
+ QVERIFY(!button1->hasActiveFocus());
+
+ // BackTab: button2->button1
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button1->hasActiveFocus());
+ QVERIFY(!button2->hasActiveFocus());
+
+ delete window;
+}
+
void tst_QQuickItem::nextItemInFocusChain()
{
if (!qt_tab_all_widgets())