macOS: Prevent recursion when modifying the edit menu
Amends d42cfeb84f
, which would result in
infinite recursion when the Edit menu was populated and added to the
menubar after the menubar has been shown.
Add a macOS-only test case that reproduces the crash without the fix.
Fixes: QTBUG-100441
Pick-to: 6.3
Change-Id: I018a7aa7f01558a3b9732b4d6d96a911dc7fbd19
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
15caa47e4b
commit
851143eff1
@ -196,8 +196,15 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate)
|
||||
|
||||
const QString captionNoAmpersand = QString::fromNSString(cocoaMenu->nsMenu().title)
|
||||
.remove(QLatin1Char('&'));
|
||||
if (captionNoAmpersand == QCoreApplication::translate("QCocoaMenu", "Edit"))
|
||||
if (captionNoAmpersand == QCoreApplication::translate("QCocoaMenu", "Edit")) {
|
||||
// prevent recursion from QCocoaMenu::insertMenuItem - when the menu is visible
|
||||
// it calls syncMenu again. QCocoaMenu::setVisible just sets the bool, which then
|
||||
// gets evaluated in the code after this block.
|
||||
const bool wasVisible = cocoaMenu->isVisible();
|
||||
cocoaMenu->setVisible(false);
|
||||
insertDefaultEditItems(cocoaMenu);
|
||||
cocoaMenu->setVisible(wasVisible);
|
||||
}
|
||||
|
||||
BOOL shouldHide = YES;
|
||||
if (cocoaMenu->isVisible()) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTranslator>
|
||||
#include <qscreen.h>
|
||||
|
||||
#include <qobject.h>
|
||||
@ -144,6 +145,8 @@ private slots:
|
||||
#ifdef Q_OS_MACOS
|
||||
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
|
||||
void QTBUG_57404_existingMenuItemException();
|
||||
void defaultEditMenuItems();
|
||||
|
||||
#endif
|
||||
void QTBUG_25669_menubarActionDoubleTriggered();
|
||||
void taskQTBUG55966_subMenuRemoved();
|
||||
@ -1818,6 +1821,32 @@ void tst_QMenuBar::QTBUG_57404_existingMenuItemException()
|
||||
QTest::qWait(100);
|
||||
// No crash, all fine. Ideally, there should be only one warning.
|
||||
}
|
||||
|
||||
void tst_QMenuBar::defaultEditMenuItems()
|
||||
{
|
||||
class TestTranslator : public QTranslator
|
||||
{
|
||||
public:
|
||||
QString translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation = nullptr, int n = -1) const override
|
||||
{
|
||||
if (QByteArrayView(context) == "QCocoaMenu" && QByteArrayView(sourceText) == "Edit")
|
||||
return QString("Editieren");
|
||||
return QTranslator::translate(context, sourceText, disambiguation, n);
|
||||
}
|
||||
} testTranslator;
|
||||
qApp->installTranslator(&testTranslator);
|
||||
|
||||
QMainWindow mw;
|
||||
mw.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&mw));
|
||||
|
||||
mw.menuBar()->addMenu("Editieren")->addAction("Undo");
|
||||
|
||||
mw.hide();
|
||||
mw.show();
|
||||
// this should not crash with infinite recursion
|
||||
}
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
void tst_QMenuBar::taskQTBUG55966_subMenuRemoved()
|
||||
|
Loading…
Reference in New Issue
Block a user