Skip to content

fix: report explicit shortcut capture outcomes - #144

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:refactor/simplify-shortcut-service
Aug 14, 2026
Merged

fix: report explicit shortcut capture outcomes#144
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
yixinshark:refactor/simplify-shortcut-service

Conversation

@yixinshark

@yixinshark yixinshark commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • report correlated X11 shortcut capture outcomes for success, invalid input, cancellation, and timeout
  • return the client capture ID with each terminal result so stale results can be ignored
  • treat Escape and pointer clicks as cancellation while reporting standalone invalid keys separately
  • retain the legacy BeginCapture(uint) overload for existing clients

Verification

  • built tst-x11grabresilientshortcuts
  • passed shortcut-x11grabresilientshortcuts

Pms: BUG-373653

@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

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 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

@sourcery-ai

sourcery-ai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors shortcut querying/validation and X11 event tracking into dedicated helper classes while extending the capture API to return structured per-request results (success/invalid/canceled/timeout) with tests and minor API cleanups for gesture and CLI controllers.

Sequence diagram for shortcut capture with per-request results

sequenceDiagram
    actor Client
    participant KeybindingManager
    participant AbstractKeyHandler
    participant X11KeyHandler

    Client->>KeybindingManager: BeginCapture(captureId, timeoutMs)
    KeybindingManager->>AbstractKeyHandler: beginCapture(captureId, timeoutMs, owner)
    AbstractKeyHandler->>X11KeyHandler: beginCapture(captureId, timeoutMs, owner)
    X11KeyHandler-->>KeybindingManager: captureStarted

    alt key_pressed_and_released
        X11KeyHandler-->>KeybindingManager: captureKeyEvent(pressed, keystroke)
        X11KeyHandler-->>KeybindingManager: captureKeyEvent(released, keystroke)
        alt Escape_or_pointer_cancel
            X11KeyHandler-->>KeybindingManager: captureResult(captureId, CaptureCanceled, keystroke)
        else valid_keystroke
            X11KeyHandler-->>KeybindingManager: captureResult(captureId, CaptureSuccess, keystroke)
        else invalid_keystroke
            X11KeyHandler-->>KeybindingManager: captureResult(captureId, CaptureInvalid, keystroke)
        end
    else timeout
        X11KeyHandler-->>KeybindingManager: captureResult(captureId, CaptureTimedOut, "")
    end

    KeybindingManager-->>Client: CaptureFinished(captureId, result, keystroke)
Loading

File-Level Changes

Change Details Files
Centralize shortcut normalization/validation and metadata/query logic into dedicated helper units, simplifying KeybindingManager.
  • Remove inline normalization/validation helpers from KeybindingManager and move them into ShortcutInputRules with a public API for hotkey/name/command validation and normalization.
  • Extract all shortcut listing/searching/category computation and ShortcutInfo/CategoryInfo construction into KeybindingManagerQuery and new ShortcutInfo/GestureInfo headers.
  • Update existing call sites (registerAllShortcuts, ModifyHotkeys, add/modify custom shortcuts, reset/rebuild configs, conflict checks) to use ShortcutInputRules and the new query helpers instead of local functions.
src/plugin-qt/shortcut/src/core/keybindingmanager.cpp
src/plugin-qt/shortcut/src/core/keybindingmanager.h
src/plugin-qt/shortcut/src/core/keybindingmanagerquery.cpp
src/plugin-qt/shortcut/src/core/shortcutinputrules.cpp
src/plugin-qt/shortcut/src/core/shortcutinputrules.h
src/plugin-qt/shortcut/src/core/shortcutinfo.h
src/plugin-qt/shortcut/src/core/gestureinfo.h
src/plugin-qt/shortcut/src/config/configloader.h
src/plugin-qt/shortcut/DEVELOPER_GUIDE.md
src/plugin-qt/shortcut/CMakeLists.txt
Introduce structured capture result reporting keyed by a client-provided captureId, while keeping the legacy BeginCapture overload.
  • Change AbstractKeyHandler::beginCapture to accept a captureId and add a CaptureResult enum plus captureResult signal.
  • Update KeybindingManager::BeginCapture to have both legacy (timeout only) and new (captureId, timeout) Q_SCRIPTABLE overloads, and forward captureId to the backend.
  • Connect AbstractKeyHandler::captureResult to KeybindingManager::onCaptureResult and emit a new CaptureFinished DBus signal carrying captureId, result code, and keystroke.
  • Update developer guide to document the new BeginCapture(captureId, timeoutMs) and CaptureFinished semantics and legacy id=0 behaviour.
src/plugin-qt/shortcut/src/backend/abstractkeyhandler.h
src/plugin-qt/shortcut/src/core/keybindingmanager.cpp
src/plugin-qt/shortcut/src/core/keybindingmanager.h
src/plugin-qt/shortcut/DEVELOPER_GUIDE.md
Simplify X11 shortcut capture and general key press tracking via X11KeyEventTracker, and emit explicit capture outcomes including timeout, cancel, invalid, and success.
  • Replace manual QMap-based pressed/pending/observed state in X11KeyHandler with X11KeyEventTracker for both XCB and RECORD paths, simplifying repeat and deferred release handling.
  • Extend CaptureState with captureId and candidate keystroke/validity; clear state reliably on finishCapture.
  • Update X11KeyHandler::beginCapture to reject concurrent captures, store captureId, reset trackers, and use the timer to emit CaptureTimedOut before finishing.
  • In handleXcbEvents, record candidate keystrokes, classify Escape or pointer click as cancellation, success for valid captured keys, and invalid otherwise, emitting captureResult before finishing.
  • Wire unregisterKey/clearPressedState to the new trackers and add X11KeyEventTracker tests to validate behaviour.
src/plugin-qt/shortcut/src/backend/x11/x11keyhandler.cpp
src/plugin-qt/shortcut/src/backend/x11/x11keyhandler.h
src/plugin-qt/shortcut/src/backend/x11/x11keyeventtracker.cpp
src/plugin-qt/shortcut/src/backend/x11/x11keyeventtracker.h
src/plugin-qt/shortcut/tests/tst_x11keyeventtracker.cpp
src/plugin-qt/shortcut/tests/tst_x11grabresilientshortcuts.cpp
Adjust tests and build configuration to cover the new helper components and capture reporting paths.
  • Add tst-shortcutinputrules to exercise normalization/validation/command parsing in ShortcutInputRules and wire it into CTest.
  • Add tst-x11keyeventtracker to cover X11KeyEventTracker press/repeat/release/clear/observedPress behaviours.
  • Extend tst-x11grabresilientshortcuts with tests for explicit capture outcomes, rejecting overlapping captures, timeout reporting, and EndCapture without result emission.
  • Disable building of the standalone dde-shortcut debug binary by default to keep build lean.
src/plugin-qt/shortcut/tests/CMakeLists.txt
src/plugin-qt/shortcut/tests/tst_shortcutinputrules.cpp
src/plugin-qt/shortcut/tests/tst_x11keyeventtracker.cpp
src/plugin-qt/shortcut/tests/tst_x11grabresilientshortcuts.cpp
src/plugin-qt/shortcut/CMakeLists.txt
Clean up gesture, translation, and CLI controller APIs by moving DBus types into headers and removing unused virtual methods/destructors.
  • Move GestureInfo and GestureActionInfo structs plus their QDBusArgument operators into gestureinfo.h; update GestureManager header to use them and add GetGestureAvailableActions while keeping the old misspelled alias.
  • Simplify TranslationManager by removing the onLocaleChanged slot and unused loadAppTranslations declaration.
  • Streamline ShortcutManager by dropping explicit destructor and DBus registration helpers, leaving it focused on component orchestration; remove unused includes.
  • Simplify BaseController and concrete controllers (audio/display/kbdlight/touchpad/launch/media/network/power/lockkey/wm) by removing name/supportedActions/actionHelp APIs and custom destructors now that controllers are created via factories.
  • Trim CommandParser to only support factory-based controller registration and remove unused controller-based register API and destructor.
  • Drop trivial destructors from Wayland gesture/key handlers that only relied on QObject parent cleanup.
src/plugin-qt/shortcut/src/core/gesturemanager.h
src/plugin-qt/shortcut/src/core/gesturemanager.cpp
src/plugin-qt/shortcut/src/core/shortcutmanager.cpp
src/plugin-qt/shortcut/src/core/shortcutmanager.h
src/plugin-qt/shortcut/src/core/translationmanager.cpp
src/plugin-qt/shortcut/src/core/translationmanager.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/basecontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/commandparser.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/commandparser.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/audiocontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/audiocontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/displaycontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/displaycontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/kbdlightcontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/kbdlightcontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/touchpadcontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/touchpadcontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/launchcontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/launchcontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/mediaplayercontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/mediaplayercontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/networkcontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/networkcontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/lockkeycontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/lockkeycontroller.h
src/plugin-qt/shortcut/tools/dde-shortcut-tool/wmcontroller.cpp
src/plugin-qt/shortcut/tools/dde-shortcut-tool/wmcontroller.h
src/plugin-qt/shortcut/src/backend/wayland/waylandgesturehandler.cpp
src/plugin-qt/shortcut/src/backend/wayland/waylandgesturehandler.h
src/plugin-qt/shortcut/src/backend/wayland/waylandkeyhandler.cpp
src/plugin-qt/shortcut/src/backend/wayland/waylandkeyhandler.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

