Don't fire shortcut if the action only lives in an unreachable submenu
Menus can be represented by a menu action, and if that menu action has been hidden or disabled, then the submenu is not accessible from the parent menu or menu bar to which it was added. Don't walk the menu action chain further when checking whether the shortcut should trigger. Note that this is unrelated to the menu being visible or not; we obviously want to trigger shortcuts for actions that only live in a menu that has not been shown, otherwise the shortcut would be rather pointless. Pick-to: 6.2 Fixes: QTBUG-25743 Change-Id: I48735e17352989bbc84a72263e4828f519b78095 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
e022ff0a8e
commit
01f96b1764
@ -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
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <qaction.h>
|
||||
#include <qactiongroup.h>
|
||||
#include <qmenu.h>
|
||||
#include <qmenubar.h>
|
||||
#include <qtoolbar.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
@ -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<QByteArray>("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)
|
||||
|
Loading…
Reference in New Issue
Block a user