summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-02-11 17:53:32 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-02-13 18:20:25 +0100
commit52ce4d2d29db8a44fa2fa817cab9ebe969db082e (patch)
tree90fa64f118ef44d6c5ba5bbd27c276c1ed46a49d /src/widgets/widgets
parent0b4286ff28748ae1e47d8750f1899df2eb85357e (diff)
QMenu: guard for destruction when emitting action signals
If a slot connected to a QMenu-action destroys the QMenu, then we must not touch data members in subsequent code, and instead return immediately. We cannot use QBoolBlocker here, as that would reset the data member of QMenuPrivate even when trying to return early. Fixes: QTBUG-106718 Pick-to: 6.5 6.4 6.2 Change-Id: I6b5ea471b1bf1f9864e1384382100f8f6c01346f Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qmenu.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 4e4c8ebe15..987dce71d9 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -1387,9 +1387,18 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget>> &causedStack, QAction *action,
QAction::ActionEvent action_e, bool self)
{
- QBoolBlocker guard(activationRecursionGuard);
+ Q_Q(QMenu);
+ // can't use QBoolBlocker here
+ const bool activationRecursionGuardReset = activationRecursionGuard;
+ activationRecursionGuard = true;
+ QPointer<QMenu> guard(q);
if (self)
action->activate(action_e);
+ if (!guard)
+ return;
+ auto boolBlocker = qScopeGuard([this, activationRecursionGuardReset]{
+ activationRecursionGuard = activationRecursionGuardReset;
+ });
for(int i = 0; i < causedStack.size(); ++i) {
QPointer<QWidget> widget = causedStack.at(i);
@@ -1465,9 +1474,10 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
#endif
}
-
+ QPointer<QMenu> thisGuard(q);
activateCausedStack(causedStack, action, action_e, self);
-
+ if (!thisGuard)
+ return;
if (action_e == QAction::Hover) {
#if QT_CONFIG(accessibility)