Skip to content

WM-195: feat: support pointer-constraints protocol - #1267

Draft
deepin-wm wants to merge 1 commit into
linuxdeepin:masterfrom
deepin-wm:agent/bot/a6fc6c7e
Draft

WM-195: feat: support pointer-constraints protocol#1267
deepin-wm wants to merge 1 commit into
linuxdeepin:masterfrom
deepin-wm:agent/bot/a6fc6c7e

Conversation

@deepin-wm

@deepin-wm deepin-wm commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

概述 / Summary

实现 zwp_pointer_constraints_v1(locked/confined)与 zwp_relative_pointer_manager_v1 协议在 treeland/waylib 中的支持。

Implement zwp_pointer_constraints_v1 (locked/confined) and zwp_relative_pointer_manager_v1 protocol support in treeland/waylib.

改动内容 / Changes

waylib(in-tree vendored):

  • 新增 WPointerConstraintsV1 协议包装器(wpointerconstraintsv1.{h,cpp}
  • 新增 WRelativePointerManagerV1 协议包装器(wrelativepointerv1.{h,cpp}
  • WCursorPrivate::on_motion/on_motion_absolute 插入约束强制路径(applyPointerConstraint):
    • Locked:通过 sendRelativeMotion 发送相对增量(时间戳微秒),隐藏光标并每次运动 warp 回锚点防累积偏移
    • Confined:用 pointer_state.sx/sy 为锚点 + 内联 regionConfineWrapper(pixman 实现)钳制到约束 region
  • 内联基于 pixman 的 regionConfine 替代 wlr_region_confine,避免 wlroots 链接依赖

treeland:

  • Helper::init 挂载 WPointerConstraintsV1WRelativePointerManagerV1
  • 新增 PointerConstraintsManager 管理激活/失活策略:
    • canActivate 检查模式为 Normal、无 drag、无 pointer grab(wlr_seat_pointer_has_grab)、无 move/resize(isInMoveResize)、持 pointer focus
    • onSeatGrabChanged 在 grab_begin 只失活不重激活,grab_end 后才重新评估
    • set_region 变化时重新评估
  • 新增 Helper::isInMoveResize(WSeat*) 访问器
  • 模式切换(锁屏/多任务视图/窗口切换)时 deactivateAll() 全量失活
  • 新增 test_protocol_pointerconstraints 测试用例

关联 / Related

  • Multica Issue: WM-195

测试 / Testing

本地全量编译验证通过(V25 / GCC 12.3 / Qt 6.8 / -Wall -Wextra -Werror / --as-needed / ninja -j16):

  • waylib + treeland 编译链接全通过
  • test_protocol_pointerconstraints 构建并通过(12/12 tests passed)
  • 产出 .deb

已知限制 / Known Limitations

  1. surfaceSizeRatio ≠ 1 时 confined 钳制假设 surface-local 与 output-layout delta 同为逻辑坐标
  2. 无 grab 的 pointer focus 漂移未接 pointer_state.events.focus_change
  3. locked cursor_hint 运行中不实时更新

以上三项作为后续 TODO 跟踪,不构成本轮阻断。

Summary by Sourcery

Add compositor-side support for Wayland pointer constraints and relative pointer protocols, including cursor behavior changes and seat-level activation management.

New Features:

  • Expose zwp_pointer_constraints_v1 and zwp_relative_pointer_manager_v1 as waylib server interfaces and attach them in treeland Helper.
  • Introduce PointerConstraintsManager to track and control activation of locked and confined pointer constraints based on seat state and compositor mode.

Enhancements:

  • Integrate pointer constraint handling into WCursor motion processing, including cursor hiding/warping for locked constraints and region-based confinement for confined constraints using a local pixman-based implementation.
  • Provide a Helper::isInMoveResize accessor and deactivate all pointer constraints when switching out of normal mode to keep constraints in sync with compositor UI states.

Tests:

  • Add the test_protocol_pointerconstraints test suite to verify creation and discovery of the new protocol interfaces and basic constraint querying behavior.

@deepin-ci-robot

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: deepin-wm

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 11, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds Wayland zwp_pointer_constraints_v1 (locked/confined) and zwp_relative_pointer_manager_v1 support to waylib/treeland, wiring them into cursor motion handling and introducing a compositor-side manager to control when constraints can be activated, plus basic protocol tests.

Sequence diagram for locked pointer constraint activation and motion handling

sequenceDiagram
    participant WPointerConstraintsV1
    participant PointerConstraintsManager
    participant WSeat
    participant WCursor
    participant WRelativePointerManagerV1

    WPointerConstraintsV1->>WPointerConstraintsV1: create(WServer)
    WPointerConstraintsV1->>WPointerConstraintsV1: newConstraint(wlr_pointer_constraint_v1*)
    WPointerConstraintsV1->>PointerConstraintsManager: onNewConstraint(wlr_pointer_constraint_v1*)
    PointerConstraintsManager->>PointerConstraintsManager: canActivate(wlr_pointer_constraint_v1*)
    PointerConstraintsManager->>WSeat: WSeat::fromHandle(qw_seat*)
    PointerConstraintsManager->>WCursor: activateConstraint(wlr_pointer_constraint_v1*)
    WCursor->>WCursor: setActivePointerConstraint(wlr_pointer_constraint_v1*)

    WCursor->>WCursor: on_motion(wlr_pointer_motion_event*)
    WCursor->>WCursor: WCursorPrivate::applyPointerConstraint(qw_pointer*, timeMsec, dx, dy, dxUnaccel, dyUnaccel, oldPos)
    alt constraint type locked
        WCursor->>WRelativePointerManagerV1: sendRelativeMotion(wlr_seat*, timeUsec, dx, dy, dxUnaccel, dyUnaccel)
        WCursor->>WCursor: setPosition(qw_pointer*, lockedWarpTarget)
    else constraint type confined
        WCursor->>WCursor: regionConfineWrapper(region, sx, sy, confinedSx, confinedSy, x2_out, y2_out)
        WCursor->>WCursor: setPosition(qw_pointer*, newPos)
    end
Loading

File-Level Changes

Change Details Files
Integrate pointer-constraint handling into WCursor motion processing, including locked and confined behaviors and region confinement logic.
  • Hook applyPointerConstraint into on_motion and on_motion_absolute before processCursorMotion
  • Implement applyPointerConstraint to send relative motion events for locked constraints and warp the cursor back to an anchor
  • Implement confined constraint handling using seat pointer_state and a pixman-based regionConfineWrapper
  • Track active pointer constraint, pre-lock cursor visibility, and locked warp target in WCursorPrivate
  • Expose setActivePointerConstraint and activePointerConstraint on WCursor
waylib/src/server/kernel/wcursor.cpp
waylib/src/server/kernel/wcursor.h
waylib/src/server/kernel/private/wcursor_p.h
Provide in-tree protocol wrappers for zwp_pointer_constraints_v1 and zwp_relative_pointer_manager_v1 and integrate them into the waylib server build.
  • Add WPointerConstraintsV1 wrapper class over qw_pointer_constraints_v1 with newConstraint signaling and constraintForSurface helper
  • Add WRelativePointerManagerV1 wrapper class over qw_relative_pointer_manager_v1 with sendRelativeMotion helper
  • Register new protocol sources and headers in waylib server CMakeLists.txt
waylib/src/server/protocols/wpointerconstraintsv1.cpp
waylib/src/server/protocols/wpointerconstraintsv1.h
waylib/src/server/protocols/wrelativepointerv1.cpp
waylib/src/server/protocols/wrelativepointerv1.h
waylib/src/server/CMakeLists.txt
Introduce a PointerConstraintsManager in treeland to manage activation/deactivation of constraints based on compositor mode, seat grab state, move/resize, and pointer focus.
  • Create PointerConstraintsManager class that tracks constraints, active set, and associated cursors
  • Implement canActivate with checks on Helper::currentMode, seat drag, wlr_seat_pointer_has_grab, Helper::isInMoveResize, and pointer focus surface
  • Wire up constraint lifecycle: activation on newConstraint/set_region, deactivation on seat grab changes or deactivateAll, cleanup on destroy
  • Hook into qw_seat pointer_grab signals to respond to grab begin/end
src/seat/pointerconstraintsmanager.cpp
src/seat/pointerconstraintsmanager.h
Wire pointer-constraint and relative-pointer protocol interfaces into Helper initialization and mode changes, and expose move/resize state for activation logic.
  • Attach WPointerConstraintsV1 and WRelativePointerManagerV1 from Helper::init and keep pointers on Helper
  • Construct PointerConstraintsManager during initialization
  • Add Helper::isInMoveResize accessor that checks the seat’s surface container moveResizeState
  • Deactivate all constraints when Helper::setCurrentMode switches away from Normal
src/seat/helper.cpp
src/seat/helper.h
src/CMakeLists.txt
Add unit tests for the new protocol wrappers and integrate them into the test suite.
  • Create test_protocol_pointerconstraints test verifying interface attachment, names, and global registration for WPointerConstraintsV1 and WRelativePointerManagerV1
  • Add CMakeLists for the new test and register it with ctest, running offscreen
tests/test_protocol_pointerconstraints/main.cpp
tests/test_protocol_pointerconstraints/CMakeLists.txt
tests/CMakeLists.txt
Embed a pixman-based regionConfine implementation in wcursor.cpp to avoid linking wlroots util library directly.
  • Implement recursive regionConfine and regionConfineWrapper functions mirroring wlroots/util/region.c behavior using pixman_region32 APIs
  • Use regionConfineWrapper for confined pointer constraints when updating cursor position
waylib/src/server/kernel/wcursor.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

1. Add PointerConstraintsManager for activation/deactivation policy
2. Mount WPointerConstraintsV1 and WRelativePointerManagerV1 in Helper
3. Add isInMoveResize accessor and grab exclusion in canActivate
4. Deactivate all constraints on mode switch (lock screen/multitask/view)
5. Add in-tree waylib wrappers and WCursor enforcement path
6. Inline pixman-based regionConfine to avoid wlroots linking dependency
7. Add test_protocol_pointerconstraints test case

Log: Added pointer lock and confinement support for wayland clients

Influence:
1. Test locked pointer with a 3D mouselook client
2. Test confined pointer with a region-limited client
3. Verify constraints deactivate on lock screen/multitask/view switch
4. Verify constraints do not activate during drag, popup grab, or move/resize
5. Verify oneshot constraints are destroyed after deactivation

feat: 支持 pointer-constraints 协议

1. 新增 PointerConstraintsManager 管理激活/失活策略
2. 在 Helper 中挂载 WPointerConstraintsV1 和 WRelativePointerManagerV1
3. 新增 isInMoveResize 访问器并在 canActivate 中排除 grab/moveResize
4. 模式切换(锁屏/多任务/视图)时全量失活约束
5. 内嵌 waylib 包装器及 WCursor 约束强制路径
6. 内联基于 pixman 的 regionConfine 避免对 wlroots 的链接依赖
7. 新增 test_protocol_pointerconstraints 测试用例

Log: 新增 Wayland 客户端指针锁定和限制功能

Influence:
1. 使用 3D 视角客户端测试锁定指针
2. 使用区域限制客户端测试 confined 指针
3. 验证锁屏/多任务/视图切换时约束失活
4. 验证拖拽/popup grab/move-resize 期间约束不激活
5. 验证 oneshot 约束失活后自动销毁
@deepin-bot

deepin-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.8.18
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1286

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