Skip to content

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

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

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

@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.

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

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

🤖 AI 代码审查报告

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

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 100 分,大于 70 分通过阈值,代码质量符合要求。本次提交修复了 QML 控件中 palette.windowText 绑定环问题,方案合理,实现清晰,未引入安全漏洞。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

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

建议: 代码语法正确,逻辑清晰。修复方案通过移除 palette.windowText 写入操作并引入 makeIconPaletteWithForeground 函数显式传递前景色,有效断开了绑定环。ItemDelegate.qml 中新增的 resolvedTextColor 只读属性正确保留了原有的选中态文字颜色逻辑。C++ 函数 makeIconPaletteWithForeground 复用 makeIconPalette 后通过 foreground.isValid() 条件判断设置前景色,逻辑严谨。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

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

建议: 代码质量优秀。新增的 C++ 函数 makeIconPaletteWithForeground 有清晰的中文注释说明用途,函数命名语义明确。QML 中 resolvedTextColor 属性命名为只读属性,命名规范。所有 6 个 QML 文件的修改保持一致的替换模式(makeIconPalette → makeIconPaletteWithForeground),代码风格统一。无重复代码,无残留调试信息。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

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

建议: 性能表现良好。makeIconPaletteWithForeground 函数先调用 makeIconPalette 再设置前景色,仅增加一次条件判断和一次 setForeground 调用,开销极小。移除绑定环实际上消除了 QML 引擎对 palette.windowText 的反复求值,提升了运行时性能。resolvedTextColor 作为只读属性绑定,仅在依赖属性变化时重新求值,符合 QML 最佳实践。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

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

建议: 本次变更未涉及用户输入处理、网络通信、文件操作等安全敏感场景。C++ 函数中对 QColor 参数进行了 isValid() 校验,体现了良好的防御性编程习惯。无安全漏洞。


💡 改进建议代码示例

// 本次提交为 Bug 修复,代码实现正确,无需修改
// makeIconPaletteWithForeground 实现简洁高效:
DDciIconPalette DQMLGlobalObject::makeIconPaletteWithForeground(const QQuickPalette *palette, const QColor &foreground)
{
    DDciIconPalette iconPalette = makeIconPalette(palette);
    if (foreground.isValid())
        iconPalette.setForeground(foreground);
    return iconPalette;
}

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

@52cyb
52cyb force-pushed the master branch 2 times, most recently from 22f0873 to 93367f3 Compare September 28, 2026 05:28
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
@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的情况,

This branch has not been deployed

No deployments
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