From 1fb685f918ed6fd740c031d5353d8a8ff65321fa Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 5 Nov 2024 20:43:37 +0100 Subject: [PATCH] QMenu: Ignore disabled hotkey during hotkey search When two actions in one menu have the same hotkey and the first action is not enabled, the action search was selecting the first, disabled action despite the fact that it could not be selected later on. Fixes: QTBUG-56952 Change-Id: I894ee09d9ccc7154ca506ef907924cd150ac6ed2 Reviewed-by: Volker Hilsheimer (cherry picked from commit 13636f848da6932f9864bf9335d19b439b8387cd) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 7a9f724735670d7880a1221fdde6d992e3554dd6) --- src/widgets/widgets/qmenu.cpp | 2 ++ .../auto/widgets/widgets/qmenu/tst_qmenu.cpp | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 78f4f13935..b92fa85672 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -3381,6 +3381,8 @@ void QMenu::keyPressEvent(QKeyEvent *e) if (d->actionRects.at(i).isNull()) continue; QAction *act = d->actions.at(i); + if (!act->isEnabled() || act->isSeparator()) + continue; QKeySequence sequence = QKeySequence::mnemonic(act->text()); int key = sequence[0].toCombined() & 0xffff; // suspicious if (key == c.unicode()) { diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 52f24505dc..f3e3eb44b7 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -117,6 +117,9 @@ private slots: void nestedTearOffDetached(); void closeMenuOnClickIfMouseHasntMoved(); +#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN) + void dontSelectDisabledActionByShortcut(); +#endif void invisibleActions(); @@ -2179,5 +2182,28 @@ void tst_QMenu::invisibleActions() QVERIFY(!contextMenu.exec()); } +#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN) +void tst_QMenu::dontSelectDisabledActionByShortcut() +{ + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("Window activation is not supported"); + + QMainWindow w; + auto mb = w.menuBar(); + auto m = mb->addMenu("me&nu"); + auto zero = m->addAction("placeholder"); + auto first = m->addAction("disabled &o"); + auto second = m->addAction(QStringLiteral("enabled &o")); + + QSignalSpy spy(second, &QAction::triggered); + first->setDisabled(true); + w.show(); + QVERIFY(QTest::qWaitForWindowActive(&w)); + QTest::keyClick(&w, Qt::Key_N, Qt::AltModifier); + QTest::keyClick(m, Qt::Key_O, Qt::NoModifier); + QCOMPARE(spy.count(), 1); +} +#endif + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc"