Skip to content

fix(PasswordEdit): set dot size 6px, spacing 5px, left margin 8px - #731

Open
iCancely wants to merge 1 commit into
linuxdeepin:v25-flowstylefrom
iCancely:fix/password-dot-style
Open

iCancely wants to merge 1 commit into
linuxdeepin:v25-flowstylefrom
iCancely:fix/password-dot-style

Conversation

@iCancely

@iCancely iCancely commented Oct 21, 2026 •

Copy link
Copy Markdown

English

Adjust the masked password rendering in PasswordEdit while keeping Qt's native text input behavior.

Changes

  1. Added dotSize, dotSpacing, and dotLeftMargin style properties to the Qt6 FlowStyle
  2. Use Qt's native passwordCharacter rendering instead of a custom overlay
  3. Keep fontManager.t6 for the visible text font and font size, so the control follows the system font size
  4. Use Noto Mono for the compact hidden-mode dot glyph and calculate letterSpacing from TextMetrics
  5. Set the hidden-mode left padding to 8px and preserve native cursor, selection, scrolling, and RTL behavior

Verification

  • Built successfully with cmake --build build-dtk6-clean --target dtk6declarative -j8
  • QML lint target completed successfully with cmake --build build-dtk6-clean --target dtk6declarative_qmllint
  • Visually checked dot size, spacing, left margin, cursor placement, selection, and long-password scrolling in the Qt6 exhibition example

中文

调整 PasswordEdit 密码隐藏时的显示样式,同时保留 Qt 原生文本输入行为。

变更内容

  1. 在 Qt6 的 FlowStyle 中新增 dotSize、dotSpacing 和 dotLeftMargin 样式属性
  2. 使用 Qt 原生 passwordCharacter 绘制密码掩码,移除自定义覆盖层
  3. 明文显示继续使用 fontManager.t6 的字体和字号,因此控件会跟随系统字号变化
  4. 隐藏模式下使用 Noto Mono 的紧凑圆点字形,并通过 TextMetrics 计算 letterSpacing
  5. 隐藏模式左侧边距设置为 8px,并保留原生光标、选择、滚动和 RTL 行为

验证

  • 使用 cmake --build build-dtk6-clean --target dtk6declarative -j8 编译通过
  • 使用 cmake --build build-dtk6-clean --target dtk6declarative_qmllint 完成 QML lint 检查
  • 在 Qt6 exhibition 示例中检查了圆点大小、间距、左边距、光标位置、选择效果和长密码滚动

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: iCancely

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 Oct 21, 2026

Copy link
Copy Markdown

Reviewer's Guide

PasswordEdit now uses configurable 6px masked dots with 5px spacing and an 8px left margin, drawn in a cursor-anchored overlay that scrolls with long passwords while compensating font letter spacing to preserve cursor alignment; the implementation is mirrored for Qt5 and Qt6 and was verified by build, lint, and geometry checks.

Sequence diagram for cursor-aligned password dot rendering

sequenceDiagram
    participant PasswordEdit
    participant TextMetrics
    participant Repeater
    participant Cursor

    PasswordEdit->>TextMetrics: _updateSpaceAdvance()
    TextMetrics-->>PasswordEdit: advanceWidth
    PasswordEdit->>PasswordEdit: Set font.letterSpacing
    PasswordEdit->>Repeater: Create control.length dots
    Repeater->>Cursor: Read cursorRectangle.x and cursorPosition
    Cursor-->>Repeater: Cursor position and scroll offset
    Repeater-->>PasswordEdit: Render dots at 6px size and 11px advance
Loading

File-Level Changes

Change Details Files
Added configurable password-dot geometry to both Qt5 and Qt6 style definitions.
  • Defined 6px dot size, 5px dot spacing, and 8px left margin defaults.
qt6/src/qml/FlowStyle.qml
src/qml/FlowStyle.qml
Replaced the platform password mask rendering with a custom synchronized dot overlay.
  • Hide Qt's mask using a space character and render one styled circular rectangle per password character.
  • Anchor dot positions to the cursor and input padding so they follow horizontal scrolling.
  • Adjust font letter spacing using measured space width to keep the cursor aligned with the custom dot advance.
  • Update font metrics on initialization and deferred font changes.
qt6/src/qml/PasswordEdit.qml
src/qml/PasswordEdit.qml
Updated SPDX copyright ranges in the Qt5 source files.
  • Extended the copyright year range through 2026.
