diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index ac474c9babc..861af005e58 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> &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 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 widget = causedStack.at(i); @@ -1465,9 +1474,10 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e #endif } - + QPointer thisGuard(q); activateCausedStack(causedStack, action, action_e, self); - + if (!thisGuard) + return; if (action_e == QAction::Hover) { #if QT_CONFIG(accessibility) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 31a3addd44f..a7563bfa26e 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -110,6 +110,7 @@ private slots: void tearOffMenuNotDisplayed(); void QTBUG_61039_menu_shortcuts(); void screenOrientationChangedCloseMenu(); + void deleteWhenTriggered(); protected slots: void onActivated(QAction*); @@ -2011,5 +2012,22 @@ void tst_QMenu::screenOrientationChangedCloseMenu() QTRY_COMPARE(menu.isVisible(),false); } +/* + Verify that deleting the menu in a slot connected to an + action's triggered signal doesn't crash. + QTBUG-106718 +*/ +void tst_QMenu::deleteWhenTriggered() +{ + QPointer menu = new QMenu; + QAction *action = menu->addAction("Action", [&menu]{ + delete menu; + }); + menu->popup(QGuiApplication::primaryScreen()->availableGeometry().center()); + menu->setActiveAction(action); + QTest::keyClick(menu, Qt::Key_Return); + QTRY_VERIFY(!menu); +} + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc"