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

Manual zone-layout registry + per-context assignment store. More...

#include <phosphor-zones/include/PhosphorZones/LayoutRegistry.h>

Inheritance diagram for PhosphorZones::LayoutRegistry:
[legend]

Signals

void layoutsChanged ()
 
void layoutDirectoryChanged ()
 
void layoutsLoaded ()
 
void layoutsSaved ()
 
- Signals inherited from PhosphorZones::IZoneLayoutRegistry
void layoutAdded (Layout *layout)
 
void layoutRemoved (Layout *layout)
 
void activeLayoutChanged (Layout *layout)
 
void layoutAssigned (const QString &screenId, int virtualDesktop, Layout *layout)
 
- Signals inherited from PhosphorLayout::ILayoutSourceRegistry
void contentsChanged ()
 Emitted when the set of layouts this registry produces changes in any way that invalidates cached previews — entries added, removed, renamed, or re-parameterised.
 

Public Member Functions

 LayoutRegistry (PhosphorWindowRules::WindowRuleStore *ruleStore, QString layoutSubdirectory, QObject *parent=nullptr)
 
 ~LayoutRegistry () override
 
int layoutCount () const override
 
QVector< Layout * > layouts () const override
 Enumerate every known layout.
 
Layoutlayout (int index) const override
 
LayoutlayoutById (const QUuid &id) const override
 Resolve a layout by its stable UUID.
 
LayoutlayoutByName (const QString &name) const override
 
void addLayout (Layout *layout) override
 
void removeLayout (Layout *layout) override
 
void removeLayoutById (const QUuid &id) override
 
LayoutduplicateLayout (Layout *source) override
 
LayoutactiveLayout () const override
 
void setActiveLayout (Layout *layout) override
 
void setActiveLayoutById (const QUuid &id) override
 
QString layoutDirectory () const
 
void setLayoutDirectory (const QString &directory)
 
void loadLayouts ()
 
void saveLayouts ()
 
void saveLayout (Layout *layout)
 
void importLayout (const QString &filePath)
 
void exportLayout (Layout *layout, const QString &filePath)
 
void loadAssignments ()
 
void saveAssignments ()
 
LayoutdefaultLayout () const override
 Resolve the effective default layout.
 
void setDefaultLayoutIdProvider (std::function< QString()> provider)
 Inject a callback that returns the user-configured default layout id (or empty if unset).
 
