QToolButton: allow opening a menu after it first failed because empty

Commit 353ce5344fbde5a6cecbdd2c131e1cf0f4b7f383 made QMenu::exec()
return immediately (without showing the menu), which meant it never
emitted aboutToHide() and QToolButton didn't reset mouseButtonDown.
Therefore, on the next click on the toolbutton (maybe by then the
menu has actions), it won't even try to show it (because mouseButtonDown
is still true).

Pick-to: 6.8
Task-number: QTBUG-129108
Change-Id: I3f84b9a35eb444fc33d8516c4be130293c04017d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit f0508b7ff3d2393521f49dcb1a9e880bf7665a87)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
David Faure 2025-02-10 20:16:16 +01:00 committed by Qt Cherry-pick Bot
parent 7fc08a8a68
commit 05016926ae
2 changed files with 28 additions and 0 deletions

View File

@ -788,6 +788,11 @@ void QToolButtonPrivate::popupTimerDone()
QObjectPrivate::disconnect(actualMenu, &QMenu::aboutToHide,
this, &QToolButtonPrivate::updateButtonDown);
if (menuButtonDown) {
// The menu was empty, it didn't actually show up, so it was never hidden either
updateButtonDown();
}
if (mustDeleteActualMenu) {
delete actualMenu;
} else {

View File

@ -35,6 +35,7 @@ private slots:
void qtbug_34759_sizeHintResetWhenSettingMenu();
void defaultActionSynced();
void deleteInHandler();
void emptyMenu();
protected slots:
void sendMouseClick();
@ -338,5 +339,27 @@ void tst_QToolButton::deleteInHandler()
QVERIFY(!tb);
}
void tst_QToolButton::emptyMenu()
{
QToolButton tb;
auto menu = new QMenu(&tb);
tb.setMenu(menu);
tb.showMenu(); // calls exec(), but since the fix for QTBUG-129108, we don't show an empty menu
// see triggered() test
QTest::mouseMove(tb.windowHandle(), tb.mapFromGlobal(QPoint(0, 0)));
// But if we now put something in the menu, it should show up
auto act = menu->addAction("an action");
QSignalSpy triggeredSpy(act, &QAction::triggered);
// In 200ms, click on the action so that exec() returns
QTimer::singleShot(200, menu, [&]() {
QTest::mouseClick(menu, Qt::LeftButton, {}, menu->rect().center());
});
tb.showMenu(); // calls exec(), which only returns in 200ms
QTRY_COMPARE(triggeredSpy.size(), 1);
}
QTEST_MAIN(tst_QToolButton)
#include "tst_qtoolbutton.moc"