src/qml/FlowStyle.qml
src/qml/PasswordEdit.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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="qt6/src/qml/PasswordEdit.qml" line_range="74-76" />
<code_context>
+                y: (control.height - height) / 2
+
+                // Use the cursor as the visible anchor so long passwords
+                // scroll together with the dots.
+                x: DS.Style.passwordEdit.dotLeftMargin
+                  + control.cursorRectangle.x - control.leftPadding
+                  + (index - control.cursorPosition) * control._dotAdvance
+            }
</code_context>
<issue_to_address>
**Dots misalign with text**

When a caller uses centered or right-aligned text, or an RTL layout, the position formula assumes left-aligned LTR text: `cursorRectangle.x` can include an alignment offset, and the index offset always advances rightward. Dots therefore lose their margin or no longer align with their characters.

Position each dot using the text's actual alignment and direction as well as the cursor position.

Also at `src/qml/PasswordEdit.qml:75-77`, `qt6/src/qml/PasswordEdit.qml:77`.
</issue_to_address>

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

Comment thread qt6/src/qml/PasswordEdit.qml Outdated
@iCancely

Copy link
Copy Markdown
Author

@18202781743

@18202781743

Copy link
Copy Markdown
Contributor

对于qml文件的,只改qt6版本,

Comment thread qt6/src/qml/PasswordEdit.qml Outdated
@iCancely
iCancely force-pushed the fix/password-dot-style branch from f9f5cec to 2b158a2 Compare October 21, 2026 08:57
@iCancely

Copy link
Copy Markdown
Author

已处理:QML 只保留 Qt6 版本修改,Qt5 文件已从 diff 中移除。字体绑定也已改为 D.DTK.fontManager.t6,圆点位置使用 positionToRectangle(index) 处理对齐、方向和滚动。已基于最新 v25-flowstyle 重建,PR 仍保持 1 个 commit。

Comment thread qt6/src/qml/PasswordEdit.qml Outdated
Comment thread qt6/src/qml/PasswordEdit.qml Outdated
1. Add password dot style properties for dot pitch and left padding
2. Use Qt's native password mask rendering instead of a custom overlay
3. Keep the DTK t6 font size and use font metrics to set mask advance
4. Use Noto Mono only for the compact hidden password glyph

Log: Keep hidden password dots compact with consistent spacing
Influence: Password masking follows the design geometry without custom drawing

fix(PasswordEdit): 设置隐藏圆点规格

1. 增加密码圆点间距和左侧边距样式属性
2. 使用 Qt 原生密码掩码绘制,替代自定义覆盖层
3. 保留 DTK t6 字号,并通过字体度量设置掩码步进
4. 仅在隐藏密码时使用 Noto Mono 的紧凑圆点字形

Log: 保持密码隐藏圆点紧凑且间距一致
Influence: 密码掩码符合设计几何且无需自绘
@iCancely
iCancely force-pushed the fix/password-dot-style branch from 2b158a2 to 13742a1 Compare October 22, 2026 09:01
@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

🤖 AI 代码审查报告

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

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交修复 PasswordEdit 密码圆点显示样式,新增圆点大小、间距和左边距配置,代码结构清晰、语法正确、无安全漏洞。样式属性集中管理于 FlowStyle.qml,PasswordEdit.qml 通过 TextMetrics 精确计算字间距,实现合理且无性能问题。

🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

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

建议: []


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

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

建议: []


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

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

建议: []


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

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

建议: []


💡 改进建议代码示例


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

}

echoMode: TextInput.Password
passwordCharacter: "●"

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.

这个如果在平台主题里是否可以设置,
This is the character displayed when echoMode is set to Password or PasswordEchoOnEdit. By default it is the password character used by the platform theme.

@iCancely

Copy link
Copy Markdown
Author

感谢建议。关于 passwordCharacter 改由平台主题设置的可行性,做了一下分析:

passwordCharacter 控制的是用哪个字符做密码掩码,Qt 默认确实由平台主题提供。但本 PR 要解决的核心问题是圆点大小不符合设计要求(6px),而不是字符选择问题。

原因是:DTK t6 默认字体 Source Han Sans SC 中 ● (U+25CF) 的实际渲染直径约为 14.4px,远大于设计要求的 6px。即使通过平台主题把 passwordCharacter 设置好,只要字体仍是 t6 的默认字体,圆点依然会很大,无法达到目标尺寸。

因此当前方案需要三部分配合:

  1. passwordCharacter: "●" —— 使用 Qt 原生掩码字符,不自己绘制
  2. 隐藏态切换字体为 Noto Mono —— 该字体下 ● 渲染直径约 6.5px,接近设计要求
  3. 通过 TextMetrics 计算 letterSpacing —— 控制圆点间距为 5px

