summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-03-10 16:24:46 (GMT)
committerYoann Lopes <yoann.lopes@nokia.com>2011-03-10 16:35:18 (GMT)
commit1b3514e4b2d9a41f73bf5b87caf73ce409eadf2a (patch)
treeab226734b91c8286bf2963fdc8faca682b440ae6
parent1b326932d48c0e584f9d5173fa5f892c5086fee8 (diff)
downloadQt-1b3514e4b2d9a41f73bf5b87caf73ce409eadf2a.zip
Qt-1b3514e4b2d9a41f73bf5b87caf73ce409eadf2a.tar.gz
Qt-1b3514e4b2d9a41f73bf5b87caf73ce409eadf2a.tar.bz2
Fix QGraphicsScene returning incorrect focus item.
When the scene was losing and regaining focus, it was incorrectly setting the focus on any item that had its focus previously explicitly cleared. Autotest included. Task-number: QTBUG-16401 Reviewed-by: TrustMe
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp11
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h1
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp31
4 files changed, 43 insertions, 4 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 52e4d79..9c3198b 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -5577,8 +5577,10 @@ void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *s
parent->d_ptr->subFocusItemChange();
} while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
- if (scene && !scene->isActive())
+ if (scene && !scene->isActive()) {
+ scene->d_func()->passiveFocusItem = subFocusItem;
scene->d_func()->lastFocusItem = subFocusItem;
+ }
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 5e5077b..699d561 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -306,6 +306,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
rectAdjust(2),
focusItem(0),
lastFocusItem(0),
+ passiveFocusItem(0),
tabFocusFirst(0),
activePanel(0),
lastActivePanel(0),
@@ -630,6 +631,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
focusItem = 0;
if (item == lastFocusItem)
lastFocusItem = 0;
+ if (item == passiveFocusItem)
+ passiveFocusItem = 0;
if (item == activePanel) {
// ### deactivate...
activePanel = 0;
@@ -2985,7 +2988,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
QGraphicsItem *QGraphicsScene::focusItem() const
{
Q_D(const QGraphicsScene);
- return isActive() ? d->focusItem : d->lastFocusItem;
+ return isActive() ? d->focusItem : d->passiveFocusItem;
}
/*!
@@ -3059,6 +3062,7 @@ void QGraphicsScene::clearFocus()
Q_D(QGraphicsScene);
if (d->hasFocus) {
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, Qt::OtherFocusReason);
}
}
@@ -3761,9 +3765,9 @@ void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
focusEvent->ignore();
break;
default:
- if (d->lastFocusItem) {
+ if (d->passiveFocusItem) {
// Set focus on the last focus item
- setFocusItem(d->lastFocusItem, focusEvent->reason());
+ setFocusItem(d->passiveFocusItem, focusEvent->reason());
}
break;
}
@@ -3782,6 +3786,7 @@ void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
{
Q_D(QGraphicsScene);
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, focusEvent->reason());
// Remove all popups when the scene loses focus.
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 815c70b..2b47105 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -150,6 +150,7 @@ public:
quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
+ QGraphicsItem *passiveFocusItem;
QGraphicsWidget *tabFocusFirst;
QGraphicsItem *activePanel;
QGraphicsItem *lastActivePanel;
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
index b221cd9..5a5c9b7 100644
--- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -289,6 +289,7 @@ private slots:
void taskQTBUG_7863_paintIntoCacheWithTransparentParts();
void taskQT_3674_doNotCrash();
void taskQTBUG_15977_renderWithDeviceCoordinateCache();
+ void taskQTBUG_16401_focusItem();
};
void tst_QGraphicsScene::initTestCase()
@@ -4652,5 +4653,35 @@ void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache()
QCOMPARE(image, expected);
}
+void tst_QGraphicsScene::taskQTBUG_16401_focusItem()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
+ rect->setFlag(QGraphicsItem::ItemIsFocusable);
+
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QApplication::setActiveWindow(&view);
+
+ QVERIFY(!scene.focusItem());
+
+ rect->setFocus();
+ QCOMPARE(scene.focusItem(), rect);
+ QFocusEvent focusOut(QEvent::FocusOut);
+ QApplication::sendEvent(&view, &focusOut);
+ QVERIFY(!scene.focusItem());
+ QFocusEvent focusIn(QEvent::FocusIn);
+ QApplication::sendEvent(&view, &focusIn);
+ QCOMPARE(scene.focusItem(), rect);
+
+ rect->clearFocus();
+ QVERIFY(!scene.focusItem());
+ QApplication::sendEvent(&view, &focusOut);
+ QVERIFY(!scene.focusItem());
+ QApplication::sendEvent(&view, &focusIn);
+ QVERIFY(!scene.focusItem());
+}
+
QTEST_MAIN(tst_QGraphicsScene)
#include "tst_qgraphicsscene.moc"