QWidget: do not send hide events to hidden children
The logic in QWidgetPrivate::hideChildren sends hide events to all of its children, including the ones that are already hidden (and thus have received already a hide event). This breaks some "event counting" logic in QGraphicsScene, which (since it can be displayed in multiple views) keeps track of how many hide/show events it has received. It is possible to break this counter by having it receive several hide events in a row, which won't be matched by the same number of show events. These extra hide events may be generated by adding a QGraphicsView into a QTabWidget (or QStackedWidget), hiding *that*, and then changing the current index -- which shows/hides the children. This makes the counter go negative and break. Furthermore, a hide event is received after the widget has been made invisible, therefore one can't check for "was I visible when I received this hide event?" This commit changes the logic in QWidgetPrivate::hideChildren so that we don't do anything if the a child was already not visible. [ChangeLog][QtWidgets][QWidget] Widgets which are already hidden no longer receive hide events if they're made hidden again (for instance because an ancestor gets hidden). Change-Id: I73061b9d8bf33911778c9c30df33dbe43e9deaa3 Fixes: QTBUG-53974 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
909493bae2
commit
b17703171c
@ -8463,7 +8463,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous)
|
||||
continue;
|
||||
qCDebug(lcWidgetShowHide) << "Considering" << widget
|
||||
<< "with attributes" << WidgetAttributes{widget};
|
||||
if (widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
|
||||
if (widget->isWindow() || !widget->isVisible())
|
||||
continue;
|
||||
|
||||
if (spontaneous)
|
||||
|
@ -5013,9 +5013,7 @@ void tst_QGraphicsView::QTBUG_53974_mismatched_hide_show_events()
|
||||
QCOMPARE_EQ(scene->d_func()->activationRefCount, 0);
|
||||
|
||||
lowLevel->setCurrentIndex(0);
|
||||
QEXPECT_FAIL("", "The view was already hidden, so the refcount should still be 0", Continue);
|
||||
QCOMPARE_EQ(scene->d_func()->activationRefCount, 0);
|
||||
scene->d_func()->activationRefCount = 0;
|
||||
|
||||
// Make lowLevel visible.
|
||||
topLevel.setCurrentIndex(1);
|
||||
@ -5043,9 +5041,7 @@ void tst_QGraphicsView::QTBUG_53974_mismatched_hide_show_events()
|
||||
QCOMPARE_EQ(scene->d_func()->activationRefCount, 0);
|
||||
|
||||
lowLevel->setCurrentIndex(0);
|
||||
QEXPECT_FAIL("", "The view was already hidden, so the refcount should still be 0", Continue);
|
||||
QCOMPARE_EQ(scene->d_func()->activationRefCount, 0);
|
||||
scene->d_func()->activationRefCount = 0;
|
||||
|
||||
// Make lowLevel and the QGV visible.
|
||||
lowLevel->setCurrentIndex(1);
|
||||
@ -5060,9 +5056,7 @@ void tst_QGraphicsView::QTBUG_53974_mismatched_hide_show_events()
|
||||
|
||||
// Hide the QGV:
|
||||
lowLevel->setCurrentIndex(0);
|
||||
QEXPECT_FAIL("", "The view was already hidden, so the refcount should still be 0", Continue);
|
||||
QCOMPARE_EQ(scene->d_func()->activationRefCount, 0);
|
||||
scene->d_func()->activationRefCount = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user