diff --git a/src/widgets/kernel/qshortcut_widgets.cpp b/src/widgets/kernel/qshortcut_widgets.cpp index 9e64376fce..8beb4ce5d6 100644 --- a/src/widgets/kernel/qshortcut_widgets.cpp +++ b/src/widgets/kernel/qshortcut_widgets.cpp @@ -307,7 +307,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge continue; #endif QAction *a = menu->menuAction(); - if (correctActionContext(context, a, active_window)) + if (a->isVisible() && a->isEnabled() && correctActionContext(context, a, active_window)) return true; } else #endif diff --git a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp index 63d49e1216..025cebb15f 100644 --- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp +++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -65,6 +67,8 @@ private slots: void disableShortcutsWithBlockedWidgets_data(); void disableShortcutsWithBlockedWidgets(); void shortcutFromKeyEvent(); // QTBUG-48325 + void disableShortcutInMenuAction_data(); + void disableShortcutInMenuAction(); #endif private: @@ -418,6 +422,76 @@ void tst_QAction::shortcutFromKeyEvent() QCOMPARE(testWidget.shortcutOverrideCount, 1); } +/* + Ignore actions in menus whose menu action has been hidden or disabled. + The menu entry will not be in the menu bar or parent menu, so the action + is not reachable through interactive means. QTBUG-25743 +*/ +void tst_QAction::disableShortcutInMenuAction_data() +{ + QTest::addColumn("property"); + + QTest::addRow("visible") << QByteArray("visible"); + QTest::addRow("enabled") << QByteArray("enabled"); +} + +void tst_QAction::disableShortcutInMenuAction() +{ + QFETCH(QByteArray, property); + + QMainWindow mw; + QMenu *testMenu = mw.menuBar()->addMenu("Test"); + QAction *testAction = testMenu->addAction("Test Action"); + testAction->setShortcut(Qt::ControlModifier | Qt::Key_A); + QToolBar *toolBar = new QToolBar; + mw.addToolBar(toolBar); + + mw.show(); + QVERIFY(QTest::qWaitForWindowActive(&mw)); + + int expectedTriggerCount = 0; + QSignalSpy spy(testAction, &QAction::triggered); + + QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::ControlModifier); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), ++expectedTriggerCount); + + testMenu->menuAction()->setProperty(property, false); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), expectedTriggerCount); + + testMenu->menuAction()->setProperty(property, true); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), ++expectedTriggerCount); + + // If the action lives somewhere else, then keep firing even + // if the menu has been hidden or disabled. + toolBar->addAction(testAction); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), ++expectedTriggerCount); + + testMenu->menuAction()->setProperty(property, false); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), ++expectedTriggerCount); + + // unless all other widgets in which the action lives have + // been hidden... + toolBar->hide(); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), expectedTriggerCount); + + // ... or disabled + toolBar->show(); + toolBar->setEnabled(false); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), expectedTriggerCount); + + // back to normal + toolBar->setEnabled(true); + QApplication::sendEvent(&mw, &event); + QCOMPARE(spy.count(), ++expectedTriggerCount); +} + #endif // QT_CONFIG(shortcut) QTEST_MAIN(tst_QAction)