diff options
author | Liang Qi <liang.qi@digia.com> | 2013-05-27 10:19:35 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-27 20:05:53 +0200 |
commit | 63f83fbd095415145ad124c7215f07a4c3c6038f (patch) | |
tree | 24637099b44ea15b090ce7e857583c4ed3a03831 /src | |
parent | e2e5ba2ce28cb3d666bd1037506c081fa9165611 (diff) |
Prevent tab focus from wrapping endlessly
If there was no item that accepted focus, it would go into an
endless loop.
This also changes the default behavior of QQuickWindow. When there is not
any activeFocusItem in the whole window, it means the contentItem got
focused. The Tab/BackTab key will now focus the next item in the tab focus
chain.
Autotest is included.
Done-with: Frederik Gladhorn <frederik.gladhorn@digia.com>
Task-number: QTBUG-31344
Change-Id: I854292f89a327c493eec21969907c94aa9cfddcb
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index d6a663ab77..58e1612e19 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2050,7 +2050,10 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item) { 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 @@ -2093,7 +2096,6 @@ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward) QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward) { Q_ASSERT(item); - Q_ASSERT(item->activeFocusOnTab()); bool all = QQuickItemPrivate::qt_tab_all_widgets(); @@ -2107,6 +2109,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo 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; @@ -2157,8 +2163,25 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo 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))); @@ -4375,7 +4398,8 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e) 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 |