From 9944a12a0f57087ea19ae428ffcd974ac0fed7bc Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 6 Sep 2016 17:26:07 +0100 Subject: [PATCH] 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 --- src/widgets/widgets/qmenubar.cpp | 1 + .../widgets/widgets/qmenubar/tst_qmenubar.cpp | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index a77c0f9753..ce43740524 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -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; diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index ca58dc1247..5e27f5e80f 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -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)