feat: add shortcut manager plugin#55
Conversation
There was a problem hiding this comment.
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
4c2e330 to
0274930
Compare
|
[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. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
1 similar comment
|
[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. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
TODO: |
| "name": "appId", | ||
| "name[zh_CN]": "提供快捷键应用Id", | ||
| "description": "provide gesture app id", | ||
| "permissions": "readonly", |
There was a problem hiding this comment.
没有readonly这个字符串配置,要么是readwrite,要么为空就行,它会默认是readonly。
| "visibility": "private" | ||
| } | ||
| } | ||
| } No newline at end of file |
| deepin-service-manager (>= 1.0.5) | ||
| deepin-service-manager (>= 1.0.5), | ||
| dbus, | ||
| libdtk6core, |
There was a problem hiding this comment.
加了build依赖,应该不需要加运行依赖了,
| #include <QDebug> | ||
| #include <QEventLoop> | ||
| #include <QTimer> | ||
| #include <qlogging.h> |
| : QWaylandClientExtensionTemplate<TreelandShortcutWrapper>(2) // version 2 | ||
| , QtWayland::treeland_shortcut_manager_v2() | ||
| { | ||
| setParent(parent); |
There was a problem hiding this comment.
不能在构造函数时将parent当做参数传递给基类么?
| bool success = false; | ||
| bool responded = false; | ||
|
|
||
| auto conn = connect(this, &TreelandShortcutWrapper::commitStatus, &loop, [&](bool status) { |
| KeyConfig ConfigLoader::parseKeyConfig(DConfig *config) | ||
| { | ||
| KeyConfig keyConfig; | ||
| keyConfig.subPath = config->subpath(); |
There was a problem hiding this comment.
如果内容分出了shortcut和gesture的config,看需不需要把对应的json名称也改一下,这样从配置文件就能看出对应的配置行为,另外对于之后用subpath方式做自定义快捷键也方便些,
|
|
||
| signals: | ||
| void keyConfigChanged(const KeyConfig &config); | ||
| void gestureConfigChanged(const GestureConfig &config); |
There was a problem hiding this comment.
GestureConfig作为信号参数的话,需要进行类型注册,不然异步连接应该会存在问题,
| } | ||
| } | ||
| } else { | ||
| GestureConfig &old = m_gestureConfigsMap[config.getId()]; |
There was a problem hiding this comment.
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-shortcutQt 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-toolCLI 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 callReloadConfigson running sessions).
Notable Issue
- Bug – ConfigLoader cannot persist updated values to DConfig
Insrc/plugin-qt/shortcut/src/config/configloader.cpp,loadConfig()callsDConfig::create(APP_ID, CONFIG_NAME, "/" + subPath, ...)and later setskeyConfig.subPath = config->subpath();, sokeyConfig.getId()is based onconfig->subpath()(which includes the leading/).
However,m_configsis keyed by the unprefixedsubPath(m_configs.insert(subPath, config);around lines 140–221), whileupdateValue()checksif (m_configs.contains(id))and usesm_configs[id](lines ~85–92), whereidis passed fromKeybindingManagerasconfig.getId()(the prefixed form).
This mismatch meansupdateValue()will never find the entry and thus will not callsetValue, so DBus methods likeModifyHotkeysandDisableupdate the in-memory maps and grabs but will not persist changes back into DConfig. A concrete fix would be to keym_configsby the same string used forgetId()(e.g.config->subpath()) or to translate fromidback tosubPathviam_subPathToIdbefore indexingm_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.
|
TAG Bot New tag: 1.0.20 |
|
TAG Bot New tag: 1.0.21 |
-Keyboard shortcut management in X11;
-Keyboard shortcut and gesture management in Treeland -develop-guide document
Log: add shortcut manager plugin