Skip to content

feat: implement zwp_keyboard_shortcuts_inhibit_unstable_v1 server-side - #1321

Draft
deepin-wm wants to merge 2 commits into
linuxdeepin:masterfrom
deepin-wm:feat/keyboard-shortcuts-inhibit
Draft

feat: implement zwp_keyboard_shortcuts_inhibit_unstable_v1 server-side#1321
deepin-wm wants to merge 2 commits into
linuxdeepin:masterfrom
deepin-wm:feat/keyboard-shortcuts-inhibit

Conversation

@deepin-wm

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

Copy link
Copy Markdown
Contributor

Summary

Implement the server-side of zwp_keyboard_shortcuts_inhibit_unstable_v1 protocol for the treeland compositor.

Changes

  • New KeyboardShortcutsInhibitManagerV1 module wrapping wlroots' wlr_keyboard_shortcuts_inhibit_v1_create()
  • Focus-driven activation: sends active when the inhibited surface gains keyboard focus; resets active flag on focus leave (no inactive event), allowing re-activation on focus return
  • Escape hatch: built-in non-inhibitable Ctrl+Alt+Fn VT-switch force-deactivates the active inhibitor (sends inactive)
  • Shortcut suppression in helper.cpp via isInhibited(seat, surface) check before compositor shortcut dispatch
  • extern "C" guard around wlroots header include to fix C++ linkage

Related Issue

WM-300

Summary by Sourcery

Implement server-side keyboard shortcuts inhibition so focused clients can suppress compositor shortcuts while retaining access to VT switching.

New Features:

  • Add server-side support for the Wayland keyboard shortcuts inhibition protocol.
  • Activate inhibitors according to keyboard focus and provide a non-inhibitable VT-switch escape hatch.

Bug Fixes:

  • Prevent compositor shortcut handling while the focused surface has an active keyboard shortcuts inhibitor.

Enhancements:

  • Integrate the keyboard shortcuts inhibition manager into compositor server and seat lifecycle management.
  • Add dedicated logging for keyboard shortcuts inhibition events.

Build:

  • Add the new keyboard shortcuts inhibition module to the build.

Add KeyboardShortcutsInhibitManagerV1 module wrapping the wlroots
keyboard-shortcuts-inhibit implementation with focus-driven activation.

新增 KeyboardShortcutsInhibitManagerV1 模块,封装 wlroots 键盘快捷键
抑制实现,激活状态严格绑定键盘焦点。

Log: 实现键盘快捷键抑制协议服务端
Influence: 客户端可通过该协议抑制合成器键盘快捷键,支持焦点驱动激活与VT切换逃生通道。
@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 24, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements the server-side zwp_keyboard_shortcuts_inhibit_unstable_v1 protocol via a new KeyboardShortcutsInhibitManagerV1 module, wiring it into the seat helper to control compositor shortcut suppression and VT-switch escape behavior, with supporting logging and build-system updates.

Sequence diagram for keyboard shortcut inhibition lifecycle

sequenceDiagram
    participant Client
    participant Manager as KeyboardShortcutsInhibitManagerV1
    participant Seat as WSeat
    participant Helper
    participant Inhibitor as wlr_keyboard_shortcuts_inhibitor_v1

    Client->>Manager: create inhibitor
    Manager->>Manager: onNewInhibitor(inhibitor)
    Seat-->>Manager: keyboardFocusSurfaceChanged
    Manager->>Inhibitor: wlr_keyboard_shortcuts_inhibitor_v1_activate()
    Inhibitor-->>Client: active
    Helper->>Manager: isInhibited(seat, surface)
    Manager-->>Helper: true
    Helper-->>Helper: suppress compositor shortcut dispatch
    Seat-->>Manager: keyboardFocusSurfaceChanged
    Manager->>Inhibitor: reset active flag
    Helper->>Manager: deactivateActiveInhibitor(seat)
    Manager->>Inhibitor: wlr_keyboard_shortcuts_inhibitor_v1_deactivate()
    Inhibitor-->>Client: inactive
Loading

File-Level Changes

Change Details Files
Introduce KeyboardShortcutsInhibitManagerV1 server-side wrapper around wlroots keyboard shortcuts inhibit manager and track inhibitors per seat/surface with focus-driven activation.
  • Add KeyboardShortcutsInhibitManagerV1 and its private helper class implementing WServerInterface and QObject, with lifecycle hooks create/destroy/global
  • Call wlr_keyboard_shortcuts_inhibit_v1_create() in create() and set up new_inhibitor listener via WScopedListener
  • Maintain a vector of InhibitorEntry objects capturing the wlr inhibitor pointer and destroy listener, removing entries on destroy event
  • Implement focus-based activation logic in onSeatFocusChanged() to call wlr_keyboard_shortcuts_inhibitor_v1_activate() when the focused surface matches, and manually clear inhibitor->active on focus leave without sending inactive
  • Provide isInhibited(seat, surface) helper to check if there is an active inhibitor for a given seat/surface pair
  • Provide deactivateActiveInhibitor(seat) helper that calls wlr_keyboard_shortcuts_inhibitor_v1_deactivate() on any active inhibitor for the seat
  • Expose interfaceName() returning the zwp_keyboard_shortcuts_inhibit_manager_v1 name and implement wl_global retrieval based on wlroots handle
src/modules/keyboard-shortcuts-inhibit/keyboardshortcutsinhibitmanager.cpp
src/modules/keyboard-shortcuts-inhibit/keyboardshortcutsinhibitmanager.h
Wire inhibitor manager into seat/seat-manager infrastructure to react to keyboard focus changes across seats.
  • Add seatConnectionsSetup flag and a QHash mapping WSeat* to QMetaObject::Connection for keyboard focus change signals
  • Implement setupSeatConnections() to iterate existing seats from SeatsManager and connect to seatAdded/seatRemoved signals
  • Implement handleSeatAdded() to connect WSeat::keyboardFocusSurfaceChanged to onSeatFocusChanged() and immediately process current focus
  • Implement handleSeatRemoved() to disconnect and remove stored focus connections
src/modules/keyboard-shortcuts-inhibit/keyboardshortcutsinhibitmanager.cpp
Integrate the new keyboard shortcuts inhibit manager into the compositor helper so that compositor-level shortcuts respect inhibition and provide an escape hatch via VT switching.
  • Attach KeyboardShortcutsInhibitManagerV1 to WServer in Helper::init() and store the pointer on the Helper instance
  • In beforeDisposeEvent(), after handling Ctrl+Alt+Fn VT switch, call deactivateActiveInhibitor() on the inhibitor manager for the seat to send inactive and restore shortcuts
  • In beforeDisposeEvent(), before compositor shortcut handling, check the current keyboardFocusSurface and return false (skip compositor shortcuts) when isInhibited() is true
src/seat/helper.cpp
src/seat/helper.h
Add logging and build-system wiring for the keyboard shortcuts inhibit module.
  • Introduce Q_LOGGING_CATEGORY and Q_DECLARE_LOGGING_CATEGORY for lcTlKeyboardShortcutsInhibit
  • Update modules CMakeLists to add the keyboard-shortcuts-inhibit subdirectory and define a module target that builds the new manager sources linked against Qt6::Core
src/common/treelandlogging.cpp
src/common/treelandlogging.h
src/modules/CMakeLists.txt
src/modules/keyboard-shortcuts-inhibit/CMakeLists.txt

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

The "Build treeland on Deepin crimson (independent)" run for this commit was cancelled after hitting the GitHub Actions 6h job limit: 31 of 48 CTest cases timed out due to CI runner resource degradation, not a code defect. The same commit already passed the "Build treeland on Arch Linux" workflow. Push an empty commit (no source changes) to retrigger the workflows on a healthy runner.

Log: 重新触发因 CI 环境退化超时失败的 Deepin 构建工作流
Influence: 无代码变更,仅重新触发 CI
@deepin-bot

deepin-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.9.1
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1348

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