void setDefaultAutotileAlgorithmProvider (std::function< QString()> provider)
 Inject a callback that returns the user-configured default autotile algorithm id (or empty if autotile is not the user's active default).
 
void setSnappingPreferredProvider (std::function< bool()> provider)
 Inject a callback that returns true when Snapping is the user's preferred default mode (regardless of whether a default snapping layout id is configured).
 
void setDefaultAssignmentSuppressedProvider (std::function< bool()> provider)
 Inject a callback that returns true when the user has opted to suppress the synthesized level-1 default layout assignment globally.
 
bool snappingPreferred () const
 True when the snapping-preferred provider is wired AND reports true — i.e.
 
LayoutpreviousLayout () const
 Get the previous active layout (before the most recent setActiveLayout).
 
void assignLayout (const QString &screenId, int virtualDesktop, const QString &activity, Layout *layout)
 
void assignLayoutById (const QString &screenId, int virtualDesktop, const QString &activity, const QString &layoutId)
 
void setAssignmentEntryDirect (const QString &screenId, int virtualDesktop, const QString &activity, const AssignmentEntry &entry)
 Store a full entry directly (from KCM via D-Bus).
 
LayoutlayoutForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
 Cascade-resolve the manual layout for screenId.
 
LayoutresolveLayoutForScreen (const QString &screenId) const override
 Resolve layout for screenId using the current desktop/activity context.
 
ContextGapOverride resolveContextGaps (const QString &screenId, int virtualDesktop, const QString &activity) const override
 Resolve the per-context gap override for (screen, desktop, activity) by evaluating a windowless WindowQuery through the RuleEvaluator and reading the gap action slots (ZonePadding / OuterGap / UsePerSideOuterGap / per-side).
 
bool resolveContextLocked (const QString &screenId, int virtualDesktop, const QString &activity) const override
 Resolve whether a context rule locks the active layout for the (screen, desktop, activity) context by evaluating a windowless WindowQuery through the RuleEvaluator and reading the ActionSlot::Locked slot.
 
std::optional< bool > resolveContextDefaultAssignment (const QString &screenId, int virtualDesktop, const QString &activity) const
 Resolve a per-context override of the global default-layout-assignment baseline for the (screen, desktop, activity) context by evaluating a windowless WindowQuery and reading the ActionSlot::DefaultAssignment slot.
 
ContextOverlayOverride resolveContextOverlay (const QString &screenId, int virtualDesktop, const QString &activity) const override
 Resolve the per-context overlay-property override (shader / style) for (screen, desktop, activity) by evaluating a windowless WindowQuery and reading the OverlayShader / OverlayStyle slots.
 
void clearAssignment (const QString &screenId, int virtualDesktop=0, const QString &activity=QString())
 
bool hasExplicitAssignment (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
 True iff a context-assignment rule whose match is exactly this (screen, desktop, activity) tuple's shape exists in the rule set — regardless of the rule's enabled state.
 
QString assignmentIdForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
 Raw assignment id for a (screen, desktop, activity) context.
 
AssignmentEntry assignmentEntryForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
 Full entry for a (screen, desktop, activity) context.
 
AssignmentEntry::Mode modeForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
 
bool isContextActiveLayoutSuppressed (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
 True iff the context has NO active layout specifically because the default assignment is suppressed — globally (see setDefaultAssignmentSuppressedProvider) or by a per-context DefaultLayoutAssignment rule.
 
bool isDefaultAssignmentSuppressedForContext (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
 True iff the SYNTHESIZED default (the level-1 provider layout / autotile algorithm) is suppressed for this context — a per-context DefaultLayoutAssignment override decides locally (suppress → true, allow → false), otherwise the global suppress setting.
 
QString snappingLayoutForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
 Per-field cascade readers — return the named field from the first entry in the cascade where it is non-empty.
 
QString tilingAlgorithmForScreen (const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
 Raw id of the tiling algorithm active for the (screenId, virtualDesktop, activity) context, or empty when none resolves.
 
void clearAutotileAssignments ()
 Flip mode to Snapping for every entry currently in Autotile (preserves snappingLayout + tilingAlgorithm).
 
void setAllScreenAssignments (const QHash< QString, QString > &assignments)
 Batch setters - clear existing, set new, save once at end.
 
void setAllDesktopAssignments (const QHash< QPair< QString, int >, QString > &assignments)
 
void setAllActivityAssignments (const QHash< QPair< QString, QString >, QString > &assignments)
 
void setAllCombinedAssignments (const QHash< CombinedAssignmentKey, QString > &assignments)
 Combined-context (screen + desktop + activity) batch setter — the triple-axis sibling of the Activity / Desktop batches.
 
QHash< QPair< QString, int >, QString > desktopAssignments () const
 
QHash< QPair< QString, QString >, QString > activityAssignments () const
 
QHash< CombinedAssignmentKey, QString > combinedAssignments () const
 Strict Combined-context reader.
 
LayoutlayoutForShortcut (AssignmentEntry::Mode mode, int number) const
 
void applyQuickLayout (AssignmentEntry::Mode mode, int number, const QString &screenId)
 
void setQuickLayoutSlot (AssignmentEntry::Mode mode, int number, const QString &layoutId)
 
void setAllQuickLayoutSlots (AssignmentEntry::Mode mode, const QHash< int, QString > &slots)
 
QHash< int, QString > quickLayoutSlots (AssignmentEntry::Mode mode) const
 
void cycleToPreviousLayout (const QString &screenId)
 
void cycleToNextLayout (const QString &screenId)
 
void createBuiltInLayouts ()
 
QVector< Layout * > builtInLayouts () const
 
int currentVirtualDesktop () const override
 
QString currentActivity () const override
 
void setCurrentVirtualDesktop (int desktop)
 
int currentVirtualDesktopForScreen (const QString &screenId) const override
 This screen's current virtual desktop, falling back to the global m_currentVirtualDesktop when no per-output value is set (#648).
 
void setCurrentVirtualDesktopForScreen (const QString &screenId, int desktop)
 Record a single screen's current virtual desktop (per-output virtual desktops).
 
void clearCurrentVirtualDesktopForScreen (const QString &screenId)
 Drop a screen's per-output desktop, reverting it to the global value.
 
void setCurrentActivity (const QString &activity)
 
void saveAutotileOverrides (const QString &algorithmId, const QJsonObject &overrides)
 
QJsonObject loadAutotileOverrides (const QString &algorithmId) const override
 Per-algorithm autotile settings (gaps, shader, hiddenFromSelector, …) stored in the unified layout-settings.json sidecar, keyed by raw algorithm id.
 
void seedDefaultLayoutSettingsIfFresh (const QJsonObject &defaults)
 Seed curated default picker visibility into the sidecar, but ONLY on a fresh install — when neither layout-settings.json nor the legacy autotile-overrides.json exists.
 
int contextResolveCacheSize () const
 Current entry count in the resolveAssignmentEntry hot-path cache.
 
- Public Member Functions inherited from PhosphorZones::IZoneLayoutRegistry
 IZoneLayoutRegistry (QObject *parent=nullptr)
 
 ~IZoneLayoutRegistry () override
 
- Public Member Functions inherited from PhosphorLayout::ILayoutSourceRegistry
 ILayoutSourceRegistry (QObject *parent=nullptr)
 
 ~ILayoutSourceRegistry () override
 

Static Public Attributes

static constexpr QLatin1String QuickSlotsSnappingKey {"snapping"}
 quicklayouts.json top-level keys: one nested slot object per tiling mode.
 
static constexpr QLatin1String QuickSlotsAutotileKey {"autotile"}
 

Detailed Description

Manual zone-layout registry + per-context assignment store.

Concrete counterpart to IZoneLayoutRegistry - mirrors the PhosphorTiles AlgorithmRegistry shape (interface for the provider contract, one concrete class for everything else). Composition roots construct one instance per process and inject it into every consumer; there is no process-global singleton.

Responsibilities:

  • In-memory catalog of Layout instances (enumeration, add, remove, duplicate, active-layout selection - inherited from IZoneLayoutRegistry).
  • Per-context AssignmentEntry resolution keyed by (screenId, virtualDesktop, activity), with cascading fallback (narrower keys beat wider keys; base screen is the widest). The assignment authority is the injected PhosphorWindowRules::WindowRuleStore — each per-context assignment is a context-only WindowRule and the cascade is the evaluator's descending-priority walk.
  • Numbered quick-layout shortcut slots (1..9), persisted to a quicklayouts.json sidecar beside the rule store's file.
  • Built-in layout templates (columns, rows, grid, priority, focus).
  • JSON-file persistence for layouts.

Constructor & Destructor Documentation

◆ LayoutRegistry()

PhosphorZones::LayoutRegistry::LayoutRegistry ( PhosphorWindowRules::WindowRuleStore *  ruleStore,
QString  layoutSubdirectory,
QObject *  parent = nullptr 
)
Parameters
ruleStoreBorrowed unified WindowRule store. Required - asserted non-null. The store's PhosphorWindowRules::WindowRuleSet is the single source of truth for every per-context assignment; the registry resolves layoutForScreen / assignmentEntryForScreen and the per-mode/snapping/ tiling derivatives by building a windowless PhosphorWindowRules::WindowQuery and evaluating it through PhosphorWindowRules::RuleEvaluator. Mutators (assignLayout etc.) translate to context-rule upserts via ContextRuleBridge and persist through the store. The caller owns the store and must outlive the registry.
layoutSubdirectoryXDG-relative path used for layout JSON discovery (e.g. "plasmazones/layouts"). The registry writes to QStandardPaths::writableLocation(GenericDataLocation)/<subdir> and reads the union of every GenericDataLocation entry containing that subdirectory, so system copies (in /usr/share/ <subdir>) provide built-ins while the user-writable copy overrides them. Required - asserted non-empty. Quick-layout slots persist to a quicklayouts.json sibling file in this directory.
parentQt parent.
Note
Required post-construction call order. The constructor does NOT read the quick-layout sidecar — loadAssignments must be called once after construction (and after loadLayouts) for the numbered quick-layout slots to be populated; without it, layoutForShortcut / applyQuickLayout silently see empty slots. The per-context assignment cascade itself needs no such call: the injected ruleStore loads its rule set in its own constructor, so assignment resolution is live immediately. loadAssignments additionally re-reads the shared rule store from disk, so composition roots also call it to pick up cross-process rule edits. The daemon composition root calls loadLayouts then loadAssignments; the editor / settings roots, which drive quick slots over D-Bus rather than locally, deliberately skip it.

◆ ~LayoutRegistry()

PhosphorZones::LayoutRegistry::~LayoutRegistry ( )
override

Member Function Documentation

◆ activeLayout()

Layout * PhosphorZones::LayoutRegistry::activeLayout ( ) const
inlineoverridevirtual

◆ activityAssignments()

QHash< QPair< QString, QString >, QString > PhosphorZones::LayoutRegistry::activityAssignments ( ) const

◆ addLayout()

void PhosphorZones::LayoutRegistry::addLayout ( Layout layout)
overridevirtual
Parameters
layoutOwnership transferred - the registry adopts layout and is responsible for its lifetime from this call on.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ applyQuickLayout()

void PhosphorZones::LayoutRegistry::applyQuickLayout ( AssignmentEntry::Mode  mode,
int  number,
const QString &  screenId 
)

◆ assignLayout()

void PhosphorZones::LayoutRegistry::assignLayout ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity,
Layout layout 
)

◆ assignLayoutById()

void PhosphorZones::LayoutRegistry::assignLayoutById ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity,
const QString &  layoutId 
)

◆ assignmentEntryForScreen()

AssignmentEntry PhosphorZones::LayoutRegistry::assignmentEntryForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const

Full entry for a (screen, desktop, activity) context.

Shares the per-context cascade with layoutForScreen up through level-2 (per-screen base entry), but the two diverge at level-1 (global defaults): on cascade-miss this method synthesizes from BOTH providers - snap provider first, then autotile provider - using the same precedence as assignmentIdForScreen, while layoutForScreen consults only the snap provider via defaultLayout. This means a caller mixing both APIs may see entry.mode == Autotile with layoutForScreen returning a snap Layout* (the historical pre-368 fallback shape, preserved so the autotile engine's assignmentIdForScreen-driven activation path remains mode-aware while the snap engine's layoutForScreen-driven path stays Layout*-typed). Returns a default-constructed entry when neither provider returns a value. Callers that need raw stored state without the synth fallback must gate with hasExplicitAssignment.

◆ assignmentIdForScreen()

QString PhosphorZones::LayoutRegistry::assignmentIdForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const
overridevirtual

Raw assignment id for a (screen, desktop, activity) context.

Returns the stored string (manual-layout UUID or "autotile:<algorithmId>") without resolving to a Layout*. On cascade-miss, falls through to the level-1 global defaults (snap provider first, then autotile provider; see setDefaultLayoutIdProvider / setDefaultAutotileAlgorithmProvider). Empty when every cascade level misses AND both providers return empty. Callers that need to distinguish "stored" from "synthesized fallback" must pair this with hasExplicitAssignment.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ builtInLayouts()

QVector< Layout * > PhosphorZones::LayoutRegistry::builtInLayouts ( ) const

◆ clearAssignment()

void PhosphorZones::LayoutRegistry::clearAssignment ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
)

◆ clearAutotileAssignments()

void PhosphorZones::LayoutRegistry::clearAutotileAssignments ( )

Flip mode to Snapping for every entry currently in Autotile (preserves snappingLayout + tilingAlgorithm).

Emits layoutAssigned per affected screen; one save at end.

◆ clearCurrentVirtualDesktopForScreen()

void PhosphorZones::LayoutRegistry::clearCurrentVirtualDesktopForScreen ( const QString &  screenId)
inline

Drop a screen's per-output desktop, reverting it to the global value.

◆ combinedAssignments()

QHash< CombinedAssignmentKey, QString > PhosphorZones::LayoutRegistry::combinedAssignments ( ) const

Strict Combined-context reader.

See setAllCombinedAssignments for the round-trip contract. Returns ONLY rules with all three dimensions pinned (screen + desktop + activity).

◆ contextResolveCacheSize()

int PhosphorZones::LayoutRegistry::contextResolveCacheSize ( ) const
inline

Current entry count in the resolveAssignmentEntry hot-path cache.

Used by tests to verify the cache populates and invalidates against rule-set revision bumps. Not for production callers — the value drifts as cursor-move resolves come in. Return type is int because the cache is bounded at 256 entries (kMaxEntries in layoutregistry_assignments.cpp), well within int range — keeps test assertions free of the qsizetype int widening dance.

◆ createBuiltInLayouts()

void PhosphorZones::LayoutRegistry::createBuiltInLayouts ( )

◆ currentActivity()

QString PhosphorZones::LayoutRegistry::currentActivity ( ) const
inlineoverridevirtual

◆ currentVirtualDesktop()

int PhosphorZones::LayoutRegistry::currentVirtualDesktop ( ) const
inlineoverridevirtual

◆ currentVirtualDesktopForScreen()

int PhosphorZones::LayoutRegistry::currentVirtualDesktopForScreen ( const QString &  screenId) const
inlineoverridevirtual

This screen's current virtual desktop, falling back to the global m_currentVirtualDesktop when no per-output value is set (#648).

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ cycleToNextLayout()

void PhosphorZones::LayoutRegistry::cycleToNextLayout ( const QString &  screenId)

◆ cycleToPreviousLayout()

void PhosphorZones::LayoutRegistry::cycleToPreviousLayout ( const QString &  screenId)

◆ defaultLayout()

Layout * PhosphorZones::LayoutRegistry::defaultLayout ( ) const
overridevirtual

Resolve the effective default layout.

Returns, in order:

  1. The layout whose id matches the default-id provider (if set and non-empty).
  2. The first registered layout (by defaultOrder).
  3. nullptr if no layouts are registered.
Note
Snap-only fallback. Unlike assignmentIdForScreen and assignmentEntryForScreen - which on cascade-miss consult both the snap and autotile level-1 providers - this method only consults the snap provider, because Layout has no autotile counterpart. Autotile-mode resolution is the autotile engine's job, driven by assignmentIdForScreen returning an "autotile:<algo>" id from the level-1 cascade.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ desktopAssignments()

QHash< QPair< QString, int >, QString > PhosphorZones::LayoutRegistry::desktopAssignments ( ) const

◆ duplicateLayout()

Layout * PhosphorZones::LayoutRegistry::duplicateLayout ( Layout source)
overridevirtual
Parameters
sourceBorrowed - caller retains ownership.
Returns
Newly allocated copy; ownership transferred to the registry (mirrors addLayout semantics). Returns nullptr if source is unknown.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ exportLayout()

void PhosphorZones::LayoutRegistry::exportLayout ( Layout layout,
const QString &  filePath 
)

◆ hasExplicitAssignment()

bool PhosphorZones::LayoutRegistry::hasExplicitAssignment ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const

True iff a context-assignment rule whose match is exactly this (screen, desktop, activity) tuple's shape exists in the rule set — regardless of the rule's enabled state.

A DISABLED explicit assignment is still an explicit assignment: this reports stored intent, not the effective cascade result. It therefore intentionally diverges from assignmentEntryForScreen / the resolvers, which skip disabled rules and would synthesize the provider default for a context whose only rule is disabled.

◆ importLayout()

void PhosphorZones::LayoutRegistry::importLayout ( const QString &  filePath)

◆ isContextActiveLayoutSuppressed()

bool PhosphorZones::LayoutRegistry::isContextActiveLayoutSuppressed ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const
overridevirtual

True iff the context has NO active layout specifically because the default assignment is suppressed — globally (see setDefaultAssignmentSuppressedProvider) or by a per-context DefaultLayoutAssignment rule.

Returns false when an active layout exists (an explicit assignment, or a default forced through by an "allow" rule), AND false for OTHER empty-assignment states (e.g. snapping enabled with no global default layout id, where callers still fall back to defaultLayout). This lets daemon overlay / display paths — which otherwise fall back to defaultLayout on a missing assignment — treat a suppressed context as "no layout, engine inactive" without regressing the no-global-default case. Mode-agnostic: a suppressed context has no layout for either engine.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ isDefaultAssignmentSuppressedForContext()

bool PhosphorZones::LayoutRegistry::isDefaultAssignmentSuppressedForContext ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const

True iff the SYNTHESIZED default (the level-1 provider layout / autotile algorithm) is suppressed for this context — a per-context DefaultLayoutAssignment override decides locally (suppress → true, allow → false), otherwise the global suppress setting.

Unlike isContextActiveLayoutSuppressed this does NOT consider whether a mode-only assignment rule covers the context: such a rule sets the mode but still draws its layout / algorithm from the default. The autotile activation path uses this to refuse to tile a bare "autotile:" context (mode set, no concrete algorithm) with the global default algorithm when the default is suppressed — a concrete assigned algorithm is explicit and always tiles.

◆ layout()

Layout * PhosphorZones::LayoutRegistry::layout ( int  index) const
overridevirtual

◆ layoutById()

Layout * PhosphorZones::LayoutRegistry::layoutById ( const QUuid &  id) const
overridevirtual

Resolve a layout by its stable UUID.

Returns nullptr when no layout with that id is known to the registry.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ layoutByName()

Layout * PhosphorZones::LayoutRegistry::layoutByName ( const QString &  name) const
overridevirtual

◆ layoutCount()

int PhosphorZones::LayoutRegistry::layoutCount ( ) const
inlineoverridevirtual

◆ layoutDirectory()

QString PhosphorZones::LayoutRegistry::layoutDirectory ( ) const
inline

◆ layoutDirectoryChanged

void PhosphorZones::LayoutRegistry::layoutDirectoryChanged ( )
signal

◆ layoutForScreen()

Layout * PhosphorZones::LayoutRegistry::layoutForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const
overridevirtual

Cascade-resolve the manual layout for screenId.

Returns defaultLayout() when no explicit assignment matches.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ layoutForShortcut()

Layout * PhosphorZones::LayoutRegistry::layoutForShortcut ( AssignmentEntry::Mode  mode,
int  number 
) const

◆ layouts()

QVector< Layout * > PhosphorZones::LayoutRegistry::layouts ( ) const
inlineoverridevirtual

Enumerate every known layout.

Borrowed pointers - owned by the concrete registry (typically LayoutManager). Order is the registry's natural iteration order.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ layoutsChanged

void PhosphorZones::LayoutRegistry::layoutsChanged ( )
signal

◆ layoutsLoaded

void PhosphorZones::LayoutRegistry::layoutsLoaded ( )
signal

◆ layoutsSaved

void PhosphorZones::LayoutRegistry::layoutsSaved ( )
signal

◆ loadAssignments()

void PhosphorZones::LayoutRegistry::loadAssignments ( )

◆ loadAutotileOverrides()

QJsonObject PhosphorZones::LayoutRegistry::loadAutotileOverrides ( const QString &  algorithmId) const
overridevirtual

Per-algorithm autotile settings (gaps, shader, hiddenFromSelector, …) stored in the unified layout-settings.json sidecar, keyed by raw algorithm id.

Default returns empty so non-persisting implementers and the unified-list builder degrade to "no overrides". Concrete registries (LayoutRegistry) read the sidecar.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ loadLayouts()

void PhosphorZones::LayoutRegistry::loadLayouts ( )

◆ modeForScreen()

AssignmentEntry::Mode PhosphorZones::LayoutRegistry::modeForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const

◆ previousLayout()

Layout * PhosphorZones::LayoutRegistry::previousLayout ( ) const
inline

Get the previous active layout (before the most recent setActiveLayout).

On first call, equals activeLayout. Used by resnap-to-new-layout.

◆ quickLayoutSlots()

QHash< int, QString > PhosphorZones::LayoutRegistry::quickLayoutSlots ( AssignmentEntry::Mode  mode) const
inline

◆ removeLayout()

void PhosphorZones::LayoutRegistry::removeLayout ( Layout layout)
overridevirtual
Parameters
layoutBorrowed - caller hands the pointer in; the registry un-registers it and schedules deletion via deleteLater (matching how the registry adopted it in addLayout). Callers must drop any other references before this call returns.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ removeLayoutById()

void PhosphorZones::LayoutRegistry::removeLayoutById ( const QUuid &  id)
overridevirtual

◆ resolveContextDefaultAssignment()

std::optional< bool > PhosphorZones::LayoutRegistry::resolveContextDefaultAssignment ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity 
) const

Resolve a per-context override of the global default-layout-assignment baseline for the (screen, desktop, activity) context by evaluating a windowless WindowQuery and reading the ActionSlot::DefaultAssignment slot.

Per-slot read (mirrors resolveContextLocked): returns the winning DefaultLayoutAssignment action's boolean value (true = allow / force the default through, false = suppress), or std::nullopt when no matching rule fills the slot (the context then follows the global setting). Same owner-thread affinity as the rest of the registry.

◆ resolveContextGaps()

ContextGapOverride PhosphorZones::LayoutRegistry::resolveContextGaps ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity 
) const
overridevirtual

Resolve the per-context gap override for (screen, desktop, activity) by evaluating a windowless WindowQuery through the RuleEvaluator and reading the gap action slots (ZonePadding / OuterGap / UsePerSideOuterGap / per-side).

Unlike resolveAssignmentEntry this is a PER-SLOT read across all matching context rules (not a single winning rule), so independent gap rules compose and there is no engine-mode gate. Returns an all-unset ContextGapOverride when no matching rule fills a gap slot. Same owner-thread affinity as the rest of the registry.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ resolveContextLocked()

bool PhosphorZones::LayoutRegistry::resolveContextLocked ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity 
) const
overridevirtual

Resolve whether a context rule locks the active layout for the (screen, desktop, activity) context by evaluating a windowless WindowQuery through the RuleEvaluator and reading the ActionSlot::Locked slot.

Mode-agnostic per-slot read (mirrors resolveContextGaps); returns true iff the winning Locked-slot action's value is true. Same owner-thread affinity as the rest of the registry.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ resolveContextOverlay()

ContextOverlayOverride PhosphorZones::LayoutRegistry::resolveContextOverlay ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity 
) const
overridevirtual

Resolve the per-context overlay-property override (shader / style) for (screen, desktop, activity) by evaluating a windowless WindowQuery and reading the OverlayShader / OverlayStyle slots.

