Skip to content

feat(keyboard): wire custom shortcut CRUD on Wayland#3346

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:feat/keyboard-wayland-custom-crud
Jul 8, 2026
Merged

feat(keyboard): wire custom shortcut CRUD on Wayland#3346
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:feat/keyboard-wayland-custom-crud

Conversation

@yixinshark

Copy link
Copy Markdown
Contributor

Wire the control center's add/modify/delete custom shortcut flows to the
new dde-services Keybinding1 custom CRUD methods on Wayland, replacing
the previous early-return stubs. Each Wayland call is observed with a
QDBusPendingCallWatcher so failures trigger refreshShortcut()/onAdded/
onShortcutChanged instead of mutating the local model optimistically.

Fetch a custom shortcut's command via the new GetShortcutCommand D-Bus
method: requestShortcutCommand fires one async call per custom shortcut
after ListAllShortcuts/SearchShortcuts/GetShortcut/ShortcutChanged, and
onGetShortcutCommandFinished overlays the Exec field onto the already-
built JSON object and re-emits shortcutQueried. The whole ShortcutInfo
JSON is stashed on the watcher so the handler needs no field-by-field
reconstruction.

ShortcutModel::onKeyBindingChanged now handles insert-on-change for new
ids arriving via ShortcutChanged: section-bearing configs are grouped
into m_groupInfos, sectionless Custom configs get the legacy "Custom"
group, and a dead unreachable tail (invalidateSystemShortcutNamesCache

  • addCustomInfo after two returning branches) is removed.

Extract KeyboardWorker::callModifyCustomShortcut() so the Wayland
modify path (modifyCustomShortcut and setNewCustomShortcut) shares one
watcher/id/type/connect setup. setNewCustomShortcut keeps the X11
fallback calling ModifyCustomShortcut directly, since on X11 it is also
invoked from onCustomConflictCleanFinished after conflict cleanup.

将控制中心自定义快捷键的增删改流程在 Wayland 下接入新的 dde-services
Keybinding1 自定义增删改方法,替换原先的提前 return 桩。每次 Wayland 调用
均用 QDBusPendingCallWatcher 观察结果,失败时触发 refreshShortcut()/
onAdded/onShortcutChanged,而不再乐观地修改本地模型。

通过新增的 GetShortcutCommand D-Bus 方法获取自定义快捷键命令:
requestShortcutCommand 在 ListAllShortcuts/SearchShortcuts/GetShortcut/
ShortcutChanged 之后对每个自定义快捷键发起一次异步调用,
onGetShortcutCommandFinished 将 Exec 字段叠加到已构建好的 JSON 对象上并
重新发射 shortcutQueried。整个 ShortcutInfo JSON 暂存在 watcher 上,处理
函数无需逐字段重建。

ShortcutModel::onKeyBindingChanged 现支持通过 ShortcutChanged 到达的新 id
的"变更即插入":带 Section 的配置归入 m_groupInfos,无 Section 的 Custom
配置归入传统"Custom"分组,并删除了两个 return 分支之后不可达的死代码尾段。

抽取 KeyboardWorker::callModifyCustomShortcut(),让 Wayland 修改路径
(modifyCustomShortcut 与 setNewCustomShortcut)共用一份 watcher/id/type/
connect 设置。setNewCustomShortcut 保留 X11 直接调用 ModifyCustomShortcut
的兜底,因为 X11 下它也会在冲突清理完成后由 onCustomConflictCleanFinished
调用。

Log: feat(keyboard): wire custom shortcut CRUD on Wayland
Change-Id: I793aa520968c92d03bb603721f00b1c7ac252fa5

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

Sorry @yixinshark, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Wire the control center's add/modify/delete custom shortcut flows to the
new dde-services Keybinding1 custom CRUD methods on Wayland, replacing
the previous early-return stubs. Each Wayland call is observed with a
QDBusPendingCallWatcher so failures trigger refreshShortcut()/onAdded/
onShortcutChanged instead of mutating the local model optimistically.

Fetch a custom shortcut's command via the new GetShortcutCommand D-Bus
method: requestShortcutCommand fires one async call per custom shortcut
after ListAllShortcuts/SearchShortcuts/GetShortcut/ShortcutChanged, and
onGetShortcutCommandFinished overlays the Exec field onto the already-
built JSON object and re-emits shortcutQueried. The whole ShortcutInfo
JSON is stashed on the watcher so the handler needs no field-by-field
reconstruction.

ShortcutModel::onKeyBindingChanged now handles insert-on-change for new
ids arriving via ShortcutChanged: section-bearing configs are grouped
into m_groupInfos, sectionless Custom configs get the legacy "Custom"
group, and a dead unreachable tail (invalidateSystemShortcutNamesCache
+ addCustomInfo after two returning branches) is removed.

Extract KeyboardWorker::callModifyCustomShortcut() so the Wayland
modify path (modifyCustomShortcut and setNewCustomShortcut) shares one
watcher/id/type/connect setup. setNewCustomShortcut keeps the X11
fallback calling ModifyCustomShortcut directly, since on X11 it is also
invoked from onCustomConflictCleanFinished after conflict cleanup.

将控制中心自定义快捷键的增删改流程在 Wayland 下接入新的 dde-services
Keybinding1 自定义增删改方法,替换原先的提前 return 桩。每次 Wayland 调用
均用 QDBusPendingCallWatcher 观察结果,失败时触发 refreshShortcut()/
onAdded/onShortcutChanged,而不再乐观地修改本地模型。

通过新增的 GetShortcutCommand D-Bus 方法获取自定义快捷键命令:
requestShortcutCommand 在 ListAllShortcuts/SearchShortcuts/GetShortcut/
ShortcutChanged 之后对每个自定义快捷键发起一次异步调用,
onGetShortcutCommandFinished 将 Exec 字段叠加到已构建好的 JSON 对象上并
重新发射 shortcutQueried。整个 ShortcutInfo JSON 暂存在 watcher 上,处理
函数无需逐字段重建。

ShortcutModel::onKeyBindingChanged 现支持通过 ShortcutChanged 到达的新 id
的"变更即插入":带 Section 的配置归入 m_groupInfos,无 Section 的 Custom
配置归入传统"Custom"分组,并删除了两个 return 分支之后不可达的死代码尾段。

抽取 KeyboardWorker::callModifyCustomShortcut(),让 Wayland 修改路径
(modifyCustomShortcut 与 setNewCustomShortcut)共用一份 watcher/id/type/
connect 设置。setNewCustomShortcut 保留 X11 直接调用 ModifyCustomShortcut
的兜底,因为 X11 下它也会在冲突清理完成后由 onCustomConflictCleanFinished
调用。

Log: feat(keyboard): wire custom shortcut CRUD on Wayland
Change-Id: I793aa520968c92d03bb603721f00b1c7ac252fa5
@yixinshark yixinshark force-pushed the feat/keyboard-wayland-custom-crud branch from b830d64 to b9e77e2 Compare July 8, 2026 08:53
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:78分

■ 【总体评价】

代码成功移除了Wayland下自定义快捷键的桩代码并实现了完整的异步CRUD流程,但存在未处理快捷键冲突的逻辑缺陷
逻辑正确性因Wayland修改分支缺少冲突清理而扣12分,代码质量因新增对象的内存管理隐患扣10分

■ 【详细分析】

  • 1.语法逻辑(存在错误)✕

在keyboardcontroller.cpp的modifyCustomShortcut函数中,X11分支在修改前会调用m_worker->onDisableShortcut(conflict)清理冲突的快捷键,但新增的Wayland分支直接调用了m_worker->modifyCustomShortcut(&updated)而跳过了冲突检测与清理逻辑。这会导致在Wayland下将自定义快捷键修改为系统已占用的快捷键时,产生按键冲突,触发非预期的系统行为。
潜在问题:Wayland下修改快捷键可能覆盖系统快捷键导致按键冲突;onKeyBindingChanged新增的insert分支中,当info->sectionKey不为空时未同步更新m_searchList,导致搜索结果可能与主列表不一致
建议:在Wayland分支中补充与X11一致的冲突检测逻辑,调用onDisableShortcut清理冲突;在insert分支补充对m_searchList的同步处理

  • 2.代码质量(良好)✓

代码抽取了callModifyCustomShortcut复用异步调用与回调逻辑,减少了重复代码。QML层通过pendingCommandId状态变量实现了良好的防重入与防抖机制,避免了对话框闪烁。但shortcutmodel.cpp的setSearchResult函数中,对包含Section字段的JSON对象直接new了ShortcutInfo并加入m_searchList,若m_searchList在清空时未执行qDeleteAll,会造成内存泄漏。
潜在问题:setSearchResult中新增的new ShortcutInfo对象可能存在内存泄漏隐患
建议:检查ShortcutModel中清空m_searchList的代码路径,确保使用qDeleteAll(m_searchList); m_searchList.clear();进行清理

  • 3.代码性能(无性能问题)✓

异步DBus调用采用QDBusPendingCallWatcher机制,不阻塞UI线程。Model层新增的遍历m_searchList进行更新以及setCategoryMeta中遍历m_customInfos的操作,由于系统快捷键和自定义快捷键数量级极小(通常在百个以内),O(N)及O(N^2)的时间复杂度在当前业务场景下不会产生性能瓶颈。
建议:无需优化

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码未引入命令注入、越权或缓冲区溢出等安全漏洞。用户输入的command字符串经过checkDesktopCmd处理后通过DBus传递给后端服务,前端仅作为配置管理器不直接执行系统命令,信任边界划分合理。JSON解析失败时会返回空对象并被update_id.isEmpty()拦截,不会引发异常。
建议:保持现有的输入传递与解析逻辑

■ 【改进建议代码示例】

// keyboardcontroller.cpp — modifyCustomShortcut:补充Wayland分支的冲突处理
void KeyboardController::modifyCustomShortcut(const QString &id, const QString &name, const QString &cmd, const QString &accels)
{
    ShortcutInfo *shortcut = m_shortcutModel->findInfoIf([id](ShortcutInfo *info){ return id == info->id; });
    if (!shortcut) {
        qWarning() << "shortcut not found..." << id << name;
        return;
    }

    if (m_worker->isWayland()) {
        // 补充:清理与目标快捷键冲突的现有快捷键
        if (auto conflict = m_shortcutModel->getInfo(accels)) {
            m_worker->onDisableShortcut(conflict);
        }

        ShortcutInfo updated = *shortcut;
        updated.name = name;
        updated.command = checkDesktopCmd(cmd);
        updated.accels = accels;
        m_worker->modifyCustomShortcut(&updated);
        return;
    }

    // Clear conflicting shortcuts when modifying
    if (auto conflict = m_shortcutModel->getInfo(accels)) {
        m_worker->onDisableShortcut(conflict);
    }

    // ... X11 原有逻辑 ...
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, yixinshark

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

@yixinshark

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 832a73f into linuxdeepin:master Jul 8, 2026
19 of 20 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