QPushButton: use QMenu::popup instead of exec to show menu

QMenu::exec opens a blocking loop, which is problematic for webassembly.
Replace with QMenu::popup, and reset the down-state of the button when
the menu is about to hide. QMenu emits aboutToHide immediately before
existing the event loop in the hideEvent override, so the timing is the
same.

Change-Id: Iccb418d10fcb25f6ad1f73f9cdce6ea6581bd73b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-03-07 14:44:14 +01:00
parent cf5d9e9eb5
commit 7199498fb9
2 changed files with 10 additions and 9 deletions

View File

@ -575,17 +575,14 @@ void QPushButtonPrivate::_q_popupPressed()
QPoint menuPos = adjustedMenuPosition();
QPointer<QPushButton> guard(q);
QMenuPrivate::get(menu)->causedPopup.widget = guard;
QMenuPrivate::get(menu)->causedPopup.widget = q;
//Because of a delay in menu effects, we must keep track of the
//menu visibility to avoid flicker on button release
menuOpen = true;
menu->exec(menuPos);
if (guard) {
menuOpen = false;
q->setDown(false);
}
QObject::connect(menu, &QMenu::aboutToHide,
q, [q]{ q->setDown(false); }, Qt::SingleShotConnection);
menu->popup(menuPos);
}
QPoint QPushButtonPrivate::adjustedMenuPosition()

View File

@ -1143,14 +1143,18 @@ void tst_QMenu::pushButtonPopulateOnAboutToShow()
QSKIP("Your window manager won't allow a window against the bottom of the screen");
}
QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
QTest::qWait(300);
buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
// note: we're assuming that, if we previously got the desired geometry, we'll get it here too
b.move(10, screen.bottom()-buttonMenu->height()-5);
QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
QTest::qWait(300);
buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
}