Per-slot read (mirrors resolveContextGaps), so independent overlay rules compose; returns an all-unset ContextOverlayOverride when no matching rule fills an overlay slot. Same owner-thread affinity as the rest of the registry.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

◆ resolveLayoutForScreen()

Layout * PhosphorZones::LayoutRegistry::resolveLayoutForScreen ( const QString &  screenId) const
inlineoverridevirtual

Resolve layout for screenId using the current desktop/activity context.

layoutForScreen already falls back to defaultLayout internally when no explicit assignment matches, so this helper is a thin context-filling forwarder.

Implements PhosphorZones::IZoneLayoutRegistry.

◆ saveAssignments()

void PhosphorZones::LayoutRegistry::saveAssignments ( )

◆ saveAutotileOverrides()

void PhosphorZones::LayoutRegistry::saveAutotileOverrides ( const QString &  algorithmId,
const QJsonObject &  overrides 
)

◆ saveLayout()

void PhosphorZones::LayoutRegistry::saveLayout ( Layout layout)

◆ saveLayouts()

void PhosphorZones::LayoutRegistry::saveLayouts ( )

◆ seedDefaultLayoutSettingsIfFresh()

void PhosphorZones::LayoutRegistry::seedDefaultLayoutSettingsIfFresh ( const QJsonObject &  defaults)

