Skip to content

feat(shot): add rounded corner and size ratio widgets - #950

Merged
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
dengzhongyuan365-dev:newfeat-1012
Oct 12, 2026
Merged

deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
dengzhongyuan365-dev:newfeat-1012

Conversation

@dengzhongyuan365-dev

@dengzhongyuan365-dev dengzhongyuan365-dev commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

feat(shot): add rounded corner and size ratio widgets
Add rounded corner and size/ratio floating panels, icons and i18n.

新增圆角与尺寸/比例悬浮面板、图标及国际化文案。

Log: 新增圆角与尺寸比例设置面板
PMS: TASK-393987
Influence: 截图选区支持圆角预览及尺寸比例设置入口。

Summary by Sourcery

Add rounded-corner preview and size/aspect-ratio controls to the screenshot selection workflow.

New Features:

  • Add an on-selection floating control group for configuring rounded corners and capture size or aspect ratio.
  • Support live rounded-corner previews and apply rounded corners to standard and pinned screenshots.
  • Allow users to edit selection dimensions, lock aspect ratios during resizing, and remember a size or ratio for the next screenshot.

Bug Fixes:

  • Preserve rounded-corner appearance when saving to formats without alpha support by compositing transparent areas onto white.
  • Prevent Enter in size and radius editors from unintentionally triggering screenshot saving.
  • Improve selection border rendering and limit rounded-corner previews to the affected regions for smoother interaction.

Enhancements:

  • Persist rounded-corner, size, ratio, and remembered-selection settings across sessions with localized controls and themed icons.

Add rounded corner and size/ratio floating panels, icons and i18n.

新增圆角与尺寸/比例悬浮面板、图标及国际化文案。

Log: 新增圆角与尺寸比例设置面板
PMS: TASK-393987
Influence: 截图选区支持圆角预览及尺寸比例设置入口。
Integrate panel with selection, preview, ratio lock and image output.

将圆角与尺寸比例面板接入选区、比例锁定、预览和成图流程。

Log: 接入圆角与尺寸比例截图
PMS: TASK-393987
Influence: 截图和贴图支持圆角、固定尺寸、固定比例及下次启动记忆。
@sourcery-ai

sourcery-ai Bot commented Oct 12, 2026

Copy link
Copy Markdown

Sorry @dengzhongyuan365-dev, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Oct 12, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a selection-attached floating control widget for rounded-corner previews and editable size/aspect-ratio settings, persists those preferences, enforces ratio-aware resizing, and carries the rounded result through screenshot output with supporting icons and Chinese translations.

Sequence diagram for rounded screenshot capture

sequenceDiagram
    actor User
    participant MainWindow
    participant RoundedCornerWidget
    participant ScreenshotOutput

    User->>MainWindow: Select screenshot region
    MainWindow->>RoundedCornerWidget: followSelection(selection, screen)
    User->>RoundedCornerWidget: Change radius
    RoundedCornerWidget-->>MainWindow: radiusChanged(radius)
    MainWindow->>MainWindow: update(dirty)
    User->>MainWindow: Save screenshot
    MainWindow->>RoundedCornerWidget: applyRoundedCorners(pix, radius)
    MainWindow->>ScreenshotOutput: saveImg(savePix, fileName, format, quality)
Loading

Sequence diagram for ratio-aware selection resizing

sequenceDiagram
    actor User
    participant RoundedCornerWidget
    participant MainWindow

    User->>RoundedCornerWidget: Select Ratio mode
    User->>RoundedCornerWidget: Enable ratio lock
    User->>MainWindow: Drag selection edge
    MainWindow->>MainWindow: applyLockedRatioToSelection()
    MainWindow->>RoundedCornerWidget: setSelectionSize(width, height)
    User->>RoundedCornerWidget: Edit width or height
    RoundedCornerWidget-->>MainWindow: selectionSizeChanged(width, height)
    MainWindow->>MainWindow: onRoundedSelectionSizeChanged(width, height)
Loading

Entity relationship diagram for persisted rounded selection settings

erDiagram
    CONFIG_SETTINGS {
        string group
        string key
        variant value
    }
    ROUNDED_SETTINGS {
        int radius
        int ratio_type
        bool remember
        bool remember_ratio
        int fixed_width
        int fixed_height
    }
    CONFIG_SETTINGS ||--|| ROUNDED_SETTINGS : stores
Loading

File-Level Changes

