Skip to content

fix: adapt shortcuts to the Treeland v3 protocol - #205

Open
yixinshark wants to merge 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/treeland-shortcut-v3
Open

yixinshark wants to merge 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/treeland-shortcut-v3

Conversation

@yixinshark

@yixinshark yixinshark commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Treeland now exposes only treeland_shortcut_manager_v3, which prevents the v2 client from registering shortcuts. Its renumbered actions also require translating the service's existing configuration IDs before sending requests.

Switch the generated bindings to v3 while preserving saved configuration and D-Bus action IDs. Replace commit acknowledgements with flush/display sync, handle individual and deferred failures, clean partial registrations, and restore old bindings when edits fail. Enable the implemented tiling, minimize and workspace-move actions, document the lifecycle, and add protocol regression tests with the required qt6-wayland <!nocheck> dependency.

Validation:

  • Built the shortcut plugin and debug executable; all 13 shortcut CTest suites passed, including private Wayland and isolated Xvfb tests.
  • On a remote Deepin 25 / Treeland 0.11.0.18 session, verified command execution, hotkey updates/removal, failure cleanup, gesture registration, window maximize/restore/tiling, and manager reacquisition.
  • A windowless startup registered 90 key bindings and 10 gestures with no protocol failures, then explicitly removed all 100 bindings.
  • Confirmed the Debian dependency is included for normal builds and excluded by the nocheck profile.

Physical touchpad input and real user-session switching were not exercised. The full repository configure was blocked locally by the unrelated power module's missing xscrnsaver dependency; the shortcut targets were built through a temporary CMake entry point.

Pms: TASK-397267

Summary by Sourcery

Adapt the shortcut backend to Treeland's v3 protocol while preserving compatibility with existing configurations and making registration failures recoverable.

New Features:

  • Support Treeland's v3 shortcut manager for key and gesture registrations, including newly available tiling, minimization, and workspace-movement actions.

Bug Fixes:

  • Preserve stable configuration and D-Bus action IDs while translating them to Treeland v3 protocol values.
  • Ensure shortcut requests are flushed and synchronized reliably, including handling immediate and deferred registration failures.
  • Clean up partial registrations and restore previous key or gesture bindings when updates fail.

Enhancements:

  • Use unique runtime binding names and track protocol lifecycle changes to safely handle session recovery and late failures.
  • Document Treeland v3 registration semantics, supported actions, and backend behavior.

Build:

  • Require Treeland protocols 0.6.0 and generate client bindings from the unstable v3 protocol.
  • Add the Debian build dependency needed for Wayland protocol testing, honoring the nocheck profile.

Documentation:

  • Update the shortcut developer guide for Treeland v3 protocol behavior, action translation, synchronization, and supported modifiers.

Tests:

  • Add protocol regression coverage for v3 registration, action mapping, activation, failure cleanup, deferred failures, replacement safety, and rollback behavior.

Treeland now exposes shortcut-manager v3, so the v2 client cannot register
shortcuts and legacy action IDs must no longer be sent as protocol values.

Generate v3 bindings and preserve configuration and D-Bus action IDs through
an explicit mapping. Replace commit acknowledgements with flush/display sync,
handle individual and deferred binding failures, clear partial registrations,
and restore old bindings when edits fail. Enable the implemented tiling,
minimize and workspace-move actions, and keep unsupported actions unregistered.
Add protocol regression coverage, declare the Qt Wayland test runtime package,
and document the new lifecycle. The 13 shortcut test suites and six live
Treeland scenarios passed; bulk startup registered and cleaned 100 bindings.

Treeland 已改为提供 shortcut-manager v3,旧版客户端无法注册快捷键,
原有业务动作 ID 也不能再直接作为协议枚举发送。

切换到 v3 生成代码,通过显式映射保留配置和 D-Bus 动作 ID。
使用 flush/display sync 替代提交确认,处理逐条及延迟注册失败,
清理部分成功的绑定,并在修改失败时恢复旧绑定。启用已实现的平铺、
最小化和移动到相邻工作区动作,继续拒绝尚不支持的动作。
补充协议回归测试、Qt Wayland 测试运行依赖及生命周期文档。
13 组快捷键测试和 6 个真实 Treeland 场景通过,批量启动完成了
100 条绑定的注册和清理。

Log: adapt shortcuts to the Treeland v3 protocol
Pms: TASK-397267
Change-Id: I9c2eb32345ee7003cac893449dc414309fbee347
@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 Oct 27, 2026

