Skip to content

fix: resolve custom shortcut conflicts during reset - #120

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/reset-custom-shortcut-conflicts
Aug 3, 2026
Merged

fix: resolve custom shortcut conflicts during reset#120
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/reset-custom-shortcut-conflicts

Conversation

@yixinshark

@yixinshark yixinshark commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • restore built-in shortcut defaults synchronously during Reset
  • remove conflicting runtime custom shortcut bindings transactionally
  • suppress delayed duplicate DConfig notifications during reset processing

Test plan

  • git diff --check
  • cmake --build build --target plugin-dde-shortcut -j2

Pms: BUG-372049

Summary by Sourcery

Ensure shortcut reset restores built-in defaults synchronously while resolving conflicts with runtime custom shortcuts and suppressing redundant configuration change processing.

Bug Fixes:

  • Clear runtime custom shortcut hotkeys that conflict with restored built-in defaults during reset.
  • Prevent delayed DConfig notifications from re-applying or resurrecting shortcut configurations while a reset transaction is in progress.

Enhancements:

  • Make resetHotkeys return the restored key configurations so reset logic can operate on them immediately.
  • Track reset-in-progress shortcut IDs to coordinate runtime state updates and config removal safely.

Restore built-in shortcut defaults synchronously during Reset.
- Read normalized DConfig defaults before processing delayed change signals.
- Remove conflicting hotkeys from runtime custom shortcuts transactionally.
- Suppress duplicate reset notifications while preserving removal handling.

在重置过程中同步恢复内置快捷键默认值。
- 在处理延迟变更信号前读取并规范化 DConfig 默认值。
- 以事务方式移除自定义快捷键中冲突的按键绑定。
- 在保留删除处理的同时抑制重复的重置通知。

Log: resolve custom shortcut conflicts during reset
Pms: BUG-372049
Change-Id: Id8454152aacee9b7af28ca0edefc4f6425362a68

@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

@sourcery-ai

sourcery-ai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

Reset now restores built-in shortcut defaults synchronously, then clears conflicting runtime custom shortcuts and suppresses duplicate DConfig-driven keyconfig updates during the reset transaction.

Sequence diagram for shortcut Reset flow with conflict resolution

sequenceDiagram
    actor User
    participant KeybindingManager
    participant KeyHandler as m_keyHandler
    participant ConfigLoader as m_loader
    participant CustomShortcutTransaction

    User->>KeybindingManager: Reset()
    KeybindingManager->>KeyHandler: commitSync()
    alt commitSync fails
        KeybindingManager-->>User: reset aborted
    else commitSync ok
        KeybindingManager->>ConfigLoader: resetHotkeys(resetIds)
        ConfigLoader-->>KeybindingManager: resetConfigs
        KeybindingManager->>KeybindingManager: normalizeHotkeys(resetConfigs.hotkeys)
        KeybindingManager->>CustomShortcutTransaction: clearConflictingHotkeys(this, restoredHotkeys)
        loop for each config in resetConfigs
            KeybindingManager->>KeybindingManager: onKeyConfigChanged(config)
        end
    end
Loading

File-Level Changes

Change Details Files
Introduce a transactional helper to remove custom shortcut hotkeys that conflict with newly restored built-in defaults.
  • Add static clearConflictingHotkeys method on CustomShortcutTransaction that scans runtime custom shortcuts and removes hotkeys overlapping a reserved set.
  • For each changed custom shortcut, apply runtime changes, persist modifications, and publish updates, with logging and early return on failures.
  • Update CustomShortcutTransaction class comment and include QSet for reserved hotkey handling.
src/plugin-qt/shortcut/src/core/customshortcuttransaction.cpp
src/plugin-qt/shortcut/src/core/customshortcuttransaction.h
Make Reset restore built-in hotkeys synchronously, track in-progress reset ids, resolve conflicts immediately, and reuse the normal DConfig change path without duplicate processing.
  • Change Reset to call ConfigLoader::resetHotkeys and receive the list of reset KeyConfig objects instead of performing a fire-and-forget reset.
  • Normalize restored hotkeys, accumulate them into a QSet, and call CustomShortcutTransaction::clearConflictingHotkeys to remove conflicting runtime custom bindings.
  • Introduce m_resetInProgressIds to track ids being reset, ensure onKeyConfigChanged ignores delayed DConfig notifications for those ids, and clean up this set as configs are processed or removed.
  • Adjust onKeyConfigChanged to normalize hotkeys on the loaded config, handle the add-on-change case, and guard against resurrecting configs deleted during nested event loops.
  • Ensure Reset commits unregistering existing hotkeys synchronously before restoring, and sequentially feeds reset configs back through onKeyConfigChanged while suppressing delayed signals.