Change Details Files
Add a floating rounded-corner and size/ratio control group to the screenshot selection UI.
  • Create a reusable widget with corner-radius slider/input and size-or-ratio editing panels.
  • Position the controls beside the selection with edge-aware expansion and hide/collapse them when the screenshot context changes.
  • Add themed icons, custom slider/button styling, accessibility names, and localized labels.
src/widgets/roundedcornerwidget.cpp
src/widgets/roundedcornerwidget.h
src/main_window.cpp
src/main_window.h
src/src.pro
assets/icons/icons.qrc
assets/icons/texts/corner-adjust_32px.svg
assets/icons/texts/corner-radius_32px.svg
assets/icons/texts/corner-sharp_32px.svg
assets/icons/texts/ratio-free_32px.svg
assets/icons/texts/ratio-lock_32px.svg
assets/icons/texts/ratio-unlock_32px.svg
assets/icons/texts/selection-fixed_32px.svg
assets/icons/texts/size-ratio_32px.svg
Integrate rounded-corner preview and final image rendering into screenshot capture and saving.
  • Preview rounded corners by repainting only the affected selection corners during radius changes.
  • Apply rounded transparency after annotations and cursor compositing for normal and pinned screenshots, while excluding OCR, recognition, and scrolling modes.
  • Composite alpha-containing output onto white for non-PNG formats to preserve the intended appearance.
src/main_window.cpp
src/widgets/roundedcornerwidget.cpp
src/widgets/roundedcornerwidget.h
Add editable fixed-size and locked-ratio selection behavior, including remembered settings.
  • Update the active selection from panel dimensions and constrain mouse/keyboard resizing to a captured aspect ratio when ratio locking is enabled.
  • Apply remembered dimensions or ratios to the first completed selection and clamp values to screen and minimum-size limits.
  • Persist radius, ratio mode, remember state, and fixed dimensions through the configuration settings.
src/main_window.cpp
src/widgets/roundedcornerwidget.cpp
src/widgets/roundedcornerwidget.h
src/utils/configsettings.cpp
Adjust screenshot interaction shortcuts and selection-frame rendering for the new controls.
  • Disable Return/Enter save shortcuts while a panel text editor has focus and clean up previously created save shortcuts during reinitialization.
  • Rework selection-frame bounds and antialiasing, including screen-edge clamping, to support the corner preview and improve visibility.
src/main_window.cpp
src/main_window.h
Register the new user-facing assets and translations.
  • Add Chinese simplified and traditional translations for radius, size/ratio, ratio locking, and remembered settings.
  • Register the new SVG toolbar and panel icons in the project resources.
translations/deepin-screen-recorder_zh_CN.ts
translations/deepin-screen-recorder_zh_HK.ts
translations/deepin-screen-recorder_zh_TW.ts
assets/icons/icons.qrc

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

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

AI 代码审查报告

项目: linuxdeepin/deepin-screen-recorder
PR: #950 feat(shot): add rounded corner and size ratio widgets
作者: dengzhongyuan365-dev
分支: newfeat-1012 → master
审查时间: 2026-10-12 11:09


总体评价

维度 评分 状态
语法逻辑 25/25 ✓
代码质量 21/25 ✓
代码性能 19/20 ✓
代码安全 30/30 ✓
总分 95/100 优秀

总体评价: 代码审查通过。未发现安全漏洞,代码结构清晰,注释详尽,性能优化到位。本次提交为截图选区新增圆角预览及尺寸比例设置功能,实现完整,逻辑严谨,边界处理完善。


漏洞统计

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个

统计项 数量
当前漏洞总数 0
新增漏洞 0
修复漏洞 0
持平漏洞 0
风险等级 None

修改文件清单

代码文件(5个,需分析):

  1. src/main_window.cpp — 主窗口集成圆角/尺寸比例工具组
  2. src/main_window.h — 新增成员变量和方法声明
  3. src/utils/configsettings.cpp — 新增 rounded 配置组
  4. src/widgets/roundedcornerwidget.cpp — 圆角/尺寸比例工具组实现(新增,1027行)
  5. src/widgets/roundedcornerwidget.h — 圆角/尺寸比例工具组头文件(新增,142行)

