Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
LayoutRegistry.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4// FILE-SIZE EXCEPTION (sanctioned): LayoutRegistry is the single owner of
5// layout storage, per-context assignments, quick slots, and the context
6// resolve cascade, and this is an INSTALLED public header — carving the
7// class in two would be an API break for third-party consumers the library
8// exists to serve. The implementation is already split by concern across
9// src/layoutregistry_*.cpp, and the member ordering here encodes which
10// state each of those files owns.
11
12#pragma once
13
19
20#include <PhosphorRules/RuleEvaluator.h>
21#include <PhosphorRules/RuleStore.h>
22
23#include <QHash>
24#include <QPair>
25#include <QString>
26#include <QUuid>
27#include <functional>
28#include <memory>
29#include <optional>
30
31namespace PhosphorZones {
32
33class ScrollingTemplateStore;
34
47{
48 QString screenId;
50 QString activity;
51
52 bool operator==(const CombinedAssignmentKey& other) const
53 {
54 return screenId == other.screenId && virtualDesktop == other.virtualDesktop && activity == other.activity;
55 }
56};
57
58inline size_t qHash(const CombinedAssignmentKey& key, size_t seed = 0) noexcept
59{
60 return qHashMulti(seed, key.screenId, key.virtualDesktop, key.activity);
61}
62
88class PHOSPHORZONES_EXPORT LayoutRegistry : public IZoneLayoutRegistry
89{
90 Q_OBJECT
91
92 Q_PROPERTY(int layoutCount READ layoutCount NOTIFY layoutsChanged)
93 // `activeLayout` Q_PROPERTY moved to IZoneLayoutRegistry alongside its
94 // NOTIFY signal so the contract is visible to interface consumers.
95 Q_PROPERTY(QString layoutDirectory READ layoutDirectory WRITE setLayoutDirectory NOTIFY layoutDirectoryChanged)
96
97public:
139 LayoutRegistry(PhosphorRules::RuleStore* ruleStore, QString layoutSubdirectory, QObject* parent = nullptr);
140 ~LayoutRegistry() override;
141
142 // ─── IZoneLayoutRegistry ──────────────────────────────────────────────
143
144 int layoutCount() const override
145 {
146 return m_layouts.size();
147 }
148 QVector<Layout*> layouts() const override
149 {
150 return m_layouts;
151 }
152 Layout* layout(int index) const override;
153 Layout* layoutById(const QUuid& id) const override;
154 Layout* layoutByName(const QString& name) const override;
155
156 Q_INVOKABLE void addLayout(Layout* layout) override;
157 Q_INVOKABLE bool removeLayout(Layout* layout) override;
158 Q_INVOKABLE bool removeLayoutById(const QUuid& id) override;
159 Q_INVOKABLE Layout* duplicateLayout(Layout* source) override;
160
165 static QString duplicateNameSuffix()
166 {
167 return QStringLiteral(" (Copy)");
168 }
169
170 Layout* activeLayout() const override
171 {
172 return m_activeLayout;
173 }
174 Q_INVOKABLE void setActiveLayout(Layout* layout) override;
175 Q_INVOKABLE void setActiveLayoutById(const QUuid& id) override;
176
177 // ─── Layout persistence (disk JSON) ───────────────────────────────────
178
179 QString layoutDirectory() const
180 {
181 return m_layoutDirectory;
182 }
183 void setLayoutDirectory(const QString& directory);
184
185 Q_INVOKABLE void loadLayouts();
186 Q_INVOKABLE void saveLayouts();
187 void saveLayout(Layout* layout);
188
198 Q_INVOKABLE Layout* importLayout(const QString& filePath);
199
213 static bool isLayoutJsonValid(const QJsonObject& json, const QString& context);
214
221 Q_INVOKABLE bool exportLayout(Layout* layout, const QString& filePath);
222
223 // ─── Assignment persistence (via config backend) ──────────────────────
224
225 Q_INVOKABLE void loadAssignments();
226 Q_INVOKABLE void saveAssignments();
227
228 // ─── Default-layout resolution ────────────────────────────────────────
229
243 Q_INVOKABLE Layout* defaultLayout() const override;
244
254 void setDefaultLayoutIdProvider(std::function<QString()> provider);
255
289 void setDefaultAutotileAlgorithmProvider(std::function<QString()> provider);
290
315 std::function<std::optional<int>(const QString& screenId, int virtualDesktop, const QString& activity)>
316 provider);
317
333 void setScreenOrientationProvider(std::function<std::optional<QString>(const QString& screenId)> provider);
334
351 void setColorSchemeProvider(std::function<std::optional<QString>()> provider);
352
379 void setSnappingPreferredProvider(std::function<bool()> provider);
380
401 void setDefaultAssignmentSuppressedProvider(std::function<bool()> provider);
402
409 bool snappingPreferred() const;
410
411 // ─── Assignments (per-context routing) ────────────────────────────────
412
417 {
418 return m_previousLayout;
419 }
420
421 Q_INVOKABLE void assignLayout(const QString& screenId, int virtualDesktop, const QString& activity, Layout* layout);
422 Q_INVOKABLE void assignLayoutById(const QString& screenId, int virtualDesktop, const QString& activity,
423 const QString& layoutId);
424
428 void setAssignmentEntryDirect(const QString& screenId, int virtualDesktop, const QString& activity,
429 const AssignmentEntry& entry);
430
438 void assignScrollingTemplate(const QString& screenId, int virtualDesktop, const QString& activity,
439 const QString& templateId);
445 ScrollingTemplate scrollingTemplateForContext(const QString& screenId, int virtualDesktop,
446 const QString& activity) const override;
447
452 {
453 m_scrollingTemplateStore = store;
454 }
456 {
457 return m_scrollingTemplateStore;
458 }
459
465 void setDefaultScrollingTemplateProvider(std::function<QString()> provider)
466 {
467 m_defaultScrollingTemplateProvider = std::move(provider);
468 }
469
480 QString rulesVisibleActiveLayoutId(const QString& screenId, int virtualDesktop, const QString& activity) const;
481
482 Q_INVOKABLE Layout* layoutForScreen(const QString& screenId, int virtualDesktop = 0,
483 const QString& activity = QString()) const override;
484
489 Q_INVOKABLE Layout* resolveLayoutForScreen(const QString& screenId) const override
490 {
491 // Resolve against THIS screen's current virtual desktop (Plasma 6.7
492 // per-output virtual desktops, #648). Falls back to the global desktop
493 // when the screen has no per-output value, so every caller (all of which
494 // already pass a screenId) gets per-screen resolution with no edits.
495 return layoutForScreen(screenId, currentVirtualDesktopForScreen(screenId), m_currentActivity);
496 }
497
522 ContextGapOverride resolveContextGaps(const QString& screenId, int virtualDesktop, const QString& activity,
523 const QString& mode = QString()) const override;
524
531 bool resolveContextLocked(const QString& screenId, int virtualDesktop, const QString& activity) const override;
532
542 std::optional<bool> resolveContextDefaultAssignment(const QString& screenId, int virtualDesktop,
543 const QString& activity) const;
544
556 std::optional<bool> resolveContextOsdEnabled(const QString& screenId, int virtualDesktop,
557 const QString& activity) const;
558
576 std::optional<bool> resolveContextDragSelectorEnabled(const QString& screenId, int virtualDesktop,
577 const QString& activity) const override;
578
586 ContextOverlayOverride resolveContextOverlay(const QString& screenId, int virtualDesktop,
587 const QString& activity) const override;
588
597 ContextTilingParams resolveContextTilingParams(const QString& screenId, int virtualDesktop,
598 const QString& activity) const;
599
608 ContextScrollingParams resolveContextScrollingParams(const QString& screenId, int virtualDesktop,
609 const QString& activity) const;
610
615 QString screenOrientationToken(const QString& screenId) const
616 {
617 if (m_screenOrientationProvider) {
618 if (const auto token = m_screenOrientationProvider(screenId)) {
619 return *token;
620 }
621 }
622 return QString();
623 }
624
638 void stampScreenOrientation(PhosphorRules::WindowQuery& query, const QString& screenId) const
639 {
640 query.screenOrientation = screenOrientationToken(screenId);
641 }
642
654 QString colorSchemeToken() const
655 {
656 if (m_colorSchemeProvider) {
657 if (const auto token = m_colorSchemeProvider()) {
658 return *token;
659 }
660 }
661 return QString();
662 }
663
670 void stampColorScheme(PhosphorRules::WindowQuery& query) const
671 {
672 query.colorScheme = colorSchemeToken();
673 }
674
686 static QString contextCacheKeyToken(const QString& modeToken, const QString& activeLayoutId,
687 const QString& orientationToken, const QString& colorSchemeToken)
688 {
689 return escapeKeyComponent(modeToken) + QLatin1String("|al:") + escapeKeyComponent(activeLayoutId)
690 + QLatin1String("|or:") + escapeKeyComponent(orientationToken) + QLatin1String("|cs:")
691 + escapeKeyComponent(colorSchemeToken);
692 }
693
702 static QString assignmentCacheKeyToken(const std::optional<int>& tiledCount, const QString& orientationToken,
703 const QString& colorSchemeToken)
704 {
705 return (tiledCount ? (QLatin1String("twc:") + QString::number(*tiledCount)) : QString()) + QLatin1String("|or:")
706 + escapeKeyComponent(orientationToken) + QLatin1String("|cs:") + escapeKeyComponent(colorSchemeToken);
707 }
708
718 static QString escapeKeyComponent(const QString& component)
719 {
720 QString escaped = component;
721 escaped.replace(QLatin1Char('%'), QLatin1String("%25"));
722 escaped.replace(QLatin1Char('|'), QLatin1String("%7C"));
723 return escaped;
724 }
725
726 Q_INVOKABLE void clearAssignment(const QString& screenId, int virtualDesktop = 0,
727 const QString& activity = QString());
736 Q_INVOKABLE bool hasExplicitAssignment(const QString& screenId, int virtualDesktop = 0,
737 const QString& activity = QString()) const;
738
746 AssignmentEntry exactContextEntry(const QString& screenId, int virtualDesktop, const QString& activity) const;
747
759 bool exactContextDeclaresEngineMode(const QString& screenId, int virtualDesktop, const QString& activity) const;
760
774 Q_INVOKABLE QString assignmentIdForScreen(const QString& screenId, int virtualDesktop = 0,
775 const QString& activity = QString()) const override;
776
786 Q_INVOKABLE QString storedAssignmentIdForScreen(const QString& screenId, int virtualDesktop = 0,
787 const QString& activity = QString()) const;
788
806 AssignmentEntry assignmentEntryForScreen(const QString& screenId, int virtualDesktop = 0,
807 const QString& activity = QString()) const;
808
809 AssignmentEntry::Mode modeForScreen(const QString& screenId, int virtualDesktop = 0,
810 const QString& activity = QString()) const;
811
824 bool isContextActiveLayoutSuppressed(const QString& screenId, int virtualDesktop = 0,
825 const QString& activity = QString()) const override;
826
838 bool isDefaultAssignmentSuppressedForContext(const QString& screenId, int virtualDesktop = 0,
839 const QString& activity = QString()) const;
840
851 QString snappingLayoutForScreen(const QString& screenId, int virtualDesktop = 0,
852 const QString& activity = QString()) const;
853 QString tilingAlgorithmForScreen(const QString& screenId, int virtualDesktop = 0,
854 const QString& activity = QString()) const override;
861 QString scrollingTemplateLayoutForScreen(const QString& screenId, int virtualDesktop = 0,
862 const QString& activity = QString()) const;
868 bool scrollingTemplateExplicitlyNone(const QString& screenId, int virtualDesktop,
869 const QString& activity) const override;
870
878
894
896 void setAllScreenAssignments(const QHash<QString, QString>& assignments);
897 void setAllDesktopAssignments(const QHash<QPair<QString, int>, QString>& assignments);
898 void setAllActivityAssignments(const QHash<QPair<QString, QString>, QString>& assignments);
906 void setAllCombinedAssignments(const QHash<CombinedAssignmentKey, QString>& assignments);
907
914 QHash<QPair<QString, int>, AssignmentEntry> desktopAssignments() const;
915 QHash<QPair<QString, QString>, AssignmentEntry> activityAssignments() const;
919 QHash<CombinedAssignmentKey, AssignmentEntry> combinedAssignments() const;
920
921 // ─── Quick-layout slots (1..9) ────────────────────────────────────────
922 //
923 // Quick slots are keyed by tiling mode, one INDEPENDENT array per mode
924 // (see @ref slotIndexFor: Snapping 0, Autotile 1, Scrolling 2). Snapping
925 // slots hold manual-layout UUIDs, Autotile slots hold autotile algorithm
926 // IDs, and Scrolling slots hold native ScrollingTemplate UUIDs. The three
927 // sets are independent so the same Meta+Alt+N can map to a zone layout in
928 // snapping mode, an algorithm in autotile mode, and a template in
929 // scrolling mode. applyQuickLayout's scrolling arm routes its slot id to
930 // applyScrollingTemplateToScreen — the press changes the screen's
931 // template, never the engine.
932
938 static constexpr QLatin1String QuickSlotsSnappingKey{"snapping"};
939 static constexpr QLatin1String QuickSlotsAutotileKey{"autotile"};
940 static constexpr QLatin1String QuickSlotsScrollingKey{"scrolling"};
941
942 Q_INVOKABLE Layout* layoutForShortcut(AssignmentEntry::Mode mode, int number) const;
943 Q_INVOKABLE void applyQuickLayout(AssignmentEntry::Mode mode, int number, const QString& screenId);
944 void setQuickLayoutSlot(AssignmentEntry::Mode mode, int number, const QString& layoutId);
945 void setAllQuickLayoutSlots(AssignmentEntry::Mode mode, const QHash<int, QString>& slots);
946 QHash<int, QString> quickLayoutSlots(AssignmentEntry::Mode mode) const
947 {
948 return m_quickLayoutSlots[slotIndexFor(mode)];
949 }
950
951 // ─── Layout cycling ───────────────────────────────────────────────────
952
953 Q_INVOKABLE void cycleToPreviousLayout(const QString& screenId);
954 Q_INVOKABLE void cycleToNextLayout(const QString& screenId);
955
961 bool applyScrollingTemplateToScreen(const QString& screenId, const QString& templateId);
962
977 bool purgeLayoutIdFromAssignments(const QString& layoutId);
978
979 // ─── Built-in layouts ─────────────────────────────────────────────────
980
981 Q_INVOKABLE void createBuiltInLayouts();
982 QVector<Layout*> builtInLayouts() const;
983
984 // ─── Context (desktop / activity) ─────────────────────────────────────
985
986 Q_INVOKABLE int currentVirtualDesktop() const override
987 {
988 return m_currentVirtualDesktop;
989 }
990 Q_INVOKABLE QString currentActivity() const override
991 {
992 return m_currentActivity;
993 }
994 void setCurrentVirtualDesktop(int desktop)
995 {
996 m_currentVirtualDesktop = desktop;
997 }
1003 int currentVirtualDesktopForScreen(const QString& screenId) const override
1004 {
1005 if (m_currentVirtualDesktopProvider) {
1006 if (const auto desktop = m_currentVirtualDesktopProvider(screenId); desktop && *desktop >= 1) {
1007 return *desktop;
1008 }
1009 }
1010 return m_currentVirtualDesktop;
1011 }
1015 void setCurrentVirtualDesktopProvider(std::function<std::optional<int>(const QString& screenId)> provider)
1016 {
1017 m_currentVirtualDesktopProvider = std::move(provider);
1018 }
1019 void setCurrentActivity(const QString& activity)
1020 {
1021 m_currentActivity = activity;
1022 }
1023
1024 // ─── Autotile layout overrides (per-algorithm user overrides) ─────────
1025
1026 void saveAutotileOverrides(const QString& algorithmId, const QJsonObject& overrides);
1027 QJsonObject loadAutotileOverrides(const QString& algorithmId) const override;
1028
1035 void seedDefaultLayoutSettingsIfFresh(const QJsonObject& defaults);
1036
1044 [[nodiscard]] int contextResolveCacheSize() const
1045 {
1046 return static_cast<int>(m_contextResolveCache.size());
1047 }
1048
1049Q_SIGNALS:
1050 // layoutAdded / layoutRemoved / activeLayoutChanged / layoutAssigned are
1051 // inherited from IZoneLayoutRegistry - declared on the interface so
1052 // consumers that target the contract can connect without depending on
1053 // the concrete class. Emit sites still live in this TU and reach the
1054 // inherited signal via Q_OBJECT's metaobject chain.
1059
1060private:
1063 void initCommon();
1064
1065 void ensureLayoutDirectory();
1066 void loadLayoutsFromDirectory(const QString& directory);
1067 Layout* restoreSystemLayout(const QUuid& id, const QString& systemPath);
1068 QString layoutFilePath(const QUuid& id) const;
1069 QString quickLayoutsFilePath() const;
1070 QString layoutSettingsFilePath() const;
1071 void readQuickLayouts();
1072 void writeQuickLayouts();
1081 static constexpr int QuickSlotCount = 9;
1091 static constexpr int slotIndexFor(AssignmentEntry::Mode mode)
1092 {
1093 if (mode == AssignmentEntry::Autotile) {
1094 return 1;
1095 }
1096 return mode == AssignmentEntry::Scrolling ? 2 : 0;
1097 }
1098 Layout* cycleLayoutImpl(const QString& screenId, int direction);
1099 bool shouldSkipLayoutAssignment(const QString& layoutId, const QString& context) const;
1100 void emitLayoutAssigned(const QString& screenId, int virtualDesktop, const QString& layoutId);
1121 bool applyLayoutToScreen(const QString& screenId, Layout* layout);
1124 void migrateLegacyAutotileOverrides();
1125
1126 // ─── Rule-backed assignment resolution ────────────────────────────────
1127 // The unified RuleStore is the single source of truth for every
1128 // per-context assignment. These helpers translate the legacy
1129 // AssignmentEntry API onto the rule store + evaluator.
1130
1165 std::optional<AssignmentEntry> resolveAssignmentEntry(const QString& screenId, int virtualDesktop,
1166 const QString& activity) const;
1167
1173 bool hasExactContextRule(const QString& screenId, int virtualDesktop, const QString& activity) const;
1174
1191 const PhosphorRules::Rule* findExactContextRule(const QString& screenId, int virtualDesktop,
1192 const QString& activity) const;
1193
1199 bool hasExplicitSnappingModePin(const QString& screenId, int virtualDesktop, const QString& activity,
1200 const AssignmentEntry& entry) const;
1201
1210 std::optional<QString> resolveStoredAssignmentId(const QString& screenId, int virtualDesktop,
1211 const QString& activity) const;
1212
1215 QUuid exactContextRuleId(const QString& screenId, int virtualDesktop, const QString& activity) const;
1216
1234 bool upsertAssignmentRule(const QString& screenId, int virtualDesktop, const QString& activity,
1235 const AssignmentEntry& entry);
1236
1239 bool removeAssignmentRule(const QString& screenId, int virtualDesktop, const QString& activity);
1240
1254 template<typename KeyT, typename DecodeFn, typename ValidFn, typename FamilyFn>
1255 void applyBatchAssignments(const QHash<KeyT, QString>& assignments, DecodeFn decode, ValidFn valid,
1256 FamilyFn familyMatches, int emitDesktop, const char* label);
1257
1270 AssignmentEntry resolveDefaultAssignmentEntryRaw() const;
1271
1278 AssignmentEntry resolveDefaultAssignmentEntry() const;
1279
1288 AssignmentEntry resolveDefaultAssignmentEntryForContext(const QString& screenId, int virtualDesktop,
1289 const QString& activity) const;
1290
1300 bool hasMatchingAssignmentRule(const QString& screenId, int virtualDesktop, const QString& activity) const;
1301
1305 using ContextResolveKey = PhosphorZones::ContextResolveKey;
1306
1322 template<typename V, typename ComputeFn>
1323 V resolveCachedContext(QHash<ContextResolveKey, V>& cache, quint64& cacheRevision, const QString& screenId,
1324 int virtualDesktop, const QString& activity, const QString& mode, ComputeFn&& compute) const
1325 {
1326 const quint64 revision = m_ruleStore->ruleSet().revision();
1327 if (revision != cacheRevision) {
1328 cache.clear();
1329 cacheRevision = revision;
1330 }
1331 const ContextResolveKey key{screenId, virtualDesktop, activity, mode};
1332 const auto cached = cache.constFind(key);
1333 if (cached != cache.constEnd()) {
1334 return cached.value();
1335 }
1336 V value = compute();
1337 constexpr qsizetype kMaxEntries = 256;
1338 if (cache.size() >= kMaxEntries) {
1339 cache.clear();
1340 }
1341 cache.insert(key, value);
1342 return value;
1343 }
1344
1362 struct RuleSlotResolution
1363 {
1364 std::optional<AssignmentEntry> modeEntry;
1365 std::optional<QString> snappingLayout;
1366 std::optional<QString> tilingAlgorithm;
1367 std::optional<QString> scrollingTemplate;
1368 };
1369
1376 mutable QHash<ContextResolveKey, std::optional<RuleSlotResolution>> m_contextResolveCache;
1380 mutable quint64 m_contextResolveCacheRevision = 0;
1381
1388 mutable QHash<ContextResolveKey, ContextGapOverride> m_contextGapCache;
1389 mutable quint64 m_contextGapCacheRevision = 0;
1390
1396 mutable QHash<ContextResolveKey, bool> m_contextLockCache;
1397 mutable quint64 m_contextLockCacheRevision = 0;
1398
1405 mutable QHash<ContextResolveKey, std::optional<bool>> m_contextDefaultAssignmentCache;
1406 mutable quint64 m_contextDefaultAssignmentCacheRevision = 0;
1407
1416 std::optional<bool> resolveContextBoolSlot(QHash<ContextResolveKey, std::optional<bool>>& cache,
1417 quint64& cacheRevision, QLatin1StringView actionType,
1418 const QString& screenId, int virtualDesktop,
1419 const QString& activity) const;
1420
1427 mutable QHash<ContextResolveKey, std::optional<bool>> m_contextOsdCache;
1428 mutable quint64 m_contextOsdCacheRevision = 0;
1429
1436 mutable QHash<ContextResolveKey, std::optional<bool>> m_contextDragSelectorCache;
1437 mutable quint64 m_contextDragSelectorCacheRevision = 0;
1438
1444 mutable QHash<ContextResolveKey, ContextOverlayOverride> m_contextOverlayCache;
1445 mutable quint64 m_contextOverlayCacheRevision = 0;
1446
1447 std::function<QString()> m_defaultLayoutIdProvider;
1453 std::function<QString()> m_defaultAutotileAlgorithmProvider;
1458 std::function<std::optional<int>(const QString& screenId, int virtualDesktop, const QString& activity)>
1459 m_tiledWindowCountProvider;
1464 std::function<std::optional<QString>(const QString& screenId)> m_screenOrientationProvider;
1466 std::function<std::optional<QString>()> m_colorSchemeProvider;
1470 ScrollingTemplateStore* m_scrollingTemplateStore = nullptr;
1474 std::function<QString()> m_defaultScrollingTemplateProvider;
1479 std::function<bool()> m_snappingPreferredProvider;
1484 std::function<bool()> m_defaultAssignmentSuppressedProvider;
1488 PhosphorRules::RuleStore* m_ruleStore = nullptr;
1490 std::unique_ptr<PhosphorRules::RuleEvaluator> m_evaluator;
1491 QString m_layoutSubdirectory;
1492 QString m_layoutDirectory;
1493 QVector<Layout*> m_layouts;
1494 Layout* m_activeLayout = nullptr;
1495 Layout* m_previousLayout = nullptr;
1501 QHash<int, QString> m_quickLayoutSlots[3];
1505 LayoutSettingsStore m_layoutSettings;
1506 int m_currentVirtualDesktop = 1;
1511 std::function<std::optional<int>(const QString&)> m_currentVirtualDesktopProvider;
1512 QString m_currentActivity;
1513};
1514
1515} // namespace PhosphorZones
Enumeration + mutation surface for the in-memory zone-layout catalog.
Definition IZoneLayoutRegistry.h:51
Manual zone-layout registry + per-context assignment store.
Definition LayoutRegistry.h:89
bool removeLayoutById(const QUuid &id) override
AssignmentEntry::Mode modeForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
bool applyScrollingTemplateToScreen(const QString &screenId, const QString &templateId)
Commit templateId as screenId's scrolling template on the screen's OWN desktop (the template twin of ...
QString layoutDirectory() const
Definition LayoutRegistry.h:179
void applyQuickLayout(AssignmentEntry::Mode mode, int number, const QString &screenId)
void setAllDesktopAssignments(const QHash< QPair< QString, int >, QString > &assignments)
LayoutRegistry(PhosphorRules::RuleStore *ruleStore, QString layoutSubdirectory, QObject *parent=nullptr)
std::optional< bool > resolveContextDragSelectorEnabled(const QString &screenId, int virtualDesktop, const QString &activity) const override
Resolve a per-context override of the drag selector popup — the edge-triggered zone / strip picker of...
QString assignmentIdForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
Raw assignment id for a (screen, desktop, activity) context.
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 no...
Layout * importLayout(const QString &filePath)
Load a layout from filePath and add it to the registry.
QString screenOrientationToken(const QString &screenId) const
The screen-orientation token from m_screenOrientationProvider ("portrait" / "landscape"),...
Definition LayoutRegistry.h:615
void setDefaultScrollingTemplateProvider(std::function< QString()> provider)
Provider for the DEFAULT scrolling template id (a config setting the daemon owns): consulted when a S...
Definition LayoutRegistry.h:465
int currentVirtualDesktop() const override
Definition LayoutRegistry.h:986
QHash< int, QString > quickLayoutSlots(AssignmentEntry::Mode mode) const
Definition LayoutRegistry.h:946
void stampScreenOrientation(PhosphorRules::WindowQuery &query, const QString &screenId) const
Stamp the screen-orientation token onto query from m_screenOrientationProvider (a no-op when the prov...
Definition LayoutRegistry.h:638
void setColorSchemeProvider(std::function< std::optional< QString >()> provider)
Inject a callback that reports the system colour scheme ("light" / "dark"), or std::nullopt when it i...
Layout * duplicateLayout(Layout *source) override
int layoutCount() const override
Definition LayoutRegistry.h:144
QString storedAssignmentIdForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
Like assignmentIdForScreen, but WITHOUT the level-1 global default fallback: resolves the same per-co...
void setActiveLayoutById(const QUuid &id) override
void assignScrollingTemplate(const QString &screenId, int virtualDesktop, const QString &activity, const QString &templateId)
Assign templateId as the context's scrolling TEMPLATE (the native ScrollingTemplate whose vocabularie...
Layout * layoutForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const override
Cascade-resolve the manual layout for screenId.
QString rulesVisibleActiveLayoutId(const QString &screenId, int virtualDesktop, const QString &activity) const
The RULES-VISIBLE ActiveLayout value the context resolvers stamp onto their windowless queries: the a...
void setAssignmentEntryDirect(const QString &screenId, int virtualDesktop, const QString &activity, const AssignmentEntry &entry)
Store a full entry directly (from KCM via D-Bus).
void cycleToNextLayout(const QString &screenId)
void setAllActivityAssignments(const QHash< QPair< QString, QString >, QString > &assignments)
static QString duplicateNameSuffix()
The literal suffix duplicateLayout appends to the source layout's name.
Definition LayoutRegistry.h:165
void setAllScreenAssignments(const QHash< QString, QString > &assignments)
Batch setters - clear existing, set new, save once at end.
Layout * resolveLayoutForScreen(const QString &screenId) const override
Resolve layout for screenId using the current desktop/activity context.
Definition LayoutRegistry.h:489
static QString escapeKeyComponent(const QString &component)
Make a cache-key component unambiguous under concatenation.
Definition LayoutRegistry.h:718
Layout * activeLayout() const override
Definition LayoutRegistry.h:170
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 sh...
void cycleToPreviousLayout(const QString &screenId)
static QString contextCacheKeyToken(const QString &modeToken, const QString &activeLayoutId, const QString &orientationToken, const QString &colorSchemeToken)
Compose the extra cache-key token a daemon-facing context resolver (gap / lock / overlay / default-as...
Definition LayoutRegistry.h:686
void addLayout(Layout *layout) override
Layout * layout(int index) const override
ContextOverlayOverride resolveContextOverlay(const QString &screenId, int virtualDesktop, const QString &activity) const override
Resolve the per-context overlay-property override (shader / style) for (screen, desktop,...
void setLayoutDirectory(const QString &directory)
void setCurrentVirtualDesktopProvider(std::function< std::optional< int >(const QString &screenId)> provider)
Inject the per-screen desktop resolver above.
Definition LayoutRegistry.h:1015
void saveAutotileOverrides(const QString &algorithmId, const QJsonObject &overrides)
void setQuickLayoutSlot(AssignmentEntry::Mode mode, int number, const QString &layoutId)
ContextScrollingParams resolveContextScrollingParams(const QString &screenId, int virtualDesktop, const QString &activity) const
Resolve the per-context scrolling parameter overrides (default column width / focused-column centerin...
void assignLayoutById(const QString &screenId, int virtualDesktop, const QString &activity, const QString &layoutId)
static bool isLayoutJsonValid(const QJsonObject &json, const QString &context)
Validate json against the bundled layout schema — the single gate every untrusted layout document pas...
ScrollingTemplateStore * scrollingTemplateStore() const override
The native scrolling-template store wired into this registry, or null when none is (lightweight stubs...
Definition LayoutRegistry.h:455
Layout * previousLayout() const
Get the previous active layout (before the most recent setActiveLayout).
Definition LayoutRegistry.h:416
void setSnappingPreferredProvider(std::function< bool()> provider)
Inject a callback that returns true when Snapping is the user's preferred default mode (regardless of...
int currentVirtualDesktopForScreen(const QString &screenId) const override
This screen's current virtual desktop, resolved through the injected provider (the daemon wires it to...
Definition LayoutRegistry.h:1003
void setCurrentActivity(const QString &activity)
Definition LayoutRegistry.h:1019
Layout * defaultLayout() const override
Resolve the effective default layout.
bool exactContextDeclaresEngineMode(const QString &screenId, int virtualDesktop, const QString &activity) const
Whether the exact-context rule for this tuple DECLARES an engine mode, rather than merely being defau...
void clearAssignment(const QString &screenId, int virtualDesktop=0, const QString &activity=QString())
std::optional< bool > resolveContextOsdEnabled(const QString &screenId, int virtualDesktop, const QString &activity) const
Resolve a per-context override of the OSD toggles for the (screen, desktop, activity) context by eval...
int contextResolveCacheSize() const
Current entry count in the resolveAssignmentEntry hot-path cache.
Definition LayoutRegistry.h:1044
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 —...
void clearAutotileAssignments()
Flip mode to Snapping for every entry currently in Autotile (preserves snappingLayout + tilingAlgorit...
void setCurrentVirtualDesktop(int desktop)
Definition LayoutRegistry.h:994
bool snappingPreferred() const
True when the snapping-preferred provider is wired AND reports true — i.e.
AssignmentEntry assignmentEntryForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
Full entry for a (screen, desktop, activity) context.
void stampColorScheme(PhosphorRules::WindowQuery &query) const
Stamp the colour-scheme token onto query from m_colorSchemeProvider (a no-op when unset).
Definition LayoutRegistry.h:670
Layout * layoutByName(const QString &name) const override
Layout * layoutById(const QUuid &id) const override
Resolve a layout by its stable UUID.
void setAllQuickLayoutSlots(AssignmentEntry::Mode mode, const QHash< int, QString > &slots)
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...
QHash< QPair< QString, QString >, AssignmentEntry > activityAssignments() const
ContextTilingParams resolveContextTilingParams(const QString &screenId, int virtualDesktop, const QString &activity) const
Resolve the per-context autotile parameter overrides (max windows / split ratio / master count) for (...
QString colorSchemeToken() const
The colour-scheme token from m_colorSchemeProvider ("light" / "dark"), or an empty string when the pr...
Definition LayoutRegistry.h:654
bool removeLayout(Layout *layout) override
ContextGapOverride resolveContextGaps(const QString &screenId, int virtualDesktop, const QString &activity, const QString &mode=QString()) const override
Resolve the per-context gap override for (screen, desktop, activity) by evaluating a windowless Windo...
void setScreenOrientationProvider(std::function< std::optional< QString >(const QString &screenId)> provider)
Inject a callback that returns a screen's orientation token ("portrait" / "landscape"),...
QHash< CombinedAssignmentKey, AssignmentEntry > combinedAssignments() const
Strict Combined-context reader.
AssignmentEntry exactContextEntry(const QString &screenId, int virtualDesktop, const QString &activity) const
The EXPLICIT assignment entry pinned by this exact context tuple's rule, or a default entry when none...
bool purgeLayoutIdFromAssignments(const QString &layoutId)
Drop id from every assignment rule's SetSnappingLayout and SetScrollingTemplate actions,...
void setScrollingTemplateStore(ScrollingTemplateStore *store)
Wire the native template store (borrowed, post-construction like the other injected collaborators; pa...
Definition LayoutRegistry.h:451
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,...
QString currentActivity() const override
Definition LayoutRegistry.h:990
void seedDefaultLayoutSettingsIfFresh(const QJsonObject &defaults)
Seed curated default picker visibility into the sidecar, but ONLY on a fresh install — when neither l...
Layout * layoutForShortcut(AssignmentEntry::Mode mode, int number) const
void setDefaultLayoutIdProvider(std::function< QString()> provider)
Inject a callback that returns the user-configured default layout id (or empty if unset).
ScrollingTemplate scrollingTemplateForContext(const QString &screenId, int virtualDesktop, const QString &activity) const override
The resolved ScrollingTemplate for a scrolling context, by value — invalid when the cascade has no Sc...
void setDefaultAssignmentSuppressedProvider(std::function< bool()> provider)
Inject a callback that returns true when the user has opted to suppress the synthesized level-1 defau...
QString scrollingTemplateLayoutForScreen(const QString &screenId, int virtualDesktop=0, const QString &activity=QString()) const
Raw template-field sibling of the two getters above: NOT mode-gated, so a dormant template preserved ...
void setDefaultAutotileAlgorithmProvider(std::function< QString()> provider)
Inject a callback that returns the user-configured default autotile algorithm id (or empty if autotil...
QJsonObject loadAutotileOverrides(const QString &algorithmId) const override
Per-algorithm autotile settings (gaps, shader, hiddenFromSelector, …) stored in the unified layout-se...
bool scrollingTemplateExplicitlyNone(const QString &screenId, int virtualDesktop, const QString &activity) const override
Mode-gated like scrollingTemplateForContext rather than like the raw getter above: a token preserved ...
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,...
void saveLayout(Layout *layout)
static QString assignmentCacheKeyToken(const std::optional< int > &tiledCount, const QString &orientationToken, const QString &colorSchemeToken)
The resolveAssignmentEntry cache's own extra token.
Definition LayoutRegistry.h:702
QVector< Layout * > builtInLayouts() const
QHash< QPair< QString, int >, AssignmentEntry > desktopAssignments() const
The three projection readers return the FULL AssignmentEntry per context (mode + all three payload fi...
void setTiledWindowCountProvider(std::function< std::optional< int >(const QString &screenId, int virtualDesktop, const QString &activity)> provider)
Inject a callback that returns the tiled-window count for a screen, or std::nullopt when the screen i...
void setActiveLayout(Layout *layout) override
void assignLayout(const QString &screenId, int virtualDesktop, const QString &activity, Layout *layout)
bool exportLayout(Layout *layout, const QString &filePath)
Write layout to filePath as a standalone layout document.
int restoreAutotileAssignments()
Reverse direction of clearAutotileAssignments FOR THE ASSIGNMENT RULES ONLY (the wiped quick-layout s...
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...
void setAllCombinedAssignments(const QHash< CombinedAssignmentKey, QString > &assignments)
Combined-context (screen + desktop + activity) batch setter — the triple-axis sibling of the Activity...
QVector< Layout * > layouts() const override
Enumerate every known layout.
Definition LayoutRegistry.h:148
Represents a collection of zones that form a layout.
Definition Layout.h:42
Load/save store for scrolling templates.
Definition ScrollingTemplateStore.h:37
A scrolling screen's first-class sizing template.
Definition ScrollingTemplate.h:128
Definition IWindowTrackingService.h:23
size_t qHash(const LayoutAssignmentKey &key, size_t seed=0)
Definition AssignmentEntry.h:87
Explicit per-context assignment entry storing every mode's payload.
Definition AssignmentEntry.h:202
Mode
Per-context engine selection.
Definition AssignmentEntry.h:212
Triple-axis key for the Combined-context batch API.
Definition LayoutRegistry.h:47
int virtualDesktop
Definition LayoutRegistry.h:49
QString activity
Definition LayoutRegistry.h:50
QString screenId
Definition LayoutRegistry.h:48
bool operator==(const CombinedAssignmentKey &other) const
Definition LayoutRegistry.h:52
Per-context gap override resolved from rules.
Definition AssignmentEntry.h:362
Per-context overlay-property overrides resolved from window-rule actions.
Definition AssignmentEntry.h:400
Lookup key for the LayoutRegistry context-resolver caches.
Definition ContextResolveKey.h:17
Per-context scrolling parameter overrides resolved from context rules.
Definition AssignmentEntry.h:481
Per-context autotile parameter overrides resolved from context rules.
Definition AssignmentEntry.h:434