diff options
| author | Tor Arne Vestbø <[email protected]> | 2024-07-01 12:44:45 +0200 |
|---|---|---|
| committer | Tor Arne Vestbø <[email protected]> | 2024-07-04 14:18:39 +0200 |
| commit | fc4c6fb5f6bd6bd63b13f1f8b5b7a7289a5fd230 (patch) | |
| tree | 1e2d58674e929512a8b36f741ce4bacf4919db3e /src/widgets/kernel | |
| parent | 9293fb9bd09d80aa6f0f503d5581cbc116b3d0b5 (diff) | |
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 6.8
Change-Id: Ibf88340b68cb4fcb20ce3d8ec5b76de0fd2d2551
Reviewed-by: Volker Hilsheimer <[email protected]>
Diffstat (limited to 'src/widgets/kernel')
| -rw-r--r-- | src/widgets/kernel/qwidget.cpp | 22 | ||||
| -rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 540a8930493..514a2f21d5a 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -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; + } } } } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 9fab9efa62b..b27ffdb1be6 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -733,6 +733,7 @@ public: uint usesRhiFlush : 1; uint childrenHiddenByWState : 1; uint childrenShownByExpose : 1; + uint dontSetExplicitShowHide : 1; // *************************** Focus abstraction ************************************ enum class FocusDirection { |
