aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@digia.com>2013-05-27 10:19:35 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-27 20:05:53 +0200
commit63f83fbd095415145ad124c7215f07a4c3c6038f (patch)
tree24637099b44ea15b090ce7e857583c4ed3a03831 /src
parente2e5ba2ce28cb3d666bd1037506c081fa9165611 (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.cpp32
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