Pluggable global-shortcut backends behind a single registration API: KGlobalAccel (Plasma-native), XDG Portal (
xdg-desktop-portal.GlobalShortcuts), and a D-Bus ad-hoc fallback.
"Super+1 snaps to zone 1" needs to register a global shortcut from a userspace process. On Plasma that goes through KGlobalAccel. On generic Wayland compositors that support the portal, it goes through org.freedesktop.portal.GlobalShortcuts. On compositors with neither, there's no standard, so the ad-hoc D-Bus fallback exists for compositor-script or compositor-provided shortcut dispatch.
The consumer shouldn't care which backend is active. phosphor-shortcuts:
Registry::bind) for a shortcut id, default sequence, description, and callback.IBackend) that the application chooses at startup, or auto-selects by probing available services.createBackend(BackendHint)) that builds the right backend given a compositor or desktop hint.IAdhocRegistrar) for transient UI like modal-capture dialogs.| Type | Purpose |
|---|---|
Phosphor::Shortcuts::Registry | Front-end: bind() a shortcut id and callback |
Phosphor::Shortcuts::IBackend | Abstract backend. Shipped implementations: KGlobalAccel, XDG-Portal, D-Bus |
Phosphor::Shortcuts::Integration::IAdhocRegistrar | Short-lived registrations that skip persistent storage |
Phosphor::Shortcuts::createBackend | Selects the right backend based on running environment |
#include <PhosphorShortcuts/Registry.h>
#include <PhosphorShortcuts/Factory.h>
using namespace Phosphor::Shortcuts;
auto backend = createBackend(); // picks KGlobalAccel on Plasma
Registry registry(backend.get());
registry.bind(
/*id*/ QStringLiteral("snap-to-quick-1"),
/*defaultSeq*/ QKeySequence(QStringLiteral("Meta+1")),
/*description*/ tr("Snap active window to Quick Layout 1"),
/*callback*/ [] { engine.snapTo(1); },
/*persistent*/ true
);Switching backends is a one-liner: the same Registry API, a different IBackend.
auto portalBackend = createBackend(BackendHint::Portal);
Registry adhoc(portalBackend.get());
adhoc.bind(id, seq, desc, cb, /*persistent*/ false);IAdhocRegistrar is a separate interface.** Binds that should never end up in the user's persistent shortcut editor live behind a different API, so the backend only persists the ones that asked for it.createBackend(BackendHint::Auto)** probes at runtime. First preference is KGlobalAccel (fastest, native Plasma integration); it falls back to the portal, and last to D-Bus.QtCore, QtGui (for QKeySequence), QtDBusKF6::GlobalAccel (Plasma backend), compiled in when -DPHOSPHORSHORTCUTS_USE_KGLOBALACCEL=ON