aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickcanvas.cpp11
-rw-r--r--src/quick/items/qquickcanvas_p.h1
-rw-r--r--src/quick/items/qquickitem.cpp27
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp139
5 files changed, 168 insertions, 12 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index cf529c0d71..5aa244c4a8 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -379,11 +379,14 @@ void QQuickCanvasPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
QVarLengthArray<QQuickItem *, 20> changed;
// Does this change the active focus?
- if (item == rootItem || scopePrivate->activeFocus) {
+ if (item == rootItem || scopePrivate->activeFocus && item->isEnabled()) {
oldActiveFocusItem = activeFocusItem;
newActiveFocusItem = item;
- while (newActiveFocusItem->isFocusScope() && newActiveFocusItem->scopedFocusItem())
+ while (newActiveFocusItem->isFocusScope()
+ && newActiveFocusItem->scopedFocusItem()
+ && newActiveFocusItem->scopedFocusItem()->isEnabled()) {
newActiveFocusItem = newActiveFocusItem->scopedFocusItem();
+ }
if (oldActiveFocusItem) {
#ifndef QT_NO_IM
@@ -405,7 +408,7 @@ void QQuickCanvasPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
}
}
- if (item != rootItem) {
+ if (item != rootItem && !(options & DontChangeSubFocusItem)) {
QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
// Correct focus chain in scope
if (oldSubFocusItem) {
@@ -513,7 +516,7 @@ void QQuickCanvasPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
}
}
- if (item != rootItem) {
+ if (item != rootItem && !(options & DontChangeSubFocusItem)) {
QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
// Correct focus chain in scope
if (oldSubFocusItem) {
diff --git a/src/quick/items/qquickcanvas_p.h b/src/quick/items/qquickcanvas_p.h
index 5da75c709a..fe57fd1a47 100644
--- a/src/quick/items/qquickcanvas_p.h
+++ b/src/quick/items/qquickcanvas_p.h
@@ -135,6 +135,7 @@ public:
QList<QQuickItem*> hoverItems;
enum FocusOption {
DontChangeFocusProperty = 0x01,
+ DontChangeSubFocusItem = 0x02
};
Q_DECLARE_FLAGS(FocusOptions, FocusOption)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index c9d81c0d11..032427d438 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1913,7 +1913,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
QQuickItemPrivate::get(d->parentItem)->addChild(this);
d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
- d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+ d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
if (scopeFocusedItem && d->parentItem && d->canvas) {
// We need to test whether this item becomes scope focused
@@ -3901,7 +3901,11 @@ void QQuickItem::setEnabled(bool e)
d->explicitEnable = e;
- d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+ QQuickItem *scope = parentItem();
+ while (scope && !scope->isFocusScope())
+ scope = scope->parentItem();
+
+ d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
}
bool QQuickItemPrivate::calcEffectiveVisible() const
@@ -3959,12 +3963,10 @@ bool QQuickItemPrivate::calcEffectiveEnable() const
return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
}
-void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
+void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
{
Q_Q(QQuickItem);
- // XXX todo - need to fixup focus
-
if (newEffectiveEnable && !explicitEnable) {
// This item locally overrides enable
return;
@@ -3981,10 +3983,21 @@ void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
if (canvasPriv->mouseGrabberItem == q)
q->ungrabMouse();
+ if (scope && !effectiveEnable && activeFocus) {
+ canvasPriv->clearFocusInScope(
+ scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+ }
}
- for (int ii = 0; ii < childItems.count(); ++ii)
- QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
+ for (int ii = 0; ii < childItems.count(); ++ii) {
+ QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
+ flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
+ }
+
+ if (canvas && scope && effectiveEnable && focus) {
+ QQuickCanvasPrivate::get(canvas)->setFocusInScope(
+ scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+ }
emit q->enabledChanged();
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 1d2a97dbb9..08cdd5700f 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -476,7 +476,7 @@ public:
bool calcEffectiveVisible() const;
void setEffectiveVisibleRecur(bool);
bool calcEffectiveEnable() const;
- void setEffectiveEnableRecur(bool);
+ void setEffectiveEnableRecur(QQuickItem *scope, bool);
// XXX todo
enum DirtyType {
diff --git a/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp b/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp
index 3ff5054bd3..099f29d925 100644
--- a/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp
@@ -136,6 +136,7 @@ private slots:
void visible();
void enabled();
+ void enabledFocus();
void mouseGrab();
void touchEventAccept();
@@ -801,6 +802,144 @@ void tst_qquickitem::enabled()
delete child2;
}
+void tst_qquickitem::enabledFocus()
+{
+ QQuickCanvas canvas;
+ ensureFocus(&canvas);
+
+ QQuickFocusScope root;
+
+ root.setFocus(true);
+ root.setEnabled(false);
+
+ QCOMPARE(root.isEnabled(), false);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), false);
+
+ root.setParentItem(canvas.rootItem());
+
+ QCOMPARE(root.isEnabled(), false);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), canvas.rootItem());
+
+ root.setEnabled(true);
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), true);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&root));
+
+ QQuickItem child1;
+ child1.setParentItem(&root);
+
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), false);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&root));
+
+ QQuickItem child2;
+ child2.setFocus(true);
+ child2.setParentItem(&root);
+
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), true);
+ QCOMPARE(child2.isEnabled(), true);
+ QCOMPARE(child2.hasFocus(), true);
+ QCOMPARE(child2.hasActiveFocus(), true);
+ QCOMPARE(canvas.activeFocusItem(), &child2);
+
+ child2.setEnabled(false);
+
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), true);
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), false);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), true);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&root));
+
+ child1.setEnabled(false);
+ QCOMPARE(child1.isEnabled(), false);
+ QCOMPARE(child1.hasFocus(), false);
+ QCOMPARE(child1.hasActiveFocus(), false);
+
+ child1.setFocus(true);
+ QCOMPARE(child1.isEnabled(), false);
+ QCOMPARE(child1.hasFocus(), true);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), false);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&root));
+
+ child1.setEnabled(true);
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), true);
+ QCOMPARE(child1.hasActiveFocus(), true);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&child1));
+
+ root.setFocus(false);
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), false);
+ QCOMPARE(root.hasActiveFocus(), false);
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), true);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), canvas.rootItem());
+
+ child2.forceActiveFocus();
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), true);
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), false);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), true);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&root));
+
+ root.setEnabled(false);
+ QCOMPARE(root.isEnabled(), false);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), false);
+ QCOMPARE(child1.isEnabled(), false);
+ QCOMPARE(child1.hasFocus(), false);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), true);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), canvas.rootItem());
+
+ child1.forceActiveFocus();
+ QCOMPARE(root.isEnabled(), false);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), false);
+ QCOMPARE(child1.isEnabled(), false);
+ QCOMPARE(child1.hasFocus(), true);
+ QCOMPARE(child1.hasActiveFocus(), false);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), false);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), canvas.rootItem());
+
+ root.setEnabled(true);
+ QCOMPARE(root.isEnabled(), true);
+ QCOMPARE(root.hasFocus(), true);
+ QCOMPARE(root.hasActiveFocus(), true);
+ QCOMPARE(child1.isEnabled(), true);
+ QCOMPARE(child1.hasFocus(), true);
+ QCOMPARE(child1.hasActiveFocus(), true);
+ QCOMPARE(child2.isEnabled(), false);
+ QCOMPARE(child2.hasFocus(), false);
+ QCOMPARE(child2.hasActiveFocus(), false);
+ QCOMPARE(canvas.activeFocusItem(), static_cast<QQuickItem *>(&child1));
+}
+
void tst_qquickitem::mouseGrab()
{
QQuickCanvas *canvas = new QQuickCanvas;