QMenuBar: do not gain focus when releasing Alt before X in a Alt+X shortcut

It might happen that, when pressing Alt+X to trigger a shortcut for an
action in a menubar, that the user releases Alt first, followed by X. When
that happens, QMenuBar gains focus as if the user just pressed and
released Alt (to focus the menu bar). That's counterintuitive, frustating
and not what native Windows seems to do.

Fix this by resetting the "altPressed" state whenever a shortcut gets
triggered with the Alt key pressed.

(In the above discussion, X stands for any key).

Task-number: QTBUG-46812
Change-Id: If4b7a47842791894a3a32d09db5de229ed33773e
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
bb10
Giuseppe D'Angelo 2016-09-06 17:26:07 +01:00
parent 60e3bfe958
commit 9944a12a0f
2 changed files with 39 additions and 1 deletions

View File

@ -1488,6 +1488,7 @@ bool QMenuBar::eventFilter(QObject *object, QEvent *event)
case QEvent::FocusIn:
case QEvent::FocusOut:
case QEvent::ActivationChange:
case QEvent::Shortcut:
d->altPressed = false;
qApp->removeEventFilter(this);
break;

View File

@ -130,6 +130,7 @@ private slots:
void cornerWidgets_data();
void cornerWidgets();
void taskQTBUG53205_crashReparentNested();
void taskQTBUG46812_doNotLeaveMenubarHighlighted();
protected slots:
void onSimpleActivated( QAction*);
@ -222,9 +223,14 @@ TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb)
menu = mb->addMenu(QStringLiteral("accel1"));
action = menu->addAction(QStringLiteral("&Open...") );
action->setShortcut(Qt::Key_O);
result.actions << action;
action = menu->addAction(QStringLiteral("action"));
action->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Z));
result.actions << action;
result.menus << menu;
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(onSimpleActivated(QAction*)));
result.actions << action;
m_lastSimpleAcceleratorId = 0;
m_simpleActivatedCount = 0;
@ -1494,6 +1500,37 @@ void tst_QMenuBar::slotForTaskQTBUG53205()
taskQTBUG53205MenuBar->setParent(parent);
}
void tst_QMenuBar::taskQTBUG46812_doNotLeaveMenubarHighlighted()
{
QMainWindow mainWindow;
QWidget *centralWidget = new QWidget;
centralWidget->setFocusPolicy(Qt::StrongFocus);
mainWindow.setCentralWidget(centralWidget);
initWindowWithSimpleMenuBar(mainWindow);
mainWindow.show();
QApplication::setActiveWindow(&mainWindow);
QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
QVERIFY(!mainWindow.menuBar()->hasFocus());
QCOMPARE(m_simpleActivatedCount, 0);
QTest::keyPress(&mainWindow, Qt::Key_Alt, Qt::AltModifier);
QVERIFY(!mainWindow.menuBar()->hasFocus());
QCOMPARE(m_simpleActivatedCount, 0);
QTest::keyPress(&mainWindow, Qt::Key_Z, Qt::AltModifier);
QVERIFY(!mainWindow.menuBar()->hasFocus());
QCOMPARE(m_simpleActivatedCount, 2); // the action AND the menu will activate
QTest::keyRelease(&mainWindow, Qt::Key_Alt, Qt::NoModifier);
QVERIFY(!mainWindow.menuBar()->hasFocus());
QCOMPARE(m_simpleActivatedCount, 2);
QTest::keyRelease(&mainWindow, Qt::Key_Z, Qt::NoModifier);
QVERIFY(!mainWindow.menuBar()->hasFocus());
QCOMPARE(m_simpleActivatedCount, 2);
}
QTEST_MAIN(tst_QMenuBar)