From 7ffa6f1dd5c47196ac05300bd990b673c7cca976 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 14 Apr 2025 13:23:49 +0200 Subject: [PATCH] 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 --- src/widgets/widgets/qmenu.cpp | 6 ++++-- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index de37c3efd79..8535056be3c 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -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; diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 968cf60bc41..7edbda70c0d 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -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)