From 0064daf4ee25f4cac0ded1fb9826b4408c76d8b7 Mon Sep 17 00:00:00 2001 From: Ivy233 Date: Sun, 4 Oct 2026 21:16:41 +0800 Subject: [PATCH] fix: handle typed colors without a control ancestor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DQuickControlColorSelector::getColorOf() left the color invalid when a typed color (e.g. D.Color.Highlight used by HighlightPanel's backgroundColor) was resolved without any QQuickControl ancestor -- popup/window contexts such as Menu/ArrowListView highlights, or a window-level attached selector. The default-constructed invalid QColor has alpha 255, so HighlightPanel rendered as an opaque black block, and every read of the property printed "ColorSelector: The ... is an invalid color on ...". Fall back to DGuiApplicationHelper::standardPalette() of the current theme, consistent with the inactive-blend branch just below. Verified with a minimal QML scene (HighlightPanel under a plain Item): before, 5 warnings and backgroundColor invalid (#000000); after, no warning and a valid highlight color (#024cca). Also wrap the ListView.highlight HighlightPanel in a Control in the Qt6 Menu/ArrowListView components (qt6/src/qml/Menu.qml and qt6/src/qml/ArrowListView.qml). This gives dtk's own highlight the QQuickControl ancestor that ColorSelector expects, without changing the highlight geometry or z-order. The standard-palette fallback above still covers other control-less contexts (standalone HighlightPanel, window-level selectors). 修复:无 Control 祖先时类型化颜色回退到标准调色板 DQuickControlColorSelector::getColorOf() 在类型化颜色(如 HighlightPanel 的 backgroundColor 使用的 D.Color.Highlight)于无 QQuickControl 祖先的上下文(Menu/ArrowListView 高亮等 popup/window 场景,或窗口级附加 selector)解析时返回无效颜色。默认构造的无效 QColor alpha 为 255,导致 HighlightPanel 被画成不透明黑块,且每次 读取属性都打印 "ColorSelector: The ... is an invalid color on ..."。 回退到当前主题的 DGuiApplicationHelper::standardPalette(),与下方 inactive 混色分支保持一致。已用最小 QML 场景(HighlightPanel 挂在 纯 Item 下)验证:修复前 5 条告警且 backgroundColor 无效(#000000), 修复后无告警且返回有效高亮色(#024cca)。 同时将 Qt6 Menu/ArrowListView 的 ListView.highlight 用 Control 包裹 (qt6/src/qml/Menu.qml、qt6/src/qml/ArrowListView.qml),为 HighlightPanel 提供 ColorSelector 期望的 QQuickControl 祖先,不改变 高亮的几何与 z 序;上述标准调色板回退继续覆盖其他无 Control 场景 (独立 HighlightPanel、窗口级 selector)。 PMS: TASK-394335 --- qt6/src/qml/ArrowListView.qml | 12 +++++++++--- qt6/src/qml/Menu.qml | 16 +++++++++++----- src/private/dquickcontrolpalette.cpp | 5 +++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/qt6/src/qml/ArrowListView.qml b/qt6/src/qml/ArrowListView.qml index eb7c880c2..e3f764fe4 100644 --- a/qt6/src/qml/ArrowListView.qml +++ b/qt6/src/qml/ArrowListView.qml @@ -60,10 +60,9 @@ FocusScope { } interactive: itemsView.count > maxVisibleItems ScrollIndicator.vertical: ScrollIndicator { } - highlight: HighlightPanel { + highlight: Control { visible: false // TODO listview's highlight is confict with Item's highlight. - outerShadowColor: null - innerShadowColor: null + hoverEnabled: false scale: D.DTK.hasAnimation ? 0.9 : 1.0 Component.onCompleted: { scale = 1.0 @@ -71,6 +70,13 @@ FocusScope { Behavior on scale { NumberAnimation { duration: 100 } } + + // Keep the highlight panel under a Control so that its + // ColorSelector can resolve typed colors (e.g. D.Color.Highlight). + contentItem: HighlightPanel { + outerShadowColor: null + innerShadowColor: null + } } highlightFollowsCurrentItem: true highlightMoveDuration: -1 diff --git a/qt6/src/qml/Menu.qml b/qt6/src/qml/Menu.qml index b3a07729b..885498602 100644 --- a/qt6/src/qml/Menu.qml +++ b/qt6/src/qml/Menu.qml @@ -68,24 +68,30 @@ T.Menu { view.highlightMoveDuration: 50 view.highlightMoveVelocity: -1 - view.highlight: HighlightPanel { - id: highlightRect + view.highlight: Control { visible: false // TODO listview's highlight is confict with Item's highlight. + hoverEnabled: false anchors.left: parent ? parent.left : undefined anchors.right: parent ? parent.right : undefined anchors.leftMargin: 0 anchors.rightMargin: 0 scale: D.DTK.hasAnimation ? 0.9 : 1.0 - radius: DS.Style.menu.item.radius - outerShadowColor: null - innerShadowColor: null Component.onCompleted: { scale = 1.0 } Behavior on scale { NumberAnimation { duration: 100 } } + + // Keep the highlight panel under a Control so that its + // ColorSelector can resolve typed colors (e.g. D.Color.Highlight). + contentItem: HighlightPanel { + id: highlightRect + radius: DS.Style.menu.item.radius + outerShadowColor: null + innerShadowColor: null + } } } Loader { diff --git a/src/private/dquickcontrolpalette.cpp b/src/private/dquickcontrolpalette.cpp index a8ea3dcc0..a1ee2bc58 100644 --- a/src/private/dquickcontrolpalette.cpp +++ b/src/private/dquickcontrolpalette.cpp @@ -840,6 +840,11 @@ QColor DQuickControlColorSelector::getColorOf(const DQuickControlPalette *palett if (targetColor.isTypedColor()) { if (m_control) colorValue = targetColor.toColor(_d_getControlPalette(m_control)); + else + // no control in the parent chain (e.g. popup/window context): + // fall back to the application-wide standard palette instead of + // returning an invalid color + colorValue = targetColor.toColor(DGuiApplicationHelper::standardPalette(state->controlTheme)); } else { colorValue = targetColor.color(); }