QMenu::popup(): don't change the menu's screen if called from exec()

Since b3fc5e1ea3,
topData()->initialScreenIndex has always been short-lived: it only
remembers the screen in case the widget parent is a QDesktopScreenWidget
(gotten from QDesktopWidget::screen()), only until the window is
created.  Then it is reset.  In the case of exec() we need to avoid
calling setScreen() twice, because that would set the screen once, then
forget which screen it was supposed to be on, then set the screen again
when exec() calls popup().  This is achieved by using the stored
eventLoop pointer to detect that popup() is being called from exec(),
and avoid calling setScreen() a second time in popup(), because exec()
already needed to call createWinId() before it created the event loop.

Amends 82da8306bc

Task-number: QTBUG-76162
Change-Id: I70da517b9d530630e59d103cb2a1ce11c897b2c8
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Joni Poikelin <joni.poikelin@qt.io>
bb10
Shawn Rutledge 2019-09-05 17:01:23 +02:00
parent e018d11600
commit 648dac1ceb
1 changed files with 10 additions and 7 deletions

View File

@ -2332,14 +2332,17 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
// However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
// then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
// Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
const int screenIndex = d->topData()->initialScreenIndex;
if (screenIndex >= 0)
d->popupScreen = screenIndex;
if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
if (d->setScreen(s))
// However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162)
if (!d->eventLoop) {
const int screenIndex = d->topData()->initialScreenIndex;
if (screenIndex >= 0)
d->popupScreen = screenIndex;
if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
if (d->setScreen(s))
d->itemsDirty = true;
} else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
} else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
}
}
const bool contextMenu = d->isContextMenu();