Copy link
Copy Markdown

Reviewer's Guide

Migrates shortcut registration to Treeland's v3 protocol, translating stable action IDs and replacing transactional commits with flush/sync plus failure compensation, while adding lifecycle documentation and comprehensive protocol regression tests.

Sequence diagram for Treeland v3 shortcut registration and failure handling

sequenceDiagram
    participant Manager as ShortcutManager
    participant Handler as WaylandKeyHandler
    participant Wrapper as TreelandShortcutWrapper
    participant Treeland as TreelandV3

    Manager->>Handler: registerKey(config)
    Handler->>Wrapper: bind_key(name, key, flags, action)
    Handler->>Wrapper: flushDeferred()
    Wrapper->>Treeland: bind_key()
    Wrapper->>Treeland: wl_display_flush()
    Manager->>Handler: commitSync()
    Handler->>Wrapper: syncAndWait()
    Wrapper->>Treeland: wl_display_sync()
    alt bind succeeds
        Treeland-->>Wrapper: sync callback
        Wrapper-->>Handler: true
    else bind_failure
        Treeland-->>Wrapper: bind_failure(name, error)
        Wrapper-->>Handler: bindFailed(name, error)
        Handler->>Wrapper: unbind(name)
        Handler-->>Manager: registrationFailed(id)
    end
Loading

Sequence diagram for compensating a failed shortcut edit

sequenceDiagram
    participant Client as ShortcutManager
    participant Handler as WaylandKeyHandler
    participant Wrapper as TreelandShortcutWrapper
    participant Treeland as TreelandV3

    Client->>Handler: unregisterShortcut(id)
    Handler->>Wrapper: unbind(oldName)
    Client->>Handler: registerKey(newConfig)
    Handler->>Wrapper: bind_key(newName, key, flags, action)
    Client->>Handler: commitSync()
    Handler->>Wrapper: syncAndWait()
    Wrapper->>Treeland: wl_display_sync()
    Treeland-->>Wrapper: bind_failure(newName, error)
    Wrapper-->>Handler: bindFailed(newName, error)
    Handler->>Wrapper: unbind(newName)
    Client->>Handler: registerKey(oldConfig)
    Handler->>Wrapper: bind_key(oldName, key, flags, action)
    Handler->>Wrapper: flushDeferred()
Loading

Flow diagram for stable action ID translation to Treeland v3

flowchart LR
    Config["Saved configuration action ID"] --> Catalog["TriggerActionCatalog"]
    Catalog -->|treelandActionId| Wire["Treeland v3 action ID"]
    Wire --> Bind["bind_key or bind_swipe_gesture"]
    Catalog -->|unsupported or disabled| Skip["No protocol binding"]
Loading

File-Level Changes

Change Details Files
Migrates the Wayland shortcut client from Treeland protocol v2 to unstable v3 while preserving stable service-facing action and configuration identifiers.
  • Generates and uses the v3 protocol bindings with the required protocol package version.
  • Translates stable action IDs to v3 wire values, including newly supported tiling, minimize, and workspace-move actions.
  • Keeps configuration and D-Bus IDs independent from protocol enum renumbering and assigns unique wire names for replacement safety.
debian/control
src/plugin-qt/shortcut/CMakeLists.txt
src/plugin-qt/shortcut/src/core/triggeractioncatalog.cpp
src/plugin-qt/shortcut/src/core/triggeractioncatalog.h
src/plugin-qt/shortcut/src/backend/wayland/treelandshortcutwrapper.cpp
src/plugin-qt/shortcut/src/backend/wayland/treelandshortcutwrapper.h
src/plugin-qt/shortcut/src/backend/wayland/waylandkeyhandler.cpp
src/plugin-qt/shortcut/src/backend/wayland/waylandgesturehandler.cpp
src/plugin-qt/shortcut/src/core/gestureactioncatalog.cpp
Replaces v2 commit/acknowledgement handling with explicit Wayland flushing and display synchronization, including tracking of synchronous and deferred bind failures.
  • Flushes outgoing requests immediately or through a coalesced deferred flush.
  • Uses wl_display.sync to wait for processing and correlates failures with the bindings pending in each sync.
  • Reports late failures after inactive-session deferral and handles protocol reacquisition/inactivation.
