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.

Pick-to: 6.9 6.8
Fixes: QTBUG-56952
Change-Id: I894ee09d9ccc7154ca506ef907924cd150ac6ed2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Christian Ehrlicher 2024-11-05 20:43:37 +01:00
parent 51474d795a
commit 13636f848d
2 changed files with 28 additions and 0 deletions

View File

@ -3381,6 +3381,8 @@ void QMenu::keyPressEvent(QKeyEvent *e)
if (d->actionRects.at(i).isNull()) if (d->actionRects.at(i).isNull())
continue; continue;
QAction *act = d->actions.at(i); QAction *act = d->actions.at(i);
if (!act->isEnabled() || act->isSeparator())
continue;
QKeySequence sequence = QKeySequence::mnemonic(act->text()); QKeySequence sequence = QKeySequence::mnemonic(act->text());
int key = sequence[0].toCombined() & 0xffff; // suspicious int key = sequence[0].toCombined() & 0xffff; // suspicious
if (key == c.unicode()) { if (key == c.unicode()) {

View File

@ -117,6 +117,9 @@ private slots:
void nestedTearOffDetached(); void nestedTearOffDetached();
void closeMenuOnClickIfMouseHasntMoved(); void closeMenuOnClickIfMouseHasntMoved();
#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN)
void dontSelectDisabledActionByShortcut();
#endif
void invisibleActions(); void invisibleActions();
@ -2179,5 +2182,28 @@ void tst_QMenu::invisibleActions()
QVERIFY(!contextMenu.exec()); 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) QTEST_MAIN(tst_QMenu)
#include "tst_qmenu.moc" #include "tst_qmenu.moc"