Seed curated default picker visibility into the sidecar, but ONLY on a fresh install — when neither layout-settings.json nor the legacy autotile-overrides.json exists.

defaults is keyed exactly as the sidecar (manual layouts by UUID, algorithms by "autotile:<id>"). Existing installs are never reseeded. Call before loadLayouts so the merge picks up the seeded entries.

◆ setActiveLayout()

void PhosphorZones::LayoutRegistry::setActiveLayout ( Layout layout)
overridevirtual

◆ setActiveLayoutById()

void PhosphorZones::LayoutRegistry::setActiveLayoutById ( const QUuid &  id)
overridevirtual

◆ setAllActivityAssignments()

void PhosphorZones::LayoutRegistry::setAllActivityAssignments ( const QHash< QPair< QString, QString >, QString > &  assignments)

◆ setAllCombinedAssignments()

void PhosphorZones::LayoutRegistry::setAllCombinedAssignments ( const QHash< CombinedAssignmentKey, QString > &  assignments)

Combined-context (screen + desktop + activity) batch setter — the triple-axis sibling of the Activity / Desktop batches.

Combined rules cannot round-trip through setAllActivityAssignments (the (screen, activity) key drops the desktop dimension); this API keeps them as first-class. Pure-Activity, pure-Desktop, and Monitor-only rules are NOT touched — they remain in their own batches.

