Skip to content

feat: add cursor size scaling with system scale factor - #36

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
caixr23:master
Dec 4, 2025
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
caixr23:master

Conversation

@caixr23

@caixr23 caixr23 commented Dec 4, 2025 •

Copy link
Copy Markdown
Contributor

Added support for cursor size to scale proportionally with system scaling factor
Introduced a new base cursor size configuration item "gtk-cursor-theme- size-base"
Removed "gtk-cursor-theme-size" from excluded keys to allow dynamic updates
Cursor size is now calculated as base size multiplied by system scale factor
This ensures cursor size remains appropriately sized across different display scales

Log: Added cursor size scaling feature that adjusts cursor size based on system scaling factor

Influence:

  1. Test cursor size changes when adjusting system scaling factor
  2. Verify base cursor size configuration works correctly
  3. Check cursor size updates in real-time when scaling factor changes
  4. Test compatibility with existing cursor theme settings
  5. Verify cursor size calculation accuracy across different scaling factors

feat: 增加光标大小随系统缩放比例调整功能

添加了光标大小随系统缩放比例按比例调整的支持
引入了新的基础光标大小配置项"gtk-cursor-theme-size-base"
将"gtk-cursor-theme-size"从排除列表中移除以支持动态更新
光标大小现在计算为基础大小乘以系统缩放比例
确保光标在不同显示比例下保持合适的大小

Log: 新增光标大小缩放功能,根据系统缩放比例调整光标大小

Influence:

  1. 测试调整系统缩放比例时光标大小的变化
  2. 验证基础光标大小配置是否正确工作
  3. 检查缩放比例改变时光标大小的实时更新
  4. 测试与现有光标主题设置的兼容性
  5. 验证不同缩放比例下光标大小计算的准确性

PMS: STORY-39797

Summary by Sourcery

Adjust cursor handling to support scaling cursor size based on a configurable base size and the system scale factor.

New Features:

  • Support scaling GTK cursor theme size proportionally to the system scale factor using a configurable base size setting.

Enhancements:

  • Allow dynamic updates to GTK cursor theme name and size by removing them from the excluded DConfig keys and triggering X resource updates when they change.

@sourcery-ai

sourcery-ai Bot commented Dec 4, 2025

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Implements cursor size scaling based on the system scale factor by introducing a base cursor size setting, wiring it into the dconfig/xsettings flow, and ensuring gtk cursor theme size updates dynamically when scale or cursor settings change.

Sequence diagram for cursor size update on scale factor change

sequenceDiagram
    actor User
    participant DisplaySettingsUI
    participant XSettingsManager
    participant DConfig
    participant GTKEnvironment

    User->>DisplaySettingsUI: Change display scale
    DisplaySettingsUI->>XSettingsManager: setSingleScaleFactor(scale, emitSignal)
    activate XSettingsManager
    XSettingsManager->>DConfig: getValue(gtk-cursor-theme-size-base)
    DConfig-->>XSettingsManager: baseCursorSizeInt, ok
    XSettingsManager->>XSettingsManager: if !ok or baseCursorSizeInt < 0
    XSettingsManager->>XSettingsManager: baseCursorSizeInt = BASE_CURSORSIZE
    XSettingsManager->>XSettingsManager: cursorSize = int(baseCursorSizeInt * scale)
    XSettingsManager->>DConfig: setValue(dcKeyGtkCursorThemeSize, cursorSize)
    deactivate XSettingsManager

    DConfig-->>GTKEnvironment: gtk-cursor-theme-size changed
    GTKEnvironment->>GTKEnvironment: Recalculate and apply cursor size
Loading

Sequence diagram for DConfig cursor setting change handling

sequenceDiagram
    participant DConfig
    participant XSettingsManager
    participant XResources

    DConfig-->>XSettingsManager: handleDConfigChangedCb(key)
    activate XSettingsManager
    XSettingsManager->>XSettingsManager: if key in excludedkeys(xft-dpi, scale-factor, window-scale)
    XSettingsManager-->>DConfig: return (ignored)
    deactivate XSettingsManager

    DConfig-->>XSettingsManager: handleDConfigChangedCb(gtk-cursor-theme-name)
    activate XSettingsManager
    XSettingsManager->>XSettingsManager: key == gtk-cursor-theme-name
    XSettingsManager->>XResources: updateXResources()
    deactivate XSettingsManager

    DConfig-->>XSettingsManager: handleDConfigChangedCb(gtk-cursor-theme-size)
    activate XSettingsManager
    XSettingsManager->>XSettingsManager: key == gtk-cursor-theme-size
    XSettingsManager->>XResources: updateXResources()
    deactivate XSettingsManager

    DConfig-->>XSettingsManager: handleDConfigChangedCb(gtk-cursor-theme-size-base)
    activate XSettingsManager
    XSettingsManager->>DConfig: getValue(gtk-cursor-theme-size-base)
    DConfig-->>XSettingsManager: cursorSizeBase
    XSettingsManager->>DConfig: setValue(gtk-cursor-theme-size, cursorSizeBase)
    XSettingsManager-->>DConfig: return (no further processing)
    deactivate XSettingsManager
Loading

Updated class diagram for XSettingsManager cursor scaling logic

classDiagram
    class XSettingsManager {
        - DConfigSettings* m_settingDconfig
        - DconfInfoStore m_dconfInfos
        + void handleDConfigChangedCb(QString key)
        + void setSingleScaleFactor(double scale, bool emitSignal)
        + void setString(QString prop, QString v)
        + void setGSettingsByXProp(QString prop, XsValue value)
        + void updateXResources()
    }

    class DConfigSettings {
        + QVariant value(QString key)
        + int value(QString key, bool* ok)
        + void setValue(QString key, QVariant value)
    }

    class DconfInfoStore {
        + QSharedPointer~DconfInfo~ getByDconfKey(QString key)
    }

    class DconfInfo {
        + QString dconfKey
        + QString xsettingsKey
    }

    XSettingsManager --> DConfigSettings : uses m_settingDconfig
    XSettingsManager --> DconfInfoStore : uses m_dconfInfos
    DconfInfoStore --> DconfInfo : returns
Loading

File-Level Changes

Change Details Files
Enable dynamic cursor size updates from dconfig changes and base cursor size configuration.
  • Stopped treating the gtk cursor size setting as an excluded key so that changes propagate through the xsettings manager.
  • Updated the dconfig change handler to refresh X resources when either the cursor theme name or cursor size changes.
  • Added handling for the new base cursor size key to mirror its value into the actual gtk cursor size key.
src/plugin-qt/xsettings/impl/xsettingsmanager.cpp
Derive cursor size from a configurable base cursor size multiplied by the system scale factor.
  • Removed the previous fixed formula that computed cursor size solely from BASE_CURSORSIZE and scale.
  • Read the new gtk-cursor-theme-size-base setting when the scale factor changes and fall back to BASE_CURSORSIZE if it is invalid.
  • Wrote the computed cursor size (base * scale) into the gtk cursor theme size dconfig key whenever the effective window scale changes.
src/plugin-qt/xsettings/impl/xsettingsmanager.cpp
Define metadata/schema for the new base cursor size configuration key.
  • Extended the xsettings JSON metadata to describe the new gtk-cursor-theme-size-base key and ensure it participates correctly in settings propagation.
src/plugin-qt/xsettings/misc/org.deepin.XSettings.json

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 there - I've reviewed your changes - here's some feedback:

  • When handling gtk-cursor-theme-size-base in handleDConfigChangedCb, you update gtk-cursor-theme-size but don’t call updateXResources(), which may prevent the cursor size change from taking effect immediately; consider triggering the same refresh path as for gtk-cursor-theme-size updates.
  • In setSingleScaleFactor, the validation if (!ok || baseCursorSizeInt < 0) allows a base cursor size of 0, which will result in a cursor size of 0; consider treating non-positive values as invalid (e.g. <= 0) to fall back to BASE_CURSORSIZE.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When handling `gtk-cursor-theme-size-base` in `handleDConfigChangedCb`, you update `gtk-cursor-theme-size` but don’t call `updateXResources()`, which may prevent the cursor size change from taking effect immediately; consider triggering the same refresh path as for `gtk-cursor-theme-size` updates.
- In `setSingleScaleFactor`, the validation `if (!ok || baseCursorSizeInt < 0)` allows a base cursor size of 0, which will result in a cursor size of 0; consider treating non-positive values as invalid (e.g. `<= 0`) to fall back to `BASE_CURSORSIZE`.

## Individual Comments

### Comment 1
<location> `src/plugin-qt/xsettings/impl/xsettingsmanager.cpp:530-535` </location>
<code_context>
             m_settingDconfig->setValue(dcKeyWindowScale, windowScale);
         }
-
+        bool ok = false;
+        int baseCursorSizeInt = m_settingDconfig->value("gtk-cursor-theme-size-base").toInt(&ok);
+        if (!ok || baseCursorSizeInt < 0) {
+            baseCursorSizeInt = BASE_CURSORSIZE;
+        }
+        int cursorSize = static_cast<int>(baseCursorSizeInt * scale);
         m_settingDconfig->setValue(dcKeyGtkCursorThemeSize, cursorSize);
     }
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Allowing a base cursor size of 0 may unintentionally produce a zero-size cursor.

Because `baseCursorSizeInt == 0` passes the current check, `cursorSize` can be computed as 0 for normal `scale` values, which is likely undesirable and may break cursor visibility/layout. If `0` is not intended to be valid, treat it as invalid in the condition (e.g., `<= 0`) or otherwise explicitly guard against `0` before computing `cursorSize`.

