Ensure subfocus is not reset to 0 when hiding a panel.
When hiding any widget that is not a panel, it is correct to clear subfocus. In case clearFocus() has been called, the result is that focusItem() / focusWidget() points to 0, which is correct. Upon reactivation, nothing gains input focus. When changing focus, the following setSubFocus() call will ensure subfocus points to the new widget. When hiding a panel, however, it's essential that subfocus within that panel is not cleared, otherwise, when re-showing the panel, nothing will have focus, whereas the expected behavior is that focus is restored to the last item that had focus, i.e., the focusItem() a.k.a. subfocus widget. Task-number: QTBUG-22256 Change-Id: I84d849a505764e074e1369fef923cef1ad5c0b1e Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
85cf6cd5f2
commit
bfb569b6e7
@ -2216,7 +2216,8 @@ bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
|
||||
Sets this item's visibility to \a newVisible. If \a explicitly is true,
|
||||
this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
|
||||
*/
|
||||
void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
|
||||
void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly,
|
||||
bool update, bool hiddenByPanel)
|
||||
{
|
||||
Q_Q(QGraphicsItem);
|
||||
|
||||
@ -2277,7 +2278,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
|
||||
} while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
|
||||
}
|
||||
if (clear)
|
||||
clearFocusHelper(/* giveFocusToParent = */ false);
|
||||
clearFocusHelper(/* giveFocusToParent = */ false, hiddenByPanel);
|
||||
}
|
||||
if (q_ptr->isSelected())
|
||||
q_ptr->setSelected(false);
|
||||
@ -2301,7 +2302,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
|
||||
&& !(flags & QGraphicsItem::ItemHasNoContents));
|
||||
foreach (QGraphicsItem *child, children) {
|
||||
if (!newVisible || !child->d_ptr->explicitlyHidden)
|
||||
child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
|
||||
child->d_ptr->setVisibleHelper(newVisible, false, updateChildren, hiddenByPanel);
|
||||
}
|
||||
|
||||
// Update activation
|
||||
@ -2399,7 +2400,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
|
||||
*/
|
||||
void QGraphicsItem::setVisible(bool visible)
|
||||
{
|
||||
d_ptr->setVisibleHelper(visible, /* explicit = */ true);
|
||||
d_ptr->setVisibleHelper(visible,
|
||||
/* explicit = */ true,
|
||||
/* update = */ true,
|
||||
/* hiddenByPanel = */ isPanel());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3159,10 +3163,16 @@ void QGraphicsItem::setActive(bool active)
|
||||
// Activate this item.
|
||||
d_ptr->scene->setActivePanel(this);
|
||||
} else {
|
||||
// Deactivate this item, and reactivate the last active item
|
||||
// (if any).
|
||||
QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
|
||||
d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
|
||||
// Deactivate this item, and reactivate the parent panel,
|
||||
// or the last active panel (if any).
|
||||
QGraphicsItem *nextToActivate = 0;
|
||||
if (d_ptr->parent)
|
||||
nextToActivate = d_ptr->parent->panel();
|
||||
if (!nextToActivate)
|
||||
nextToActivate = d_ptr->scene->d_func()->lastActivePanel;
|
||||
if (nextToActivate == this || isAncestorOf(nextToActivate))
|
||||
nextToActivate = 0;
|
||||
d_ptr->scene->setActivePanel(nextToActivate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3256,7 +3266,7 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
|
||||
|
||||
// Update the child focus chain.
|
||||
QGraphicsItem *commonAncestor = 0;
|
||||
if (scene && scene->focusItem()) {
|
||||
if (scene && scene->focusItem() && scene->focusItem()->panel() == q_ptr->panel()) {
|
||||
commonAncestor = scene->focusItem()->commonAncestorItem(f);
|
||||
scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
|
||||
}
|
||||
@ -3286,13 +3296,14 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
|
||||
*/
|
||||
void QGraphicsItem::clearFocus()
|
||||
{
|
||||
d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
|
||||
d_ptr->clearFocusHelper(/* giveFocusToParent = */ true,
|
||||
/* hiddenByParentPanel = */ false);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
|
||||
void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenByParentPanel)
|
||||
{
|
||||
if (giveFocusToParent) {
|
||||
// Pass focus to the closest parent focus scope
|
||||
@ -3317,7 +3328,8 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
|
||||
|
||||
if (q_ptr->hasFocus()) {
|
||||
// Invisible items with focus must explicitly clear subfocus.
|
||||
clearSubFocus(q_ptr);
|
||||
if (!hiddenByParentPanel)
|
||||
clearSubFocus(q_ptr);
|
||||
|
||||
// If this item has the scene's input focus, clear it.
|
||||
scene->setFocusItem(0);
|
||||
|
@ -279,7 +279,8 @@ public:
|
||||
void setTransformHelper(const QTransform &transform);
|
||||
void prependGraphicsTransform(QGraphicsTransform *t);
|
||||
void appendGraphicsTransform(QGraphicsTransform *t);
|
||||
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
|
||||
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true,
|
||||
bool hiddenByPanel = false);
|
||||
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
|
||||
bool discardUpdateRequest(bool ignoreVisibleBit = false,
|
||||
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
|
||||
@ -476,7 +477,7 @@ public:
|
||||
inline void markParentDirty(bool updateBoundingRect = false);
|
||||
|
||||
void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide);
|
||||
void clearFocusHelper(bool giveFocusToParent);
|
||||
void clearFocusHelper(bool giveFocusToParent, bool hiddenByParentPanel);
|
||||
void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
|
||||
void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
|
||||
void resetFocusProxy();
|
||||
|
@ -424,7 +424,7 @@ private slots:
|
||||
void setGraphicsEffect();
|
||||
void panel();
|
||||
void addPanelToActiveScene();
|
||||
void panelWithFocusItem();
|
||||
void panelWithFocusItems();
|
||||
void activate();
|
||||
void setActivePanelOnInactiveScene();
|
||||
void activationOnShowHide();
|
||||
@ -8721,52 +8721,97 @@ void tst_QGraphicsItem::panel()
|
||||
QVERIFY(!panel1->isActive());
|
||||
}
|
||||
|
||||
void tst_QGraphicsItem::panelWithFocusItem()
|
||||
void tst_QGraphicsItem::panelWithFocusItems()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QEvent activate(QEvent::WindowActivate);
|
||||
QApplication::sendEvent(&scene, &activate);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QEvent activate(QEvent::WindowActivate);
|
||||
QApplication::sendEvent(&scene, &activate);
|
||||
|
||||
QGraphicsRectItem *parentPanel = new QGraphicsRectItem;
|
||||
QGraphicsRectItem *parentPanelFocusItem = new QGraphicsRectItem(parentPanel);
|
||||
parentPanel->setFlag(QGraphicsItem::ItemIsPanel);
|
||||
parentPanelFocusItem->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
parentPanelFocusItem->setFocus();
|
||||
scene.addItem(parentPanel);
|
||||
bool widget = (i == 1);
|
||||
QGraphicsItem *parentPanel = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
QGraphicsItem *parentPanelFocusItem = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
QGraphicsItem *parentPanelFocusItemSibling = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
parentPanel->setFlag(QGraphicsItem::ItemIsPanel);
|
||||
parentPanelFocusItem->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
parentPanelFocusItemSibling->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
if (widget) {
|
||||
static_cast<QGraphicsWidget *>(parentPanelFocusItem)->setFocusPolicy(Qt::StrongFocus);
|
||||
static_cast<QGraphicsWidget *>(parentPanelFocusItemSibling)->setFocusPolicy(Qt::StrongFocus);
|
||||
}
|
||||
parentPanelFocusItem->setParentItem(parentPanel);
|
||||
parentPanelFocusItemSibling->setParentItem(parentPanel);
|
||||
parentPanelFocusItem->setFocus();
|
||||
scene.addItem(parentPanel);
|
||||
|
||||
QVERIFY(parentPanel->isActive());
|
||||
QVERIFY(parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QVERIFY(parentPanel->isActive());
|
||||
QVERIFY(parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
|
||||
QGraphicsRectItem *childPanel = new QGraphicsRectItem;
|
||||
QGraphicsRectItem *childPanelFocusItem = new QGraphicsRectItem(childPanel);
|
||||
childPanel->setFlag(QGraphicsItem::ItemIsPanel);
|
||||
childPanelFocusItem->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
childPanelFocusItem->setFocus();
|
||||
QGraphicsItem *childPanel = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
QGraphicsItem *childPanelFocusItem = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
QGraphicsItem *grandChildPanelFocusItem = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
QGraphicsItem *grandChildPanelFocusItem2 = widget ? (QGraphicsItem *)new QGraphicsWidget : (QGraphicsItem *)new QGraphicsRectItem;
|
||||
|
||||
QVERIFY(!childPanelFocusItem->hasFocus());
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)childPanelFocusItem);
|
||||
QCOMPARE(childPanelFocusItem->focusItem(), (QGraphicsItem *)childPanelFocusItem);
|
||||
childPanel->setFlag(QGraphicsItem::ItemIsPanel);
|
||||
childPanelFocusItem->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
grandChildPanelFocusItem->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
grandChildPanelFocusItem2->setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
|
||||
childPanel->setParentItem(parentPanel);
|
||||
if (widget)
|
||||
{
|
||||
static_cast<QGraphicsWidget *>(childPanelFocusItem)->setFocusPolicy(Qt::StrongFocus);
|
||||
static_cast<QGraphicsWidget *>(grandChildPanelFocusItem)->setFocusPolicy(Qt::StrongFocus);
|
||||
static_cast<QGraphicsWidget *>(grandChildPanelFocusItem2)->setFocusPolicy(Qt::StrongFocus);
|
||||
}
|
||||
grandChildPanelFocusItem->setParentItem(childPanelFocusItem);
|
||||
grandChildPanelFocusItem2->setParentItem(childPanelFocusItem);
|
||||
childPanelFocusItem->setParentItem(childPanel);
|
||||
grandChildPanelFocusItem->setFocus();
|
||||
|
||||
QVERIFY(!parentPanel->isActive());
|
||||
QVERIFY(!parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QVERIFY(!grandChildPanelFocusItem->hasFocus());
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QCOMPARE(childPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QCOMPARE(grandChildPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
|
||||
QVERIFY(childPanel->isActive());
|
||||
QVERIFY(childPanelFocusItem->hasFocus());
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)childPanelFocusItem);
|
||||
QCOMPARE(childPanelFocusItem->focusItem(), (QGraphicsItem *)childPanelFocusItem);
|
||||
childPanel->setParentItem(parentPanel);
|
||||
|
||||
childPanel->hide();
|
||||
QVERIFY(!parentPanel->isActive());
|
||||
QVERIFY(!parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
|
||||
QVERIFY(parentPanel->isActive());
|
||||
QVERIFY(parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QVERIFY(childPanel->isActive());
|
||||
QVERIFY(!childPanelFocusItem->hasFocus());
|
||||
QVERIFY(grandChildPanelFocusItem->hasFocus());
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QCOMPARE(childPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
|
||||
childPanel->hide();
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QVERIFY(!childPanel->focusItem()->hasFocus());
|
||||
QVERIFY(parentPanel->isActive());
|
||||
QVERIFY(parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(grandChildPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
|
||||
childPanel->show();
|
||||
QVERIFY(childPanel->isActive());
|
||||
QVERIFY(grandChildPanelFocusItem->hasFocus());
|
||||
QCOMPARE(childPanel->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QCOMPARE(childPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
QCOMPARE(grandChildPanelFocusItem->focusItem(), (QGraphicsItem *)grandChildPanelFocusItem);
|
||||
|
||||
childPanel->hide();
|
||||
|
||||
QVERIFY(parentPanel->isActive());
|
||||
QVERIFY(parentPanelFocusItem->hasFocus());
|
||||
QCOMPARE(parentPanel->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
QCOMPARE(parentPanelFocusItem->focusItem(), (QGraphicsItem *)parentPanelFocusItem);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsItem::addPanelToActiveScene()
|
||||
|
Loading…
Reference in New Issue
Block a user