QMenu: show when QWidget::childrenRect is not empty

Amends 353ce5344fbde5a6cecbdd2c131e1cf0f4b7f383 after which QMenu::popup
returned early and without showing the menu if none of the actions had a
valid geometry in the menu.

This broke use cases where QMenu was used as a regular container widget
with child widgets (possibly in a layout). To fix this, take the result
of QWidget::childrenRect() into account, and only return early if that
rect is also empty.

Task-number: QTBUG-129108
Fixes: QTBUG-135933
Pick-to: 6.9 6.8
Change-Id: I05977044411df236146bb81dc08a30c176dfb6cb
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Volker Hilsheimer 2025-04-14 13:23:49 +02:00
parent be2729cd7c
commit 7ffa6f1dd5
2 changed files with 11 additions and 2 deletions

View File

@ -2450,9 +2450,11 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
}
}
// do nothing if we don't have a valid size, e.g. when all actions are invisible
// Do nothing if we don't have a valid size, e.g. when all actions are invisible
// and there are no child widgets.
const auto rectIsNull = [](const QRect &rect) { return rect.isNull(); };
if (std::all_of(actionRects.cbegin(), actionRects.cend(), rectIsNull)) {
if (q->childrenRect().isEmpty()
&& std::all_of(actionRects.cbegin(), actionRects.cend(), rectIsNull)) {
eventLoop = nullptr;
syncAction = nullptr;
return;

View File

@ -2179,6 +2179,13 @@ void tst_QMenu::invisibleActions()
contextMenu.popup(globalPos);
QVERIFY(!contextMenu.isVisible());
QVERIFY(!contextMenu.exec());
// a QMenu might not have any (visible) actions, but still have contents
QPushButton *buttonInMenu = new QPushButton(&contextMenu);
buttonInMenu->show();
contextMenu.popup(globalPos);
QVERIFY(contextMenu.isVisible());
}
#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN)