From 6173fc0e4be93604286b9a424f1aa3ff5896082a Mon Sep 17 00:00:00 2001 From: Chen Bin Date: Tue, 21 Jun 2022 11:10:00 +0800 Subject: [PATCH] Menu: cull non-visible items when `contentItem` inherits Item For a custom menu control, when the contentItem does not inherit from ItemView, the text overlaps. A related bug is QTBUG-53262, but this problem is only fixed for the ItemView control. Since the contentItem control can accept the Item control, I think the repair only for ItemView has limitations. Therefore, this submission cancels the restriction on the type of contentitem. Pick-to: 6.3 6.4 Fixes: QTBUG-104470 Change-Id: I7e697e3cb993475d157a92f37d9512e4a9872387 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickmenu.cpp | 3 +- .../qquickmenu/data/customMenuCullItems.qml | 55 +++++++++++++++++++ .../qquickmenu/tst_qquickmenu.cpp | 22 ++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quickcontrols2/qquickmenu/data/customMenuCullItems.qml diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 5494ab3b67..20280824c0 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -204,8 +204,7 @@ void QQuickMenuPrivate::insertItem(int index, QQuickItem *item) { contentData.append(item); item->setParentItem(contentItem); - if (qobject_cast(contentItem)) - QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-53262 + QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-53262 if (complete) resizeItem(item); QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); diff --git a/tests/auto/quickcontrols2/qquickmenu/data/customMenuCullItems.qml b/tests/auto/quickcontrols2/qquickmenu/data/customMenuCullItems.qml new file mode 100644 index 0000000000..0f56ecdd87 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/customMenuCullItems.qml @@ -0,0 +1,55 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + width: 200 + height: 200 + property alias menu: menu + + Menu { + id: menu + + contentItem: FocusScope { + implicitHeight: view.implicitHeight + Button { + anchors { + top: parent.top + topMargin: 5 + horizontalCenter: parent.horizontalCenter + } + z: 1 + text: "Button Up" + visible: view.interactive + } + ListView { + id: view + width: parent.width + implicitHeight: Math.min(contentHeight, 300) + model: menu.contentModel + + clip: true + currentIndex: menu.currentIndex + ScrollIndicator.vertical: ScrollIndicator {} + } + Button { + anchors { + bottom: parent.bottom + bottomMargin: 5 + horizontalCenter: parent.horizontalCenter + } + z: 1 + text: "Button Down" + visible: view.interactive + } + } + + Repeater { + model: 20 + MenuItem { + objectName: "Item: " + modelData + text: objectName + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp index 38f2cd6f4b..d7ec942c14 100644 --- a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp +++ b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp @@ -78,6 +78,7 @@ private slots: void menuItemWidthAfterImplicitWidthChanged(); void menuItemWidthAfterRetranslate(); void giveMenuItemFocusOnButtonPress(); + void customMenuCullItems(); }; tst_QQuickMenu::tst_QQuickMenu() @@ -1977,6 +1978,27 @@ void tst_QQuickMenu::giveMenuItemFocusOnButtonPress() QTRY_VERIFY(menu->isOpened()); } +void tst_QQuickMenu::customMenuCullItems() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("customMenuCullItems.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value(); + QVERIFY(menu); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + + QQuickItem *menuItemFirst = menu->itemAt(0); + QQuickItem *menuItemLast = menu->itemAt(menu->count() - 1); + QVERIFY(menuItemFirst); + QVERIFY(menuItemLast); + QTRY_VERIFY(!QQuickItemPrivate::get(menuItemFirst)->culled); + QTRY_VERIFY(QQuickItemPrivate::get(menuItemLast)->culled); +} + QTEST_QUICKCONTROLS_MAIN(tst_QQuickMenu) #include "tst_qquickmenu.moc"