如果仅靠平台主题设置字符,只能改变用哪个字符,无法控制该字符在特定字体下的渲染大小。所以字体切换和间距计算仍然需要在 QML 层处理,否则圆点尺寸无法满足设计规范。

此外,font.pixelSize 始终绑定 D.DTK.fontManager.t6.pixelSize,因此圆点大小会跟随系统字号变化;font.family 仅在明文显示时使用 fontManager.t6.family,隐藏态才用 Noto Mono 的紧凑字形。

@18202781743

Copy link
Copy Markdown
Contributor

感谢建议。关于 passwordCharacter 改由平台主题设置的可行性,做了一下分析:

passwordCharacter 控制的是用哪个字符做密码掩码,Qt 默认确实由平台主题提供。但本 PR 要解决的核心问题是圆点大小不符合设计要求(6px),而不是字符选择问题。

原因是:DTK t6 默认字体 Source Han Sans SC 中 ● (U+25CF) 的实际渲染直径约为 14.4px,远大于设计要求的 6px。即使通过平台主题把 passwordCharacter 设置好,只要字体仍是 t6 的默认字体,圆点依然会很大,无法达到目标尺寸。

因此当前方案需要三部分配合:

  1. passwordCharacter: "●" —— 使用 Qt 原生掩码字符,不自己绘制
  2. 隐藏态切换字体为 Noto Mono —— 该字体下 ● 渲染直径约 6.5px,接近设计要求
  3. 通过 TextMetrics 计算 letterSpacing —— 控制圆点间距为 5px

如果仅靠平台主题设置字符,只能改变用哪个字符,无法控制该字符在特定字体下的渲染大小。所以字体切换和间距计算仍然需要在 QML 层处理,否则圆点尺寸无法满足设计规范。

此外,font.pixelSize 始终绑定 D.DTK.fontManager.t6.pixelSize,因此圆点大小会跟随系统字号变化;font.family 仅在明文显示时使用 fontManager.t6.family,隐藏态才用 Noto Mono 的紧凑字形。

结论

可以。QML TextInput.passwordCharacter 的默认值不是 Qt Quick 自己写死的,取值链路是:

TextInput 构造 → QStyleHints::passwordMaskCharacter() → QPlatformTheme::PasswordMaskCharacter → QPlatformIntegration → 默认值 U+25CF

对应源码:

  • /home/work/qt6-declarative-6.8.0+dfsg/src/quick/items/qquicktextinput_p_p.h:97
  • src/gui/kernel/qstylehints.cpp:494
  • src/gui/kernel/qplatformtheme.cpp:519
  • 默认字符 ● 在 src/gui/kernel/qplatformtheme.cpp:563

修改方式

在 deepin 平台主题里覆盖即可,不需要改 qt6-base 或 Qt Quick。当前 /home/work/qt5integration/platformthemeplugin/qdeepintheme.cpp:642 没有处理这个 hint,会一路回退到默认 U+25CF。增加一个 case:

QVariant QDeepinTheme::themeHint(QPlatformTheme::ThemeHint hint) const
{
switch (hint) {
case QPlatformTheme::PasswordMaskCharacter:
return QVariant(QChar(0x2022)); // 改成期望的字符,例如 • U+2022

// ...
default:
    break;
}

return QGenericUnixTheme::themeHint(hint);

}

如果想和 DTK Widget 风格保持一致,DTK 当前在 /home/work/dtkwidget/src/widgets/dstyle.cpp:2038 使用:

  • 字体支持时:U+26AB(⚫)
  • 否则:U+25CF(●)

也可以在平台主题里做同样的字体判断:

case QPlatformTheme::PasswordMaskCharacter: {
const QFontMetrics fm(QGuiApplication::font());
return QVariant(fm.inFont(QChar(0x26AB)) ? QChar(0x26AB) : QChar(0x25CF));
}

改完后重新编译安装平台主题插件,确认应用加载的是 deepin 主题,例如 QT_QPA_PLATFORMTHEME=deepin 或 -platformtheme deepin。

注意

  • QML 里显式设置了 passwordCharacter 时,平台主题不会覆盖它。
  • Qt Quick 只在 TextInput 构造时读取一次默认值;QStyleHints::passwordMaskCharacter 是 CONSTANT 属性,运行中修改平台主题不会刷新已经创建的对象,需要重新创建控件或重启应用。
  • 平台主题改的是默认值。DTK Widget 的 DStyle 自己覆盖了 SH_LineEdit_PasswordCharacter,所以如果希望 QML 和 Widget 表现完全一致,还需要同步调整 DStyle,或者去掉它的单独覆盖。

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