◆ setAllDesktopAssignments()

void PhosphorZones::LayoutRegistry::setAllDesktopAssignments ( const QHash< QPair< QString, int >, QString > &  assignments)

◆ setAllQuickLayoutSlots()

void PhosphorZones::LayoutRegistry::setAllQuickLayoutSlots ( AssignmentEntry::Mode  mode,
const QHash< int, QString > &  slots 
)

◆ setAllScreenAssignments()

void PhosphorZones::LayoutRegistry::setAllScreenAssignments ( const QHash< QString, QString > &  assignments)

Batch setters - clear existing, set new, save once at end.

◆ setAssignmentEntryDirect()

void PhosphorZones::LayoutRegistry::setAssignmentEntryDirect ( const QString &  screenId,
int  virtualDesktop,
const QString &  activity,
const AssignmentEntry entry 
)

Store a full entry directly (from KCM via D-Bus).

Stores regardless of isValid() - mode-only entries are valid when explicitly set.

◆ setCurrentActivity()

void PhosphorZones::LayoutRegistry::setCurrentActivity ( const QString &  activity)
inline

◆ setCurrentVirtualDesktop()

void PhosphorZones::LayoutRegistry::setCurrentVirtualDesktop ( int  desktop)
inline

◆ setCurrentVirtualDesktopForScreen()

