summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qcombobox.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-08-25 14:11:23 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-08-27 15:51:28 +0000
commitaccc833e556ba54038d1cc7e261a936492145240 (patch)
treed127639497ebebe4cf392bbfa8cf7485af7f2c13 /src/widgets/widgets/qcombobox.cpp
parent50bb5f8282d3295f9891b83126526474235d0dec (diff)
QComboBox: Prevent recursion in hidePopup
With styles that want the selected combobox item to flash, QComboBox runs a modal event loop in hidePopup. This might result in reentrancy if a mouseReleaseEvent is processed during the 60 ms of flashing. Since mouseReleaseEvent calls hidePopup again, we end up reentrancy and possibly undefined behavior which has caused crashes with Qt Creator on macOS. Prevent the reentrancy of hidePopup using a boolean flag. Since QBoolBlocker (or QScopedValueRollback) cannot be used with a bit flag, use a QScopeGuard to reset the flag reliably. Fixes: QTBUG-105951 Change-Id: Iaa5df47b93217fc8dff621764ac4005bbc3459b7 Reviewed-by: Eike Ziller <eike.ziller@qt.io> (cherry picked from commit 2af64c4577e42fecfeab9611c15fa8526bb09988) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/widgets/widgets/qcombobox.cpp')
-rw-r--r--src/widgets/widgets/qcombobox.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 9caac239f9..e754d02f2a 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -58,7 +58,8 @@ QComboBoxPrivate::QComboBoxPrivate()
shownOnce(false),
duplicatesEnabled(false),
frame(true),
- inserting(false)
+ inserting(false),
+ hidingPopup(false)
{
}
@@ -2805,6 +2806,13 @@ void QComboBox::showPopup()
void QComboBox::hidePopup()
{
Q_D(QComboBox);
+ if (d->hidingPopup)
+ return;
+ d->hidingPopup = true;
+ // can't use QBoolBlocker on a bitfield
+ auto resetHidingPopup = qScopeGuard([d]{
+ d->hidingPopup = false;
+ });
if (d->container && d->container->isVisible()) {
#if QT_CONFIG(effects)
QSignalBlocker modelBlocker(d->model);