```suggestion
        bool ok = false;
        int baseCursorSizeInt = m_settingDconfig->value("gtk-cursor-theme-size-base").toInt(&ok);
        // Treat non-positive values (including 0) as invalid to avoid producing an invisible cursor.
        if (!ok || baseCursorSizeInt <= 0) {
            baseCursorSizeInt = BASE_CURSORSIZE;
        }
        int cursorSize = static_cast<int>(baseCursorSizeInt * scale);
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/plugin-qt/xsettings/impl/xsettingsmanager.cpp
@caixr23
caixr23 requested a review from mhduiy December 4, 2025 09:07
Added support for cursor size to scale proportionally with system
scaling factor
Introduced a new base cursor size configuration item "gtk-cursor-theme-
size-base"
Removed "gtk-cursor-theme-size" from excluded keys to allow dynamic
updates
Cursor size is now calculated as base size multiplied by system scale
factor
This ensures cursor size remains appropriately sized across different
display scales

Log: Added cursor size scaling feature that adjusts cursor size based on
system scaling factor

Influence:
1. Test cursor size changes when adjusting system scaling factor
2. Verify base cursor size configuration works correctly
3. Check cursor size updates in real-time when scaling factor changes
4. Test compatibility with existing cursor theme settings
5. Verify cursor size calculation accuracy across different scaling
factors

feat: 增加光标大小随系统缩放比例调整功能

添加了光标大小随系统缩放比例按比例调整的支持
引入了新的基础光标大小配置项"gtk-cursor-theme-size-base"
将"gtk-cursor-theme-size"从排除列表中移除以支持动态更新
光标大小现在计算为基础大小乘以系统缩放比例
确保光标在不同显示比例下保持合适的大小

Log: 新增光标大小缩放功能,根据系统缩放比例调整光标大小

Influence:
1. 测试调整系统缩放比例时光标大小的变化
2. 验证基础光标大小配置是否正确工作
3. 检查缩放比例改变时光标大小的实时更新
4. 测试与现有光标主题设置的兼容性
5. 验证不同缩放比例下光标大小计算的准确性

PMS: STORY-39797
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

我来对这个代码变更进行详细审查:

  1. 语法逻辑分析:
  • 代码语法正确,没有明显的语法错误
  • 逻辑流程清晰,处理了光标主题大小的基础值和实际值的分离
  1. 代码质量改进建议:
    a) 变量命名:
  • baseCursorSizeInt 命名可以更简洁,建议改为 baseCursorSize
  • excludedkeys 应该使用驼峰命名法改为 excludedKeys

b) 常量定义:

  • 建议将 gtk-cursor-theme-size-base 这样的字符串常量定义为静态常量,便于维护
  • 示例:
static const QString DCONF_KEY_CURSOR_SIZE_BASE = "gtk-cursor-theme-size-base";
  1. 代码性能优化:
  • handleDConfigChangedCb 函数中的 excludedkeys.contains(key) 可以改用 QSet 来提升查找性能:
static const QSet<QString> excludedKeys = {"xft-dpi", "scale-factor", "window-scale"};
if (excludedKeys.contains(key)) {
    return;
}
  1. 代码安全建议:
    a) 错误处理:
  • 在 toInt() 转换时增加了错误检查,这是好的做法
  • 建议对 scale 参数也进行范围检查,防止异常值
if (scale <= 0 || scale > 10) {  // 设置合理的缩放范围
    return;
}

b) 数据验证:

  • baseCursorSizeInt 的检查逻辑很好,建议添加上限检查:
if (!ok || baseCursorSizeInt <= 0 || baseCursorSizeInt > 128) {  // 设置合理的上限
    baseCursorSizeInt = BASE_CURSORSIZE;
}
  1. 其他建议:
    a) 配置文件:
  • JSON 配置文件中的描述文本应该保持一致性,建议使用统一的描述格式
  • 建议为新添加的配置项添加版本号标记,便于后续维护

b) 代码注释:

  • 建议在 handleDConfigChangedCb 函数中添加注释,说明为什么这些键值需要特殊处理
  • 示例:
// 这些键值需要特殊处理,因为它们会影响系统UI的基本显示
static const QStringList excludedKeys = {"xft-dpi", "scale-factor", "window-scale"};
  1. 测试建议:
  • 建议添加单元测试来验证:
    • 基础光标大小为0或负数时的处理
    • 缩放因子为边界值时的行为
    • 配置值变更时的级联更新是否正确

这些改进建议主要关注代码的可维护性、性能和安全性。整体来说,这个变更实现了光标大小的基础值和实际值的分离,是一个合理的设计改进。

@mhduiy

mhduiy commented Dec 4, 2025

Copy link
Copy Markdown
Contributor

/forcemerge

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, mhduiy

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

@deepin-bot

deepin-bot Bot commented Dec 4, 2025

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit 40b5d4a into linuxdeepin:master Dec 4, 2025
7 of 8 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