void PhosphorZones::LayoutRegistry::setCurrentVirtualDesktopForScreen ( const QString &  screenId,
int  desktop 
)
inline

Record a single screen's current virtual desktop (per-output virtual desktops).

Pushed by the daemon's per-screen desktop handler.

◆ setDefaultAssignmentSuppressedProvider()

void PhosphorZones::LayoutRegistry::setDefaultAssignmentSuppressedProvider ( std::function< bool()>  provider)

Inject a callback that returns true when the user has opted to suppress the synthesized level-1 default layout assignment globally.

When the callback returns true, resolveDefaultAssignmentEntry yields a default-constructed (invalid) entry on cascade-miss instead of synthesizing one from the snap / autotile / snapping-preferred providers — i.e. a context with no explicit assignment gets NO active layout and no engine activates until the user assigns one. This is the same effective state as a system with every provider returning empty, so the daemon's existing "empty entry ⇒ no default" handling covers it unchanged.

The global baseline is overridable PER CONTEXT by a DefaultLayoutAssignment rule (see resolveContextDefaultAssignment): a false rule suppresses a single context even when this provider is off, a true rule forces the default through even when this provider is on.

Optional. When unset, the resolver behaves as before (never suppresses). Same threading rules as the other providers.

◆ setDefaultAutotileAlgorithmProvider()

void PhosphorZones::LayoutRegistry::setDefaultAutotileAlgorithmProvider ( std::function< QString()>  provider)

