Skip to content

fix(palette): break windowText binding loops with resolved icon palette - #682

Closed
52cyb wants to merge 1 commit into
linuxdeepin:masterfrom
52cyb:master
Closed

52cyb wants to merge 1 commit into
linuxdeepin:masterfrom
52cyb:master

Conversation

@52cyb

@52cyb 52cyb commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor
  1. Remove state-dependent palette.windowText bindings from Button,
    MenuItem and ItemDelegate to avoid feeding ColorSelector output back
    into the control palette
  2. Build DciIcon.palette from the control palette and override its
    foreground with the resolved state color, keeping the control palette
    as a read-only input
  3. Make ItemDelegate text and indicator icons share the resolved
    DciIcon foreground without introducing additional properties
  4. Reuse the control's resolved DciIcon.palette in IconButton,
    WindowButton and ButtonIndicator instead of rebuilding it from the
    base control palette
  5. Preserve background, highlight and highlightForeground roles so
    future role-specific overrides can be propagated to child icons

Influence:

  1. Button, MenuItem and ItemDelegate no longer report binding loops for
    palette.windowText
  2. Checked and highlighted text and icons retain their state foreground
    colors
  3. Derived and indicator icons receive the same effective palette as
    their parent control
  4. Verify light/dark theme switching and checked, highlighted and
    disabled states

fix(palette): 使用解析后的图标调色板断开 windowText 绑定环

  1. 移除 Button、MenuItem 和 ItemDelegate 中依赖控件状态的
    palette.windowText 绑定,避免将 ColorSelector 输出回写到控件调色板
  2. 基于控件调色板构造 DciIcon.palette,并在其中覆盖已解析的状态前景色,
    使控件调色板保持为只读输入
  3. ItemDelegate 的文本和指示图标共用 DciIcon 的有效前景色,不引入额外属性
  4. IconButton、WindowButton 和 ButtonIndicator 复用控件已经解析的
    DciIcon.palette,不再从基础控件调色板重新构造
  5. 保留 background、highlight 和 highlightForeground 等角色,便于后续将
    各角色的独立覆盖统一传递给子图标

Influence:

  1. Button、MenuItem 和 ItemDelegate 不再报告 palette.windowText 绑定循环
  2. 选中和高亮状态下的文本、图标继续使用正确的状态前景色
  3. 派生图标和指示图标与父控件使用同一份有效调色板
  4. 验证亮暗主题切换以及选中、高亮和禁用状态

PMS: TASK-39241

Summary by Sourcery

Resolve control icon palettes independently from stateful control palette bindings to eliminate binding loops and keep text and icons visually consistent across interaction states.

Bug Fixes:

  • Prevent palette.windowText binding loops while preserving state-dependent text and icon foreground colors across buttons, menu items, and item delegates.

Enhancements:

  • Unify child and indicator icons around each control’s resolved icon palette while retaining other palette roles for future propagation.

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 52cyb

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR breaks palette.windowText binding loops by restoring its native inherited-foreground behavior, routing state colors directly to text and icon consumers, and adding an explicit icon-palette foreground helper. Review should verify binding-loop elimination, checked/hovered/pressed color correctness, and theme/accent responsiveness.

Sequence diagram for explicit state foreground resolution

sequenceDiagram
    participant Control
    participant ColorSelector
    participant DQMLGlobalObject
    participant DciIcon
    participant Text

    Control->>ColorSelector: textColor
    Control->>DQMLGlobalObject: makeIconPaletteWithForeground(palette, textColor)
    DQMLGlobalObject->>DQMLGlobalObject: makeIconPalette(palette)
    DQMLGlobalObject->>DciIcon: setForeground(textColor)
    Control->>Text: color = textColor
    Control->>DciIcon: palette = iconPalette
Loading

Flow diagram for restoring native windowText semantics

flowchart LR
    State["Control state changes"] --> Selector["D.ColorSelector resolves state foreground"]
    Selector --> Text["Text or Label reads state color directly"]
    Selector --> Icons["makeIconPaletteWithForeground sets icon foreground"]
    Palette["palette.windowText"] --> Native["Qt-native inherited general foreground"]
    Native --> Default["Normal-state default foreground"]
Loading

File-Level Changes

