Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorShortcuts::Registry Class Reference

Consumer-facing facade over IBackend. More...

#include <phosphor-shortcuts/include/PhosphorShortcuts/Registry.h>

Inheritance diagram for PhosphorShortcuts::Registry:
[legend]

Classes

struct  Binding
 

Signals

void triggered (QString id)
 Emitted on every activation, regardless of whether the binding has a callback.
 
void ready ()
 Forwarded from IBackend::ready().
 
void triggersChanged (QString id)
 Forwarded from IBackend::triggersChanged for ids this registry owns — the effective binding changed outside the bind/rebind flow (external rebind, compositor assignment).
 

Public Member Functions

 Registry (IBackend *backend, QObject *parent=nullptr)
 
 ~Registry () override
 
void bind (const QString &id, const QKeySequence &defaultSeq, const QString &description={}, std::function< void()> callback={}, bool persistent=true)
 Register a shortcut.
 
void rebind (const QString &id, const QKeySequence &seq)
 Change the active binding for an already-registered id.
 
void unbind (const QString &id)
 Drop a binding entirely.
 
void flush ()
 Forward queued bind/rebind ops to the backend.
 
QKeySequence shortcut (const QString &id) const
 
QStringList effectiveTriggers (const QString &id) const
 Display strings for the key(s) the user EFFECTIVELY has to press for an id right now.
 
QVector< Bindingbindings (bool persistentOnly=false) const
 Enumerate registered bindings, sorted by id for deterministic output.
 

Detailed Description

Consumer-facing facade over IBackend.

Owns a table of (id, default sequence, current sequence, description, optional callback) rows. Forwards registration + rebind calls to the backend and fans activation signals out as either per-id callbacks or the triggered() signal — consumers may use either pattern interchangeably.

The Registry does not own the backend; the caller keeps the backend alive for the Registry's lifetime. Passing a null backend is a programming error.

Constructor & Destructor Documentation

◆ Registry()

PhosphorShortcuts::Registry::Registry ( IBackend backend,
QObject *  parent = nullptr 
)
explicit

◆ ~Registry()

PhosphorShortcuts::Registry::~Registry ( )
override

Member Function Documentation

◆ bind()

void PhosphorShortcuts::Registry::bind ( const QString &  id,
const QKeySequence &  defaultSeq,
const QString &  description = {},
std::function< void()>  callback = {},
bool  persistent = true 
)

Register a shortcut.

Safe to call multiple times for the same id — subsequent calls update the default sequence, description, and callback in place but PRESERVE the current sequence (any user-applied rebind is kept). Takes effect after flush().

Parameters
callbackOptional. Invoked on activation in addition to the triggered() signal. Nullptr callbacks are stored but never invoked; consumers relying purely on the signal can omit the argument.
persistentIf false, the binding is considered transient (e.g. a grab bound around a specific UI state) and is excluded from bindings(true) enumeration. Does not affect backend behaviour. Defaults to true.

Note: descriptions are captured at first-flush time and NOT forwarded on subsequent bind() calls — IBackend::updateShortcut doesn't carry a description argument. Description changes at runtime are local-only.

◆ bindings()

QVector< Binding > PhosphorShortcuts::Registry::bindings ( bool  persistentOnly = false) const

Enumerate registered bindings, sorted by id for deterministic output.

Parameters
persistentOnlyIf true, transient bindings (those registered with persistent=false) are excluded. Intended for settings UIs that should not expose internal ad-hoc grabs to the user. Defaults to false so tests and library-internal callers see everything.

◆ effectiveTriggers()

QStringList PhosphorShortcuts::Registry::effectiveTriggers ( const QString &  id) const

Display strings for the key(s) the user EFFECTIVELY has to press for an id right now.

Prefers the backend's read-back (IBackend::currentTriggers — which sees out-of-process overrides like System Settings rebinds, INCLUDING a cleared binding, which reports engaged-empty and is honored as unbound); falls back to the registry's own current sequence only when the backend cannot report at all. Empty means the id is genuinely unbound (or unknown).

The strings are DISPLAY-ONLY and not format-stable across backends (see IBackend::currentTriggers): KGlobalAccel yields PortableText while Portal relays the compositor's localized description. Don't string-compare results across backends or parse them back into QKeySequence.

KNOWN CONSUMER PAST THAT CONTRACT: the daemon's cheatsheet family compression (shortcutmanager_catalog.cpp) does parse these back to normalize and token-compare. It degrades gracefully by design — a string that does not parse stays verbatim, fails the compare, and the family simply shows uncompressed rows — but a change to this method's output format must keep that consumer in mind.

◆ flush()

void PhosphorShortcuts::Registry::flush ( )

Forward queued bind/rebind ops to the backend.

Does NOT include unbind() — those are applied immediately at the call site. Matches the backend's queue-then-flush model for register / update.

ready() fires after flushes settle, including no-op flushes where no entry actually changed, so consumers can gate UI on "any flush has settled" without per-entry bookkeeping. Do NOT assume a 1:1 flush→ready count: during asynchronous backend bring-up (PortalBackend before its session handle lands) multiple queued flushes coalesce into a single ready(). If you need "only fire when something actually changed", track that on the caller side.

◆ ready

void PhosphorShortcuts::Registry::ready ( )
signal

Forwarded from IBackend::ready().

◆ rebind()

void PhosphorShortcuts::Registry::rebind ( const QString &  id,
const QKeySequence &  seq 
)

Change the active binding for an already-registered id.

Takes effect after flush(). Unknown ids are logged and ignored. Passing an empty QKeySequence releases the backend grab immediately (never leaves an empty sequence registered) but KEEPS the entry, so a later rebind() to a non-empty sequence re-registers it without a fresh bind().

◆ shortcut()

QKeySequence PhosphorShortcuts::Registry::shortcut ( const QString &  id) const

◆ triggered

void PhosphorShortcuts::Registry::triggered ( QString  id)
signal

Emitted on every activation, regardless of whether the binding has a callback.

Use this for centralised dispatch (one slot, switch on id).

Signature matches IBackend::activated (QString by value) so the two signals can be cross-connected without adapter slots.

◆ triggersChanged

void PhosphorShortcuts::Registry::triggersChanged ( QString  id)
signal

Forwarded from IBackend::triggersChanged for ids this registry owns — the effective binding changed outside the bind/rebind flow (external rebind, compositor assignment).

Re-query effectiveTriggers() on it.

◆ unbind()

void PhosphorShortcuts::Registry::unbind ( const QString &  id)

Drop a binding entirely.

Releases any key grab and forgets the callback. Idempotent. Applied immediately — NOT batched until flush() — because the backends' unregister paths all act synchronously or with trivial state, and a late flush would be surprising for a "release this grab now" API.


The documentation for this class was generated from the following file: