Call QWidget::setVisible, not QWidgetPrivate, when showing children
As part of 5ba0982b2879a1a4c13bf97467b8e5ad296e57a2 we started calling QWidgetPrivate::setVisible instead of QWidget::setVisible when showing children, to avoid setting ExplicitShowHide. Unfortunately some widget subclasses wrongly override setVisible to do initialization, which resulted in these widgets not running their init code. The documentation clearly specifies to use showEvent or Polish for this use case, but to avoid a regression we temporarily set a flag that prevents QWidget::setVisible from setting the ExplicitShowHide attribute. We can not rely on simply unsetting ExplicitShowHide after our call to QWidget::setVisible, as the call might recurse into logic that checks ExplicitShowHide and wrongly determines that the show is explicit. Fixes: QTBUG-126721 Fixes: QTBUG-126218 Pick-to: 6.7 Change-Id: Ibf88340b68cb4fcb20ce3d8ec5b76de0fd2d2551 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit fc4c6fb5f6bd6bd63b13f1f8b5b7a7289a5fd230) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
7b53e87bd7
commit
705dbea2a9
@ -153,6 +153,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
|
||||
, usesRhiFlush(0)
|
||||
, childrenHiddenByWState(0)
|
||||
, childrenShownByExpose(0)
|
||||
, dontSetExplicitShowHide(0)
|
||||
#if defined(Q_OS_WIN)
|
||||
, noPaintOnScreen(0)
|
||||
#endif
|
||||
@ -8291,8 +8292,12 @@ void QWidget::setVisible(bool visible)
|
||||
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible)
|
||||
return;
|
||||
|
||||
// Remember that setVisible was called explicitly
|
||||
setAttribute(Qt::WA_WState_ExplicitShowHide);
|
||||
if (d->dontSetExplicitShowHide) {
|
||||
d->dontSetExplicitShowHide = false;
|
||||
} else {
|
||||
// Remember that setVisible was called explicitly
|
||||
setAttribute(Qt::WA_WState_ExplicitShowHide);
|
||||
}
|
||||
|
||||
d->setVisible(visible);
|
||||
}
|
||||
@ -8446,10 +8451,17 @@ void QWidgetPrivate::showChildren(bool spontaneous)
|
||||
QShowEvent e;
|
||||
QApplication::sendSpontaneousEvent(widget, &e);
|
||||
} else {
|
||||
if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
|
||||
if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
|
||||
widget->d_func()->show_recursive();
|
||||
else
|
||||
widget->d_func()->setVisible(true);
|
||||
} else {
|
||||
// Call QWidget::setVisible() here, so that subclasses
|
||||
// that (wrongly) override setVisible to do initialization
|
||||
// will still be notified that they are made visible, but
|
||||
// do so without triggering ExplicitShowHide.
|
||||
widget->d_func()->dontSetExplicitShowHide = true;
|
||||
widget->setVisible(true);
|
||||
widget->d_func()->dontSetExplicitShowHide = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -733,6 +733,7 @@ public:
|
||||
uint usesRhiFlush : 1;
|
||||
uint childrenHiddenByWState : 1;
|
||||
uint childrenShownByExpose : 1;
|
||||
uint dontSetExplicitShowHide : 1;
|
||||
|
||||
// *************************** Focus abstraction ************************************
|
||||
enum class FocusDirection {
|
||||
|
Loading…
x
Reference in New Issue
Block a user