From 4eea99788b11ab8b5e3e68764671757d010425c6 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Date: Wed, 25 Nov 2015 11:39:02 +0100
Subject: [PATCH] Fix closing a QMenu by pressing Alt.

In QMenuPrivate::hideMenu(), delay clearing of 'causedPopup.widget'
to after the QMenu::close() call, so that it is still accessible
in QMenu::hideEvent() which calls QMenuBarPrivate::setCurrentAction(0)
if the caused widget is a QMenuBar.

Task-number: QTBUG-47377
Task-number: QTBUG-49592
Change-Id: Idbda48e918dae799afea84068a60d7383d7b4971
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
---
 src/widgets/widgets/qmenu.cpp                 |  2 +-
 .../widgets/widgets/qmenubar/tst_qmenubar.cpp | 30 +++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 27e977f027f..4239e7f3d42 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -502,8 +502,8 @@ void QMenuPrivate::hideMenu(QMenu *menu)
     if (activeMenu == menu)
         activeMenu = 0;
     menu->d_func()->causedPopup.action = 0;
-    menu->d_func()->causedPopup.widget = 0;
     menu->close();
+    menu->d_func()->causedPopup.widget = 0;
     if (previousMouseMenu.data() == menu)
         handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR);
 }
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index baf60551c45..f787d73a027 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -117,6 +117,7 @@ private slots:
 //     void check_mouse2();
 
     void check_altPress();
+    void check_altClosePress();
 #if !defined(Q_OS_MAC) && !defined(Q_OS_WINCE)
     void check_shortcutPress();
     void check_menuPosition();
@@ -978,6 +979,35 @@ void tst_QMenuBar::check_altPress()
     QTRY_VERIFY( ::qobject_cast<QMenuBar *>(qApp->focusWidget()) );
 }
 
+// QTBUG-47377: Pressing 'Alt' after opening a menu by pressing 'Alt+Accelerator'
+// should close it and QMenuBar::activeAction() should be 0.
+void tst_QMenuBar::check_altClosePress()
+{
+    const QStyle *style = QApplication::style();
+    if (!style->styleHint(QStyle::SH_MenuBar_AltKeyNavigation) ) {
+        QSKIP(("This test is not supposed to work in the " + style->objectName().toLatin1()
+               + " style. Skipping.").constData());
+    }
+
+    QMainWindow w;
+    w.setWindowTitle(QTest::currentTestFunction());
+    QMenu *menuFile = w.menuBar()->addMenu(tr("&File"));
+    menuFile->addAction("Quit");
+    QMenu *menuEdit = w.menuBar()->addMenu(tr("&Edit"));
+    menuEdit->addAction("Copy");
+
+    w.show();
+    w.move(QGuiApplication::primaryScreen()->availableGeometry().center());
+    QApplication::setActiveWindow(&w);
+    QVERIFY(QTest::qWaitForWindowActive(&w));
+
+    QTest::keyClick(&w, Qt::Key_F, Qt::AltModifier);
+    QTRY_VERIFY(menuFile->isVisible());
+    QTest::keyClick(menuFile, Qt::Key_Alt, Qt::AltModifier);
+    QTRY_VERIFY(!menuFile->isVisible());
+    QTRY_VERIFY(!w.menuBar()->activeAction());
+}
+
 // Qt/Mac,WinCE does not use the native popups/menubar
 #if !defined(Q_OS_MAC) && !defined(Q_OS_WINCE)
 void tst_QMenuBar::check_shortcutPress()
-- 
GitLab