diff options
author | Oleg Yadrov <oleg.yadrov@qt.io> | 2017-01-13 10:33:49 -0800 |
---|---|---|
committer | Oleg Yadrov <oleg.yadrov@qt.io> | 2017-03-04 05:37:30 +0000 |
commit | f2e103296f9077a747e0dd43504e3e7630f56605 (patch) | |
tree | c666b77dc5d6ff1f5d10117000d34c68b25c5335 | |
parent | ad5565b6438cb239ad36722605a31b1006cd6478 (diff) |
QMenu: make wide submenu appear on the same screen with its parent menu
On a multi-display system wide submenu might either appear on wrong
screen or not appear at all (depending on the specific display
configuration).
Task-number: QTBUG-56917
Change-Id: I40013b0bee340a01ae1c08a5e074afa63da4dbfd
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 15 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 25 |
2 files changed, 38 insertions, 2 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 16f8734d7b..1925b58326 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -3501,11 +3501,22 @@ void QMenu::internalDelayedPopup() d->activeMenu->d_func()->causedPopup.widget = this; d->activeMenu->d_func()->causedPopup.action = d->currentAction; + QRect screen; +#ifndef QT_NO_GRAPHICSVIEW + bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this); + if (isEmbedded) + screen = d->popupGeometry(this); + else +#endif + screen = d->popupGeometry(QApplication::desktop()->screenNumber(pos())); + int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); const QRect actionRect(d->actionRect(d->currentAction)); - const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + QPoint subMenuPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + if (subMenuPos.x() > screen.right()) + subMenuPos.setX(QCursor::pos().x()); - d->activeMenu->popup(rightPos); + d->activeMenu->popup(subMenuPos); d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu); #if !defined(Q_OS_DARWIN) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 4e82099706..b037cc2141 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -113,6 +113,7 @@ private slots: #endif void QTBUG_56917_wideMenuSize(); void QTBUG_56917_wideMenuScreenNumber(); + void QTBUG_56917_wideSubmenuScreenNumber(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -1348,5 +1349,29 @@ void tst_QMenu::QTBUG_56917_wideMenuScreenNumber() } } +void tst_QMenu::QTBUG_56917_wideSubmenuScreenNumber() +{ + if (QApplication::styleHints()->showIsFullScreen()) + QSKIP("The platform defaults to windows being fullscreen."); + // submenu must appear on the same screen where its parent menu is shown + QString longString; + longString.fill(QLatin1Char('Q'), 3000); + + for (int i = 0; i < QApplication::desktop()->screenCount(); i++) { + QMenu menu; + QMenu submenu("Submenu"); + submenu.addAction(longString); + QAction *action = menu.addMenu(&submenu); + menu.popup(QApplication::desktop()->screen(i)->geometry().center()); + QVERIFY(QTest::qWaitForWindowExposed(&menu)); + QVERIFY(menu.isVisible()); + QTest::mouseClick(&menu, Qt::LeftButton, 0, menu.actionGeometry(action).center()); + QTest::qWait(100); + QVERIFY(QTest::qWaitForWindowExposed(&submenu)); + QVERIFY(submenu.isVisible()); + QCOMPARE(QApplication::desktop()->screenNumber(&submenu), i); + } +} + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" |