跳过文件(13个):

  • 8个 SVG 图标文件(assets/icons/texts/*.svg)
  • 1个 Qt 资源文件(assets/icons/icons.qrc)
  • 1个项目配置文件(src/src.pro)
  • 3个翻译文件(translations/*.ts)

维度1:语法逻辑(25/25)✓

语法正确,逻辑清晰,边界处理完善

审查内容

本次提交涉及主窗口集成和新组件开发,代码逻辑完整严谨。

主窗口集成(main_window.cpp):

  1. initAttributes() 中创建 RoundedCornerWidget 并连接信号,radiusChanged 信号处理中采用局部脏区域重绘策略,正确计算新旧半径影响范围
  2. isRoundedPanelEditorFocused() 正确使用 qobject_cast 判断焦点控件类型,遍历父控件链判断是否属于面板
  3. initSaveShortcut() 中先 delete 旧快捷方式再创建新的,避免残留 QShortcut 抢占回车,nullptr 初始值保证首次调用安全
  4. saveImg() 中对非 PNG 格式且有 Alpha 通道的图片进行白底合成,防止 JPEG/BMP 中出现黑角
  5. paintEvent() 中修正虚线框绘制位置(外移 1px 并夹取到窗口边界),圆角预览使用 QPainterPath.subtracted() 正确计算圆角外区域
  6. shotCurrentImg() 中调整操作顺序:圆角模式下先加光标再裁圆角再加投影,保证最终效果正确

新组件(roundedcornerwidget.cpp):

  1. RoundedSliderStyle 构造函数传 nullptr 给 QProxyStyle,正确避免应用样式被连带销毁的崩溃问题(注释详尽)
  2. 信号连接使用函数指针语法,类型安全;valueChanged 双向同步通过值比较防止无限循环
  3. applyRememberedSelectionSetting() 中 m_lockedRatio 赋值前 recordWidth 和 recordHeight 已通过 qBound 保证 ≥1,无除零风险
  4. applyLockedRatioToSelection() 中 m_lockedRatio <= 0.0 前置检查,dragRecordWidth/Height 通过 > 0 三元判断防止除零
  5. onRoundedSelectionSizeChanged() 中 pixelRatio 通过 > 0 ? ... : 1.0 保护

边界条件处理

  • 空选区:selection.isEmpty() 检查
  • 零尺寸:qMax(1, ...) 和 qBound(1, ...) 保护
  • 屏幕边缘:qBound 和 qMax 限制定位
  • DPR 为 0:> 0 ? ... : 1.0 三元保护
  • 空图片:source.isNull() 前置检查

维度2:代码质量(21/25)✓

代码结构清晰,注释完整

优点

  1. 注释质量优秀: 几乎每个非平凡决策都有详尽注释,包括设计稿参考、Qt 机制说明、崩溃风险规避(如 QProxyStyle 所有权注释)、性能优化原因(如防抖落盘注释解释 150ms QSettings::sync() 开销)
  2. 命名规范: 变量和方法命名清晰,m_radiusPreviewRadius、m_lockedRatio、m_pendingRememberedSetting 等命名准确表达意图
  3. Doxygen 文档: 公开方法有 @brief 文档注释
  4. 调试代码清理: 无残留调试代码,qCDebug 为标准 Qt 日志模式
  5. 封装合理: 匿名命名空间辅助函数良好封装,RoundedCornerWidget 类职责单一

问题

  1. 代码重复(-3分): m_widthEdit->editingFinished 和 m_heightEdit->editingFinished 信号处理逻辑几乎完全相同(约14行),仅锚定维度不同,可重构为共享方法 commitDimensionEdit(bool widthChanged):

    // 当前:两段几乎相同的代码
    connect(m_widthEdit, &DLineEdit::editingFinished, this, [this]() {
        // ... 14行逻辑,锚定 height
    });
    connect(m_heightEdit, &DLineEdit::editingFinished, this, [this]() {
        // ... 14行逻辑,锚定 width
    });
  2. 函数过长(-1分): initUi() 约123行(含 lambda 体),超出100行建议上限。虽然 lambda 信号连接膨胀了行数,但可考虑将宽/高编辑处理提取为独立方法


维度3:代码性能(19/20)✓

性能良好,资源使用合理

性能优化亮点

  1. 防抖落盘(-0分,优秀): m_persistTimer 设置 300ms 防抖,避免拖动滑块时频繁 QSettings::sync()(实测单次 150ms+),松手/输入完成/控件隐藏时立即落盘
  2. 局部重绘(-0分,优秀): radiusChanged 处理中仅计算四角脏区域 QRegion,避免整屏重绘(背景位图+蒙层),显著减少拖动滑块时的卡顿
  3. 值变化检查(-0分): persistRadius() 检查 m_persistedRadius == m_radius 避免无变化重复写入
  4. DPR 处理: applyRoundedCorners() 和 compositeOnWhite() 正确处理 devicePixelRatio,保证高分屏输出质量

问题

  1. 图标未缓存(-1分): SelectionLockButton::paintEvent 每次绘制都调用 tintedIcon() 创建新 QPixmap 进行着色合成。虽然图标仅 24x24,开销极小,但 paintEvent 可能频繁触发(hover/press 状态切换),可缓存着色后的图标:
    // 建议:在状态变化时缓存着色图标
    QIcon m_cachedActiveIcon;
    QIcon m_cachedNormalIcon;

维度4:代码安全(30/30)✓

存在0个安全漏洞

安全审查

  1. 输入校验: QIntValidator 限制宽高输入范围(1-99999/999),qBound 全面限制数值边界,m_radiusSpin->setRange(0, RADIUS_MAX) 限制半径范围
  2. 命令注入: 无 system()/exec()/popen() 调用,无 shell 命令拼接
  3. 路径遍历: 无文件路径拼接,文件操作使用已有 saveImg 路径
  4. 敏感信息: 无硬编码密钥/密码/Token,qCDebug 仅输出选区几何信息(非敏感)
  5. 缓冲区溢出: 使用 Qt 容器类(QString/QVector/QList),无原始指针数组操作
  6. 整数溢出: MAX_DIMENSION_VALUE=99999、MAX_RATIO_VALUE=999 乘法不会溢出 int(最大约21亿);比例计算使用 qreal(double)中间值,避免整数除法截断
  7. 资源管理: 所有 new 对象正确设置 Qt 父对象,QPainter 使用 save()/restore() 配对,无手动 malloc/free
  8. 拒绝服务: 防抖落盘和局部重绘优化防止 UI 冻结

改进建议

建议1:提取重复的编辑完成处理逻辑

// 重构建议:将 width/height editingFinished 提取为共享方法
void RoundedCornerWidget::commitDimensionEdit(bool widthChanged)
{
    if (m_syncingSelectionSize) {
        return;
    }
    const int maxValue = m_ratioLocked ? MAX_RATIO_VALUE : MAX_DIMENSION_VALUE;
    const int widthValue = qBound(1, m_widthEdit->text().toInt(), maxValue);
    const int heightValue = qBound(1, m_heightEdit->text().toInt(), maxValue);
    if (m_ratioLocked) {
        if (widthChanged) {
            const int anchorHeight = qMax(1, m_selectionHeight);
            m_selectionWidth = qMax(1, qRound(anchorHeight * static_cast<qreal>(widthValue) / heightValue));
            m_selectionHeight = anchorHeight;
        } else {
            const int anchorWidth = qMax(1, m_selectionWidth);
            m_selectionHeight = qMax(1, qRound(anchorWidth * static_cast<qreal>(heightValue) / widthValue));
            m_selectionWidth = anchorWidth;
        }
    } else {
        m_selectionWidth = widthValue;
        m_selectionHeight = heightValue;
    }
    updateDimensionFields();
    persistFixedSize();
    emit selectionSizeChanged(m_selectionWidth, m_selectionHeight);
}

建议2:缓存着色图标

// 在 SelectionLockButton 中缓存着色后的图标
class SelectionLockButton : public DIconButton
{
    // ...
private:
    QIcon m_cachedActiveIcon;
    QIcon m_cachedNormalIcon;
    void updateCachedIcons(const QColor &activeColor, const QColor &normalColor) {
        m_cachedActiveIcon = tintedIcon(icon(), iconSize(), activeColor);
        m_cachedNormalIcon = tintedIcon(icon(), iconSize(), normalColor);
    }
};

审查结论

本次提交为 deepin-screen-recorder 截图功能新增圆角预览及尺寸比例设置面板,代码质量优秀。提交目的明确(feat: 新增功能),实现与 commit message 描述一致。代码注释详尽,性能优化到位(防抖落盘、局部重绘),安全无漏洞。主要改进点为消除 editingFinished 处理器中的代码重复。建议合并。

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: dengzhongyuan365-dev, lzwind

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

@dengzhongyuan365-dev

Copy link
Copy Markdown
Member Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: unstable)

@deepin-bot
deepin-bot Bot merged commit 72f05ed into linuxdeepin:master Oct 12, 2026
6 of 7 checks passed
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