Change Details Files
Remove DTK state-color bindings from Qt palette.windowText so it retains inherited Qt foreground semantics and avoids binding loops.
  • Delete state-dependent windowText assignments and undefined resets across controls and dialogs.
  • Move state-color reads to text, Label, and content-item color properties.
  • Expose ItemDelegate.resolvedTextColor for checked/drag-aware text resolution.
qt6/src/qml/ActionButton.qml
qt6/src/qml/Button.qml
qt6/src/qml/ItemDelegate.qml
qt6/src/qml/LicenseDialog.qml
qt6/src/qml/MenuItem.qml
qt6/src/qml/NavigationTitle.qml
qt6/src/qml/SliderTipItem.qml
qt6/src/qml/SpinBoxIndicator.qml
qt6/src/qml/TitleBar.qml
qt6/src/qml/ToolButton.qml
qt6/src/qml/private/ArrowListViewButton.qml
qt6/src/qml/settings/NavigationTitle.qml
Make state-dependent icon foreground colors explicit instead of deriving them from palette.windowText.
  • Add makeIconPaletteWithForeground to clone an icon palette and override its foreground.
  • Update control, menu, delegate, title-bar, spin-box, action, indicator, and window-button icons to pass the resolved state foreground.
  • Preserve icon mode/theme handling while supplying highlighted, pressed, or inactive colors explicitly.
src/private/dqmlglobalobject.cpp
src/private/dqmlglobalobject_p.h
qt6/src/qml/ActionButton.qml
qt6/src/qml/Button.qml
qt6/src/qml/ButtonIndicator.qml
qt6/src/qml/IconButton.qml
qt6/src/qml/ItemDelegate.qml
qt6/src/qml/MenuItem.qml
qt6/src/qml/SpinBoxIndicator.qml
qt6/src/qml/TitleBar.qml
qt6/src/qml/ToolButton.qml
qt6/src/qml/WindowButton.qml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@52cyb
52cyb force-pushed the master branch 5 times, most recently from 4522a44 to aaa04b4 Compare September 10, 2026 07:40
@deepin-bot

deepin-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

TAG Bot

New tag: 6.7.49
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #685

Comment thread src/private/dqmlglobalobject_p.h Outdated
Q_INVOKABLE DTK_GUI_NAMESPACE::DDciIconPalette makeIconPalette(const QPalette &palette);
#else
Q_INVOKABLE DTK_GUI_NAMESPACE::DDciIconPalette makeIconPalette(const QQuickPalette *palette);
Q_INVOKABLE DTK_GUI_NAMESPACE::DDciIconPalette makeIconPaletteWithForeground(const QQuickPalette *palette, const QColor &foreground);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要是之后再有个背景色要设置咋整呀?

Comment thread qt6/src/qml/ItemDelegate.qml Outdated
property bool contentFlow
property Component content
property D.Palette checkedTextColor: DS.Style.checkedButton.text
readonly property color resolvedTextColor: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种应该不需要才对,不应该为了修这个问题而去引入,

@52cyb
52cyb force-pushed the master branch 4 times, most recently from 93367f3 to 6fc9108 Compare September 28, 2026 05:49
@52cyb 52cyb changed the title fix(palette): remove palette.windowText writes to break binding loop fix(palette): break windowText binding loops with resolved icon palette Sep 28, 2026
Comment thread qt6/src/qml/Button.qml
D.DciIcon.palette: D.DTK.makeIconPalette(palette)
palette.windowText: D.ColorSelector.textColor
D.DciIcon.palette: {
const iconPalette = D.DTK.makeIconPalette(control.palette)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不应该用const修饰吧,

}
name: "arrow_ordinary_down"
palette: control.D.DTK.makeIconPalette(control.palette)
palette: control.D.DciIcon.palette

@18202781743 18202781743 Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不需要用control.D.DciIcon.palette吧,用原来的D.DTK.makeIconPalette(control.palette)应该也可以吧,control不一定是Button,有附加属性DciIcon.palette的值吧,

