summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/widgets/qmenu.cpp25
-rw-r--r--src/widgets/widgets/qmenu_p.h1
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp49
3 files changed, 75 insertions, 0 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 5ecac2c7c6..c6d1dd0e7e 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -625,6 +625,29 @@ void QMenuPrivate::hideMenu(QMenu *menu)
menu->d_func()->causedPopup.widget = nullptr;
}
+QWindow *QMenuPrivate::transientParentWindow() const
+{
+ Q_Q(const QMenu);
+ if (const QWidget *parent = q->nativeParentWidget()) {
+ if (parent->windowHandle())
+ return parent->windowHandle();
+ }
+
+ if (const QWindow *w = q->windowHandle()) {
+ if (w->transientParent())
+ return w->transientParent();
+ }
+
+ if (causedPopup.widget) {
+ if (const QWidget *w = causedPopup.widget.data()) {
+ if (const QWidget *ww = w->window())
+ return ww->windowHandle();
+ }
+ }
+
+ return nullptr;
+}
+
void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
{
Q_Q(QMenu);
@@ -2983,6 +3006,8 @@ bool QMenu::event(QEvent *e)
d->sloppyState.reset();
if (d->currentAction)
d->popupAction(d->currentAction, 0, false);
+ if (isWindow() && window() && window()->windowHandle() && !window()->windowHandle()->transientParent())
+ window()->windowHandle()->setTransientParent(d->transientParentWindow());
break;
#if QT_CONFIG(tooltip)
case QEvent::ToolTip:
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index ffe956d007..bad9c294f8 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -440,6 +440,7 @@ public:
QMenuCaused causedPopup;
void hideUpToMenuBar();
void hideMenu(QMenu *menu);
+ QWindow *transientParentWindow() const;
//index mappings
inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 4b46c05568..31ecd024c0 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -118,6 +118,7 @@ private slots:
void QTBUG_89082_actionTipsHide();
void QTBUG8122_widgetActionCrashOnClose();
void widgetActionTriggerClosesMenu();
+ void transientParent();
void QTBUG_10735_crashWithDialog();
#ifdef Q_OS_MAC
@@ -1588,6 +1589,54 @@ void tst_QMenu::widgetActionTriggerClosesMenu()
QCOMPARE(actionTriggered, &widgetAction);
}
+void tst_QMenu::transientParent()
+{
+ QMainWindow window;
+ window.resize(480, 320);
+ window.menuBar()->setNativeMenuBar(false);
+ centerOnScreen(&window);
+
+ QMenu *fileMenu = new QMenu("&File");
+ QAction *exitAct = new QAction("Exit");
+ fileMenu->addAction(exitAct);
+
+ QMenu *editMenu = new QMenu("&Edit");
+ QAction *undoAct = new QAction("Undo");
+ editMenu->addAction(undoAct);
+
+ QMenuBar *menuBar = new QMenuBar;
+ menuBar->addMenu(fileMenu);
+ menuBar->addMenu(editMenu);
+ window.setMenuBar(menuBar);
+
+ // On Mac, we need to create native key events to test menu
+ // action activation, so skip this part of the test.
+#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN)
+ window.show();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QWindow *topLevel = window.windowHandle();
+ QVERIFY(topLevel);
+
+ QApplication::setActiveWindow(&window);
+ window.setFocus();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QVERIFY(window.hasFocus());
+
+ QTest::keyPress(&window, Qt::Key_F, Qt::AltModifier);
+ QTRY_VERIFY(QTest::qWaitForWindowExposed(fileMenu));
+ if (fileMenu->isWindow() && fileMenu->window() && fileMenu->window()->windowHandle())
+ QVERIFY(fileMenu->window()->windowHandle()->transientParent());
+ QTest::keyRelease(fileMenu, Qt::Key_F, Qt::AltModifier);
+
+ QTest::keyPress(fileMenu, Qt::Key_E, Qt::AltModifier);
+ QTRY_VERIFY(QTest::qWaitForWindowExposed(editMenu));
+ if (editMenu->isWindow() && editMenu->window() && editMenu->window()->windowHandle())
+ QVERIFY(editMenu->window()->windowHandle()->transientParent());
+ QTest::keyRelease(editMenu, Qt::Key_E, Qt::AltModifier);
+#endif // QT_CONFIG(shortcut) && !Q_OS_DARWIN
+
+}
+
class MyMenu : public QMenu
{
Q_OBJECT