Inject a callback that returns the user-configured default autotile algorithm id (or empty if autotile is not the user's active default).

Symmetric to setDefaultLayoutIdProvider, completing the level-1 (global) tier of the assignment hierarchy:

  1. global default - snap layout id AND autotile algorithm id
  2. monitor-level assignment
  3. virtual-desktop-level assignment

On cascade-miss, assignmentIdForScreen and assignmentEntryForScreen consult the snap provider first, then the autotile provider; the first non-empty return wins. Providers are pass-throughs from the composition root's settings layer - each is expected to return empty when its mode is disabled in settings, which means "autotile-only" users see autotile as the natural cascade fallback (snap provider returns empty → autotile wins) without any mode-priority logic in the composition root. layoutForScreen ignores the autotile provider (it returns a snap Layout*, which has no autotile counterpart) and falls back to defaultLayout as before.

Invoked on every cascade-miss with no caching, so providers can re-read settings cheaply per call. Pass an empty function to disable.

Thread-safety: the provider is read on every cascade query and swapped via this setter without synchronization; both must run on the same thread (the LayoutRegistry's owner thread, typically the main Qt thread). The same applies to setDefaultLayoutIdProvider.

◆ setDefaultLayoutIdProvider()

void PhosphorZones::LayoutRegistry::setDefaultLayoutIdProvider ( std::function< QString()>  provider)

Inject a callback that returns the user-configured default layout id (or empty if unset).

Used by composition roots that own a settings object the lib doesn't know about. The registry invokes the callback on every defaultLayout call (no caching) so the callback can re-read settings on each call. Pass an empty function to disable.

◆ setLayoutDirectory()

void PhosphorZones::LayoutRegistry::setLayoutDirectory ( const QString &  directory)

◆ setQuickLayoutSlot()

void PhosphorZones::LayoutRegistry::setQuickLayoutSlot ( AssignmentEntry::Mode  mode,
int  number,
const QString &  layoutId 
)

◆ setSnappingPreferredProvider()

void PhosphorZones::LayoutRegistry::setSnappingPreferredProvider ( std::function< bool()>  provider)

Inject a callback that returns true when Snapping is the user's preferred default mode (regardless of whether a default snapping layout id is configured).

Without this provider, resolveDefaultAssignmentEntry can only tell whether snap has a non-empty default layout id. When a user has snapping enabled but never configured a global default layout (a common, valid state - the user expects per-screen assignments to drive everything), the m_defaultLayoutIdProvider returns empty and the cascade silently falls through to the autotile branch - surfacing autotile content (e.g. "Tiling: Binary Split") to a user who never wanted autotile.

This provider lets the composition root express "snap mode is preferred" independently of "snap has a default layout". When it returns true, the resolver returns a Snapping entry with the (possibly empty) snappingLayout from m_defaultLayoutIdProvider - activeLayoutId() then yields empty, callers see "no assignment", and the OSD path correctly suppresses rather than falling back to autotile.

Optional. When unset, the resolver behaves as before (snap-id-non-empty → snap; else autotile if available; else empty). Same threading rules as the other two providers.

◆ snappingLayoutForScreen()

QString PhosphorZones::LayoutRegistry::snappingLayoutForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const

Per-field cascade readers — return the named field from the first entry in the cascade where it is non-empty.

Crucially, these do NOT route through the activeLayoutId-based reject filter that assignmentEntryForScreen uses, so a "stored-but-inactive" preference (e.g. an entry shaped like {mode=Snapping, snap="", tile="cluster"} that the partial-update path can produce) IS visible to the field-getter that targets the populated field. On total cascade miss they synthesize from the global default (snap provider for snap, autotile provider for tile) and may still return empty if no provider has a value.

◆ snappingPreferred()

bool PhosphorZones::LayoutRegistry::snappingPreferred ( ) const

True when the snapping-preferred provider is wired AND reports true — i.e.

snapping is globally enabled (the daemon wires the provider to ISettings::snappingEnabled). Mirrors the internal default-assignment branch's m_snappingPreferredProvider && m_snappingPreferredProvider() test, exposed so other engines can gate cross-engine coordination on the global snap toggle. When unset, returns false (no provider ⇒ not preferred).

◆ tilingAlgorithmForScreen()

QString PhosphorZones::LayoutRegistry::tilingAlgorithmForScreen ( const QString &  screenId,
int  virtualDesktop = 0,
const QString &  activity = QString() 
) const
overridevirtual

Raw id of the tiling algorithm active for the (screenId, virtualDesktop, activity) context, or empty when none resolves.

Used by the unified-list builder to keep the active algorithm visible in the picker even when it's been hidden (mirrors the active-layout exemption for manual layouts). Default empty for non-resolving implementers.

Reimplemented from PhosphorZones::IZoneLayoutRegistry.

Member Data Documentation

◆ QuickSlotsAutotileKey

constexpr QLatin1String PhosphorZones::LayoutRegistry::QuickSlotsAutotileKey {"autotile"}
staticconstexpr

◆ QuickSlotsSnappingKey

constexpr QLatin1String PhosphorZones::LayoutRegistry::QuickSlotsSnappingKey {"snapping"}
staticconstexpr

quicklayouts.json top-level keys: one nested slot object per tiling mode.

This is the ONLY on-disk shape — there is no flat legacy variant. Shared with the v3→v4 schema migration (configmigration.cpp), which writes the same nested format, so reader and migration cannot drift.


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