Comment thread qt6/src/qml/Button.qml
D.DciIcon.theme: D.ColorSelector.controlTheme
D.DciIcon.palette: D.DTK.makeIconPalette(palette)
palette.windowText: D.ColorSelector.textColor
D.DciIcon.palette: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉这样改有点儿奇怪,这含义有点儿不同,D.DciIcon.palette针对的是dci图标的调色板,只对图标有效,
而palette.windowText针对的是qt的调色板,是通用的,
可能存在没有D.DciIcon.palette 但有palette.windowText的情况,

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 98 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 98 分,大于 70 分通过阈值。本次提交修复了 palette.windowText 绑定循环问题,代码逻辑正确,结构清晰,无安全漏洞,仅建议补充关键代码注释。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 语法正确,逻辑清晰,无需修改。建议在后续维护中保持 DciIcon.palette 构建模式的一致性。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. qt6/src/qml/Button.qml:26 - DciIcon.palette inline 函数缺少注释说明移除 palette.windowText 绑定的原因
  2. qt6/src/qml/MenuItem.qml:30 - DciIcon.palette inline 函数缺少注释说明移除 palette.windowText 绑定的原因
  3. qt6/src/qml/ItemDelegate.qml:48 - DciIcon.palette inline 函数缺少注释说明移除 palette.windowText 绑定的原因

建议: 建议在 DciIcon.palette 的 inline 函数中添加简要注释,说明移除 palette.windowText 绑定的原因(避免 ColorSelector 输出回写导致绑定循环),便于后续维护者理解。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 性能良好,资源使用合理。绑定循环修复和 palette 复用模式均对性能有正向影响。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 存在0个安全漏洞。本次变更为 QML UI 调色板逻辑修复,不涉及用户输入处理、网络操作、文件操作或敏感信息,无安全风险。


💡 改进建议代码示例

// 建议在 DciIcon.palette inline 函数中添加注释
D.DciIcon.palette: {
    // 从控件调色板构建图标调色板,直接覆盖前景色
    // 避免修改 palette.windowText 导致 ColorSelector 绑定循环
    const iconPalette = D.DTK.makeIconPalette(control.palette)
    iconPalette.foreground = control.D.ColorSelector.textColor
    return iconPalette
}

本报告由 AI 代码审查工具自动生成

@52cyb
52cyb marked this pull request as draft October 14, 2026 05:04
@deepin-bot

deepin-bot Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

TAG Bot

New tag: 6.7.51
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #723

1. Remove state-dependent palette.windowText bindings from Button,
 MenuItem and ItemDelegate to avoid feeding ColorSelector output back
 into the control palette
2. Build DciIcon.palette from the control palette and override its
 foreground with the resolved state color, keeping the control palette
 as a read-only input
3. Make ItemDelegate text and indicator icons share the resolved
 DciIcon foreground without introducing additional properties
4. Reuse the control's resolved DciIcon.palette in IconButton,
 WindowButton and ButtonIndicator instead of rebuilding it from the
 base control palette
5. Preserve background, highlight and highlightForeground roles so
 future role-specific overrides can be propagated to child icons

Influence:
1. Button, MenuItem and ItemDelegate no longer report binding loops for
 palette.windowText
2. Checked and highlighted text and icons retain their state foreground
 colors
3. Derived and indicator icons receive the same effective palette as
 their parent control
4. Verify light/dark theme switching and checked, highlighted and
 disabled states

fix(palette): 使用解析后的图标调色板断开 windowText 绑定环

1. 移除 Button、MenuItem 和 ItemDelegate 中依赖控件状态的
 palette.windowText 绑定,避免将 ColorSelector 输出回写到控件调色板
2. 基于控件调色板构造 DciIcon.palette,并在其中覆盖已解析的状态前景色,
 使控件调色板保持为只读输入
3. ItemDelegate 的文本和指示图标共用 DciIcon 的有效前景色,不引入额外属性
4. IconButton、WindowButton 和 ButtonIndicator 复用控件已经解析的
 DciIcon.palette,不再从基础控件调色板重新构造
5. 保留 background、highlight 和 highlightForeground 等角色,便于后续将
 各角色的独立覆盖统一传递给子图标

Influence:
1. Button、MenuItem 和 ItemDelegate 不再报告 palette.windowText 绑定循环
2. 选中和高亮状态下的文本、图标继续使用正确的状态前景色
3. 派生图标和指示图标与父控件使用同一份有效调色板
4. 验证亮暗主题切换以及选中、高亮和禁用状态

PMS: TASK-39241
@18202781743

Copy link
Copy Markdown
Contributor

#729

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants