Skip to content

feat: add shortcut manager plugin#55

Open
yixinshark wants to merge 1 commit intolinuxdeepin:masterfrom
yixinshark:feat-shortcut
Open

feat: add shortcut manager plugin#55
yixinshark wants to merge 1 commit intolinuxdeepin:masterfrom
yixinshark:feat-shortcut

Conversation

@yixinshark
Copy link
Contributor

-Keyboard shortcut management in X11;
-Keyboard shortcut and gesture management in Treeland -develop-guide document

Log: add shortcut manager plugin

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @yixinshark, your pull request is larger than the review limit of 150000 diff characters

-Keyboard shortcut management in X11;
-Keyboard shortcut and gesture management in Treeland
-develop-guide document

Log: add shortcut manager plugin
@deepin-ci-robot
Copy link

[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

1 similar comment
@deepin-ci-robot
Copy link

[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

@yixinshark
Copy link
Contributor Author

TODO:
1.进一步测试triggers触发重新加载快捷键配置
2.treeland的联调,已初步测试。关注协议的变化。

"name": "appId",
"name[zh_CN]": "提供快捷键应用Id",
"description": "provide gesture app id",
"permissions": "readonly",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有readonly这个字符串配置,要么是readwrite,要么为空就行,它会默认是readonly。

"visibility": "private"
}
}
} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

换行,

deepin-service-manager (>= 1.0.5)
deepin-service-manager (>= 1.0.5),
dbus,
libdtk6core,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加了build依赖,应该不需要加运行依赖了,

#include <QDebug>
#include <QEventLoop>
#include <QTimer>
#include <qlogging.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大写头文件,整理下日志category

: QWaylandClientExtensionTemplate<TreelandShortcutWrapper>(2) // version 2
, QtWayland::treeland_shortcut_manager_v2()
{
setParent(parent);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不能在构造函数时将parent当做参数传递给基类么?

bool success = false;
bool responded = false;

auto conn = connect(this, &TreelandShortcutWrapper::commitStatus, &loop, [&](bool status) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conn变量用不到了,

KeyConfig ConfigLoader::parseKeyConfig(DConfig *config)
{
KeyConfig keyConfig;
keyConfig.subPath = config->subpath();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果内容分出了shortcut和gesture的config,看需不需要把对应的json名称也改一下,这样从配置文件就能看出对应的配置行为,另外对于之后用subpath方式做自定义快捷键也方便些,


signals:
void keyConfigChanged(const KeyConfig &config);
void gestureConfigChanged(const GestureConfig &config);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GestureConfig作为信号参数的话,需要进行类型注册,不然异步连接应该会存在问题,

}
}
} else {
GestureConfig &old = m_gestureConfigsMap[config.getId()];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不修改的话,使用const &

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new shortcut manager plugin for Deepin, including a core daemon/service with X11 and Wayland backends, a helper CLI (dde-shortcut-tool), DConfig-based shortcut/gesture definitions, translations, and Debian packaging hooks to reload shortcuts when configs change.

Changes:

  • Add a full-featured dde-shortcut Qt plugin and optional standalone debug binary that manage global keyboard shortcuts and gestures across X11 and Treeland/Wayland, with X11/Wayland-specific handlers and DBus APIs (org.deepin.dde.Keybinding1 / org.deepin.dde.Gesture1).
  • Introduce dde-shortcut-tool CLI with multiple controllers (audio, display, power, touchpad, network, keyboard backlight, lock keys, app launcher) to execute system actions used by the shortcut configs.
  • Define a large set of DConfig-based shortcut/gesture metadata under org.deepin.dde.keybinding, translation infrastructure (TS files, i18n extraction tool and CMake helpers), and Debian integration (extra build/runtime deps, triggers, and postinst logic to call ReloadConfigs on running sessions).

Notable Issue

  • Bug – ConfigLoader cannot persist updated values to DConfig
    In src/plugin-qt/shortcut/src/config/configloader.cpp, loadConfig() calls DConfig::create(APP_ID, CONFIG_NAME, "/" + subPath, ...) and later sets keyConfig.subPath = config->subpath();, so keyConfig.getId() is based on config->subpath() (which includes the leading /).
    However, m_configs is keyed by the unprefixed subPath (m_configs.insert(subPath, config); around lines 140–221), while updateValue() checks if (m_configs.contains(id)) and uses m_configs[id] (lines ~85–92), where id is passed from KeybindingManager as config.getId() (the prefixed form).
    This mismatch means updateValue() will never find the entry and thus will not call setValue, so DBus methods like ModifyHotkeys and Disable update the in-memory maps and grabs but will not persist changes back into DConfig. A concrete fix would be to key m_configs by the same string used for getId() (e.g. config->subpath()) or to translate from id back to subPath via m_subPathToId before indexing m_configs.

Reviewed changes

Copilot reviewed 176 out of 176 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/plugin-qt/CMakeLists.txt Adds the shortcut plugin subdirectory to the Qt plugin build, wiring the new module into the overall project.
src/plugin-qt/shortcut/CMakeLists.txt Defines build of the plugin-dde-shortcut library and optional dde-shortcut-debug binary, sets up Wayland protocol codegen, installs configs, i18n tooling, and integrates translation generation.
src/plugin-qt/shortcut/src/main.cpp Standalone debug entry point that initializes ShortcutManager in a QGuiApplication, supports --list to dump configs.
src/plugin-qt/shortcut/src/core/shortcutmanager.h/.cpp Coordinates config loading, backend selection (X11 vs Wayland), and creation of KeybindingManager/GestureManager; handles Wayland protocol lifecycle and registration.
src/plugin-qt/shortcut/src/core/keybindingmanager.h/.cpp Implements DBus interface org.deepin.dde.Keybinding1, manages key shortcut registration, conflict checking, lock-key properties, and delegates execution to ActionExecutor; affected by the ConfigLoader::updateValue bug described above.
src/plugin-qt/shortcut/src/core/gesturemanager.h/.cpp Implements DBus interface org.deepin.dde.Gesture1, manages gesture registration, config updates, and activation signals for Wayland sessions.
src/plugin-qt/shortcut/src/core/shortcutconfig.h Defines shared configuration structs/enums for shortcuts and gestures (trigger types, categories, key event flags, gesture types/directions).
src/plugin-qt/shortcut/src/core/qkeysequenceconverter.h/.cpp Provides conversions between Qt key sequence names, XKB-style strings, and Qt key combinations; used by X11 backend and Wayland binding names.
src/plugin-qt/shortcut/src/core/actionexecutor.h/.cpp Executes configured actions based on TriggerType (command/app/action), invoking /usr/bin/dde-am or launching app IDs.
src/plugin-qt/shortcut/src/core/translationmanager.h/.cpp Manages per-app-id QTranslator instances loaded from /usr/share/deepin/org.deepin.dde.keybinding/translations, and provides translation lookup used in DBus structs.
src/plugin-qt/shortcut/src/config/configloader.h/.cpp Loads DConfig-based shortcut and gesture definitions from .ini + org.deepin.shortcut.json files, exposes lists and change signals, and attempts to update DConfig on changes; contains the id/subPath key mismatch bug for updateValue().
src/plugin-qt/shortcut/src/backend/abstractkeyhandler.h Abstract interface for key backends (register/unregister, commit, lock-key operations, and activation signal).
src/plugin-qt/shortcut/src/backend/abstractgesturehandler.h Abstract interface for gesture backends (register/unregister, commit, and activation signal).
src/plugin-qt/shortcut/src/backend/specialkeyhandler.h/.cpp Handles “special” keys that come via org.deepin.dde.KeyEvent1 (libinput), mapping numeric keycodes to shortcut IDs with support for press/release/repeat semantics.
src/plugin-qt/shortcut/src/backend/x11/x11keyhandler.h/.cpp Implements AbstractKeyHandler for X11 using XCB/XTest, including key grabbing, repeat detection, standalone modifier handling, and Caps/Num Lock state get/set.
src/plugin-qt/shortcut/src/backend/x11/modifierkeymonitor.h/.cpp Polling-based helper that tracks standalone modifier presses/releases and emits modifierKeyReleased for use by X11KeyHandler.
src/plugin-qt/shortcut/src/backend/x11/x11helper.cpp Wraps XStringToKeysym in a C-accessible function used by the X11 backend.
src/plugin-qt/shortcut/src/backend/wayland/treelandshortcutwrapper.h/.cpp Wraps the Treeland shortcut manager Wayland protocol (treeland_shortcut_manager_v2), handling bind/unbind, commit semantics, and activation callbacks.
src/plugin-qt/shortcut/src/backend/wayland/waylandkeyhandler.h/.cpp Implements AbstractKeyHandler on Wayland via TreelandShortcutWrapper and KDE keystate protocol, managing bindings and Caps/Num Lock state where compositor support is available.
src/plugin-qt/shortcut/src/backend/wayland/waylandgesturehandler.h/.cpp Implements AbstractGestureHandler on Wayland, binding swipe/hold gestures via Treeland, tracking active bindings, and forwarding activations.
src/plugin-qt/shortcut/src/3rdparty/kde-keystate.xml Bundles the KDE keystate Wayland protocol description used to generate client stubs.
src/plugin-qt/shortcut/pluginshortcutmanager.h/.cpp Adapter that owns a ShortcutManager in plugin mode and uses a provided QDBusConnection to register/unregister Keybinding and Gesture DBus objects and org.deepin.dde.Keybinding1 service.
src/plugin-qt/shortcut/plugin.cpp Defines DSM plugin entry points DSMRegister / DSMUnRegister, creating and cleaning up PluginShortcutManager.
src/plugin-qt/shortcut/plugin-dde-shortcut.json Deepin service-manager plugin metadata for the shortcut plugin (name, library path, exposed DBus paths, residency policy).
src/plugin-qt/shortcut/tools/extract_shortcuts_i18n.py Helper script that scans org.deepin.shortcut.json configs for modifiable shortcuts and generates a C++ file with QT_TRANSLATE_NOOP entries for lupdate.
src/plugin-qt/shortcut/tools/CMakeLists.txt Adds the dde-shortcut-tool subdirectory to the tools build.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/CMakeLists.txt Builds the dde-shortcut-tool CLI, links Qt6, Dtk6, XCB, and installs the binary.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/main.cpp Entry point for dde-shortcut-tool, setting up CommandParser and registering all controllers.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/commandparser.h/.cpp CLI parser that dispatches subcommands like audio, display, network, etc., to their respective controllers and prints usage/help.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/basecontroller.h Abstract base class for individual CLI controllers (name, supported actions, execute, help).
src/plugin-qt/shortcut/tools/dde-shortcut-tool/audiocontroller.h/.cpp Controls system audio via DBus (mute/unmute, volume up/down) and optional OSD signalling.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/displaycontroller.h/.cpp Controls display brightness and mode via Deepin display DBus APIs and DConfig, and can turn off the screen.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.h/.cpp Exposes power-related actions (shutdown/suspend/hibernate/turn-off-screen/away/etc.) via DBus integrations and DConfig.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/touchpadcontroller.h/.cpp Toggles and controls touchpad enabled state via DBus, with OSD signalling.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/networkcontroller.h/.cpp Toggles WiFi and airplane mode via org.deepin.dde.AirplaneMode1 on the system bus.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/mediaplayercontroller.h/.cpp Controls media players (play/pause/next/prev/seek/rewind/forward) via MPRIS DBus interfaces.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/kbdlightcontroller.h/.cpp Manages keyboard backlight toggling and brightness via DBus and backlight interfaces.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/lockkeycontroller.h/.cpp Shows OSD for CapsLock/NumLock state changes and queries/sets lock states across X11 and Wayland sessions.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/launchcontroller.h/.cpp Launches default applications for given MIME types or URL scheme handlers using xdg-mime and dde-am.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/networkcontroller.h/.cpp See above; used by WLAN shortcut config to toggle WiFi.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/constant.h Defines enums for audio/media/display/touchpad actions and DConfig key constants used across controllers.
src/plugin-qt/shortcut/tools/dde-shortcut-tool/test_shortcut_tool.sh Shell script to exercise and validate dde-shortcut-tool actions, serving as an integration test harness.
src/plugin-qt/shortcut/translations/org.deepin.dde.keybinding*.ts New TS stubs (per-locale) containing Display switch and terminal sources, marked as unfinished translations for future localization.
src/plugin-qt/shortcut/configs/org.deepin.dde.keybinding.ini Registers all shortcut and gesture DConfig subpaths so ConfigLoader can discover them at runtime.
src/plugin-qt/shortcut/configs/org.deepin.dde.keybinding.shortcut.*/org.deepin.shortcut.json Define a comprehensive set of system keyboard shortcuts (volume, brightness, media, power, WLAN, touchpad, lock keys, default terminal, apps, etc.) with metadata (appId, displayName, hotkeys, triggerType/value, category, enabled, modifiable).
src/plugin-qt/shortcut/configs/org.deepin.dde.keybinding.gesture.*/org.deepin.shortcut.json Define touchpad gesture shortcuts (3/4-finger swipes and taps) for Wayland, mapping to compositor action IDs used in Treeland protocol.
src/plugin-qt/shortcut/src/3rdparty/kde-keystate.xml (Already noted above) Wayland protocol spec for key states, used by KeyStateManager.
debian/control Extends build-deps (Qt Wayland, tools, XCB keysyms/xtest, Wayland, treeland-protocols, Python) and runtime deps (Qt6, Dtk6, Wayland/XCB libs) to support the new plugin and tools; updates package description to mention the shortcut manager.
debian/dde-services.triggers Adds a trigger on /usr/share/deepin/org.deepin.dde.keybinding so DConfig metadata changes will cause postinst to run with triggered.
debian/dde-services.postinst On trigger, iterates active user DBus session buses and calls org.deepin.dde.Keybinding1.ReloadConfigs for each, so running sessions pick up updated shortcut configs without restart.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@deepin-bot
Copy link

deepin-bot bot commented Jan 29, 2026

TAG Bot

New tag: 1.0.20
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #56

@deepin-bot
Copy link

deepin-bot bot commented Feb 27, 2026

TAG Bot

New tag: 1.0.21
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #58

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.

4 participants