src/plugin-qt/shortcut/src/backend/wayland/treelandshortcutwrapper.cpp
src/plugin-qt/shortcut/src/backend/wayland/treelandshortcutwrapper.h
src/plugin-qt/shortcut/src/backend/abstractkeyhandler.h
src/plugin-qt/shortcut/src/backend/abstractgesturehandler.h
src/plugin-qt/shortcut/src/core/shortcutmanager.cpp
src/plugin-qt/shortcut/src/core/shortcutmanager.h
Adds compensation and runtime cleanup so partial or deferred registration failures do not leave stale compositor bindings.
  • Removes all bindings belonging to a failed multi-hotkey registration while retaining unrelated bindings.
  • Removes runtime bindings on late failures without discarding saved configuration.
  • Restores prior key and gesture bindings when edits, persistence updates, or replacement registrations fail.
src/plugin-qt/shortcut/src/backend/wayland/waylandkeyhandler.cpp
src/plugin-qt/shortcut/src/backend/wayland/waylandgesturehandler.cpp
src/plugin-qt/shortcut/src/core/keybindingmanager.cpp
src/plugin-qt/shortcut/src/core/keybindingmanager.h
src/plugin-qt/shortcut/src/core/gesturemanager.cpp
src/plugin-qt/shortcut/src/core/gesturemanager.h
Documents the v3 lifecycle and expands regression coverage for action mapping and Wayland protocol behavior.
  • Documents non-atomic bind/unbind semantics, flush/sync behavior, deferred failures, supported actions, and lifecycle expectations.
  • Adds stable-ID mapping tests and enables newly supported gesture actions.
  • Adds a private windowless Wayland server test covering registration, activation, cleanup, deferred failures, replacement isolation, and edit rollback.
  • Adds the Qt6 Wayland test dependency and configures protocol/server code generation and test execution.
src/plugin-qt/shortcut/DEVELOPER_GUIDE.md
src/plugin-qt/shortcut/tests/CMakeLists.txt
src/plugin-qt/shortcut/tests/tst_triggeractioncatalog.cpp
src/plugin-qt/shortcut/tests/tst_gestureactioncatalog.cpp
src/plugin-qt/shortcut/tests/tst_waylandshortcuts.cpp

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 - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 100 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交将快捷键服务从 Treeland shortcut manager v2 协议迁移至 v3 协议, 变更涉及 24 个文件、880 行新增、187 行删除。核心改动包括:用 flush/syncAndWait 替代 v2 的 commit/commitAndWait,引入 PendingSync 结构管理同步状态,新增 registrationFailed 信号处理延迟绑定失败,为绑定名称添加序列号以防止延迟失败 误伤替换绑定,将动作 ID 映射从硬编码数字改为协议枚举常量。代码语法逻辑正确, 无编译错误与崩溃风险;代码质量优良,注释完整、结构清晰、无重复代码;性能方面 无瓶颈,资源使用合理;安全方面无任何漏洞。同时新增了完整的 Wayland 私有服务器 测试用例,测试覆盖充分。

🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: []


💡 改进建议代码示例

本次代码无需修复,以下为 syncAndWait 的正确实现供参考: bool TreelandShortcutWrapper::syncAndWait(int timeoutMs) {
    auto *display = waylandDisplay();
    if (!isActive() || !display)
        return false;

    auto *callback = wl_display_sync(display);
    if (!callback)
        return false;

    PendingSync sync;
    sync.bindings = std::exchange(m_pendingBindings, {});
    sync.failed = std::exchange(m_pendingBindFailed, false);
    m_syncs.append(&sync);

    static const wl_callback_listener listener = {
        [](void *data, wl_callback *, uint32_t) {
            auto *pending = static_cast<PendingSync *>(data);
            pending->done = true;
            pending->loop.quit();
        }
    };
    wl_callback_add_listener(callback, &listener, &sync);

    QPointer<TreelandShortcutWrapper> guard(this);
    const auto *boundObject = object();
    connect(this, &TreelandShortcutWrapper::protocolInactive, &sync.loop, &QEventLoop::quit);
    connect(this, &QObject::destroyed, &sync.loop, &QEventLoop::quit);
    QTimer timer;
    timer.setSingleShot(true);
    connect(&timer, &QTimer::timeout, &sync.loop, &QEventLoop::quit);
    timer.start(timeoutMs);
    flush();
    sync.loop.exec();
    wl_callback_destroy(callback);

    if (!guard)
        return false;
    m_syncs.removeOne(&sync);
    if (!sync.done)
        qCWarning(logShortcut) << "Treeland shortcut sync did not complete within" << timeoutMs << "ms";
    return sync.done && !sync.failed && isActive() && object() == boundObject;
}

本报告由 AI 代码审查工具自动生成

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