@yixinshark
yixinshark force-pushed the refactor/simplify-shortcut-service branch from 5822bcf to b5b3763 Compare August 13, 2026 12:53
@yixinshark yixinshark changed the title refactor: simplify shortcut service and report capture outcomes fix: report explicit shortcut capture outcomes Aug 13, 2026
Report correlated X11 shortcut capture results to distinguish invalid input,
cancellation, timeout, and successful capture.
- Return the client capture ID with every terminal capture result.
- Treat Escape and pointer clicks as cancellation and invalid keys separately.
- Keep the legacy BeginCapture overload for existing clients.
- Cover success, invalid, canceled, timeout, and explicit end cases.

明确返回可关联的 X11 快捷键录入结果,以区分无效输入、取消、超时和成功。
- 每个终态结果都返回客户端录入 ID。
- 分别处理 Escape、鼠标取消和无效按键。
- 保留旧版 BeginCapture 重载以兼容现有客户端。
- 覆盖成功、无效、取消、超时和主动结束场景。

Log: fix: report explicit shortcut capture outcomes
Pms: BUG-373653
Change-Id: Ibb165871afcbf4611be4fcab530810f5f348be6a
@yixinshark
yixinshark force-pushed the refactor/simplify-shortcut-service branch from b5b3763 to cd41e71 Compare August 13, 2026 13:07
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:100分

■ 【总体评价】

代码实现了快捷键录入机制的重构,增加了明确的结果反馈与并发冲突防护,逻辑严谨且无安全漏洞
各维度均无扣分项,实现质量极高,测试覆盖充分

■ 【详细分析】

  • 1.语法逻辑 基本正确 ✓

代码在 abstractkeyhandler.h 中定义了标准的 CaptureResult 枚举,并在 x11keyhandler.cpphandleXcbEvents 中根据按键释放、鼠标点击和超时事件精准发射对应状态信号。状态机转换清晰,beginCapture 拒绝并发请求,finishCapture 彻底清理新增的 candidateKeystroke 等状态字段,测试用例完整覆盖了成功、取消、超时、无效按键及显式结束等分支。
建议:在 x11keyhandler.cpp 的鼠标点击释放分支中,emit captureResult 放在 finishCapture() 之前,与按键释放分支保持一致,当前逻辑正确,建议保持此顺序以防止信号携带已清空的数据。

  • 2.代码质量 良好 ✓

代码遵循了 Qt 和 D-Bus 的开发规范,抽象层与 X11 实现层分离清晰。KeybindingManager 通过重载 BeginCapture 保留了旧版 D-Bus 接口的兼容性,同时内部通过 onCaptureResult 槽函数优雅地转发信号。配套的单元测试新增了四个高质量的测试函数,验证了核心边界条件。
潜在问题:C++ 层面存在轻微的函数重载歧义风险,若本地代码调用 BeginCapture(0),编译器可能无法区分 uintquint64 重载。
建议:由于该接口主要供 D-Bus 远程调用,C++ 歧义影响有限,但若需本地调用,建议使用 BeginCapture(0, 30000) 显式指定参数。

  • 3.代码性能 高效 ✓

重构仅引入了极少量基础类型(quint64boolQString)的状态变量赋值与信号发射操作,无额外的内存分配、系统调用或轮询机制。finishCapture 中的状态清理操作时间复杂度为 O(1),对原有事件处理循环的性能无任何负面影响。
建议:无需优化。

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
本次重构移除了旧版 beginCapture 中允许同属主覆盖刷新超时的逻辑,改为直接拒绝活跃状态下的任何新录入请求,从根本上消除了因并发录入导致的状态混乱与潜在的竞态条件风险。captureId 作为无符号 64 位整数由客户端生成并原样返回,不涉及内存操作、指针解引用或命令拼接,无注入或越界风险。
建议:继续保持对 D-Bus 外部输入的严格校验,当前实现已足够安全。

■ 【改进建议代码示例】

// 建议示例:消除潜在的C++重载歧义,提升本地调用的健壮性
// 文件:src/plugin-qt/shortcut/src/core/keybindingmanager.h

// 修改前:
// Q_SCRIPTABLE bool BeginCapture(uint timeoutMs = 30000);
// Q_SCRIPTABLE bool BeginCapture(quint64 captureId, uint timeoutMs);

// 修改后:移除默认参数,强制调用方明确意图,避免隐式转换导致的歧义
Q_SCRIPTABLE bool BeginCapture(uint timeoutMs);
Q_SCRIPTABLE bool BeginCapture(quint64 captureId, uint timeoutMs);

// 文件:src/plugin-qt/shortcut/src/core/keybindingmanager.cpp

// 修改前:
// bool KeybindingManager::BeginCapture(uint timeoutMs)
// {
//     return BeginCapture(0, timeoutMs);
// }

// 修改后:
bool KeybindingManager::BeginCapture(uint timeoutMs)
{
    // 显式传递 0ULL 消除编译器警告或歧义
    return BeginCapture(0ULL, timeoutMs);
}

@yixinshark

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit 55009c0 into linuxdeepin:master Aug 14, 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.

2 participants