src/plugin-qt/shortcut/src/core/keybindingmanager.cpp
src/plugin-qt/shortcut/src/core/keybindingmanager.h
Change ConfigLoader hotkey reset to return the restored key configs synchronously and validate reset behavior.
  • Modify ConfigLoader::resetHotkeys to return QList rather than void, capturing the configs whose hotkeys were reset.
  • After calling DConfig::reset("hotkeys"), immediately check that the value is at its default and log a warning when it is not.
  • Use reloadKeyConfig to reconstruct each reset KeyConfig and append it to the returned list.
  • Update the declaration in configloader.h and adjust comments to reflect synchronous reset and conflict handling by KeybindingManager.
  • Clarify resettableHotkeyIds comment about leaving runtime custom shortcuts alone and relying on KeybindingManager for conflict cleanup.
src/plugin-qt/shortcut/src/config/configloader.cpp
src/plugin-qt/shortcut/src/config/configloader.h

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

★ 总体评分:95分

■ 【总体评价】

代码通过同步返回重置配置和引入状态集合,有效修复了快捷键重置时的异步竞态问题。
逻辑正确且注释详尽,无安全漏洞,整体代码质量优秀。

■ 【详细分析】

  • 1.语法逻辑完全正确 ✓

ConfigLoader::resetHotkeys 修改为返回 QList<KeyConfig>,并在重置后立即调用 reloadKeyConfig 同步获取值。KeybindingManager::Reset 中通过遍历返回的配置集合并调用 clearConflictingHotkeys 解决冲突。引入 m_resetInProgressIds 集合在 onKeyConfigChangedonConfigRemoved 中进行状态判断,正确处理了异步信号与同步重置逻辑的竞态条件。
潜在问题:无
建议:无

  • 2.代码质量优秀 ✓

新增的注释非常详尽,如 "Do not resurrect a config deleted while commitSync() was running its nested event loop" 准确解释了为何要检查 m_resetInProgressIds.remove() 的返回值。变量命名如 m_resetInProgressIdsrestoredHotkeys 清晰表达了意图,代码结构清晰。
潜在问题:无
建议:无

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

重置操作属于低频用户行为,同步读取配置和遍历清理冲突带来的额外开销可忽略不计。代码中使用了 std::as_const 避免不必要的深拷贝,removeIf 使用了高效的谓词判断,整体性能良好。
潜在问题:无
建议:无

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码主要处理内部配置同步和状态管理,未涉及外部不可信输入的直接解析或命令执行,不存在注入或越权风险。

  • 建议:无需额外安全修复

■ 【改进建议代码示例】

// 当前代码逻辑已经非常完善,无需额外修复,以下为保持格式完整的原样代码片段展示
void KeybindingManager::Reset()
{
    // ... 前置代码 ...
    const QSet<QString> resetIdSet(resetIds.begin(), resetIds.end());
    m_resetInProgressIds.unite(resetIdSet);

    QSet<QString> restoredHotkeys;
    QList<KeyConfig> resetConfigs = m_loader->resetHotkeys(resetIds);
    for (KeyConfig &config : resetConfigs) {
        config.hotkeys = normalizeHotkeys(config.hotkeys);
        restoredHotkeys.unite(QSet<QString>(config.hotkeys.begin(), config.hotkeys.end()));
    }

    CustomShortcutTransaction::clearConflictingHotkeys(this, restoredHotkeys);

    for (const KeyConfig &config : std::as_const(resetConfigs)) {
        if (!m_resetInProgressIds.remove(config.getId()))
            continue;
        onKeyConfigChanged(config);
    }

    m_resetInProgressIds.subtract(resetIdSet);
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: robertkill, 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 Aug 3, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit dd4c8d6 into linuxdeepin:master Aug 3, 2026
9 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