From 99ceb8d19083323a37ef8d5a87e30c86a536ed18 Mon Sep 17 00:00:00 2001 From: wangjinrun Date: Tue, 25 Aug 2026 15:12:26 +0800 Subject: [PATCH] fix(popup): prevent width jumping when content changes in Window popupType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit cba9773 removed the background Item's implicitWidth binding to break a binding loop, Popup's implicitWidth started tracking contentImplicitWidth directly. When popupType is Popup.Window, QQuickPopupWindow::implicitWidthChanged() unconditionally adopts popup->implicitWidth(), so search filtering that shrinks the content causes the popup window to jump to a smaller width. Add an explicit ratchet: once the popup is open, implicitWidth/Height only grow, never shrink. The old binding loop accidentally provided this behavior; this is a loop-free replacement. Instead of overriding implicitWidth/Height directly, keep the sticky-max via the background's (windowBlurComponent) implicit size, the natural source of the popup's default implicit size, and only for Popup.Window so Popup.Item keeps resizing with its content. 1. Add _maxImplicitWidth/_maxImplicitHeight ratchet state properties 2. Reset ratchet on aboutToShow for each open session 3. Update ratchet on implicitContentWidth/HeightChanged (grow only) 4. Apply the ratchet to the Popup.Window background's implicit size 修复 Popup 在 Window popupType 下宽度跳变问题 commit cba9773 移除 background Item 的 implicitWidth 绑定以消除绑定环后, Popup 的 implicitWidth 直接随 contentImplicitWidth 变化。当 popupType 为 Popup.Window 时,QQuickPopupWindow::implicitWidthChanged() 无条件采用 popup->implicitWidth(),搜索过滤导致内容减少时窗口宽度跳变。 添加显式棘轮机制:Popup 打开后 implicitWidth/Height 只增不减。旧的绑定环 意外提供了此行为,本修复是无绑定环的等价替代。棘轮不再直接覆盖 implicitWidth/Height,而是通过 background(windowBlurComponent) 的隐式尺寸 (Popup 默认隐式尺寸的自然来源)保持最大值,且仅作用于 Popup.Window, Popup.Item 仍随内容动态缩放。 PMS: BUG-373823、BUG-373843 --- qt6/src/qml/Popup.qml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/qt6/src/qml/Popup.qml b/qt6/src/qml/Popup.qml index 6b861333..9a9ec139 100644 --- a/qt6/src/qml/Popup.qml +++ b/qt6/src/qml/Popup.qml @@ -17,8 +17,30 @@ T.Popup { property bool closeOnInactive: true readonly property bool active: parent && parent.Window.active - implicitWidth: DS.Style.control.implicitWidth(control) - implicitHeight: DS.Style.control.implicitHeight(control) + + // Sticky-max ratchet for Popup.Window: the popup's implicit size is by + // default derived from background + contentItem, so keeping the largest + // size during an open session is done via the background's implicit size + // (windowBlurComponent) rather than overriding implicitWidth/Height here. + // Content shrinking (e.g. search filtering) then no longer jumps the + // popup window smaller. Reset on aboutToShow for each open session. + property real _maxImplicitWidth: 0 + property real _maxImplicitHeight: 0 + + onAboutToShow: { + if (control.popupType === Popup.Window) { + control._maxImplicitWidth = control.implicitContentWidth + + control.leftPadding + control.rightPadding + control._maxImplicitHeight = control.implicitContentHeight + + control.topPadding + control.bottomPadding + } + } + onImplicitContentWidthChanged: if (control.popupType === Popup.Window) + control._maxImplicitWidth = Math.max(control._maxImplicitWidth, + control.implicitContentWidth + control.leftPadding + control.rightPadding) + onImplicitContentHeightChanged: if (control.popupType === Popup.Window) + control._maxImplicitHeight = Math.max(control._maxImplicitHeight, + control.implicitContentHeight + control.topPadding + control.bottomPadding) padding: DS.Style.popup.padding @@ -28,7 +50,10 @@ T.Popup { Component { id: windowBlurComponent - D.StyledBehindWindowBlur { } + D.StyledBehindWindowBlur { + implicitWidth: control._maxImplicitWidth + implicitHeight: control._maxImplicitHeight + } } Component {