Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PerScreenStates.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
8
9#include <functional>
10#include <optional>
11#include <type_traits>
12
13#include <QHash>
14#include <QString>
15#include <QtGlobal>
16
17namespace PhosphorEngine {
18
33template<typename StateT>
35{
36 static_assert(std::is_base_of_v<IPlacementState, StateT>,
37 "PerScreenStates<StateT>: StateT must implement PhosphorEngine::IPlacementState");
38
39public:
43 StateT* forKey(const PlacementStateKey& key, const std::function<StateT*()>& factory)
44 {
45 auto it = m_states.find(key);
46 if (it != m_states.end()) {
47 return it.value();
48 }
49 StateT* created = factory ? factory() : nullptr;
50 if (created) {
51 m_states.insert(key, created);
52 }
53 return created;
54 }
55
57 StateT* stateForKey(const PlacementStateKey& key) const
58 {
59 return m_states.value(key);
60 }
61
62 bool containsKey(const PlacementStateKey& key) const
63 {
64 return m_states.contains(key);
65 }
66
68 void insertState(const PlacementStateKey& key, StateT* state)
69 {
70 m_states.insert(key, state);
71 }
72
74 StateT* takeState(const PlacementStateKey& key)
75 {
76 return m_states.take(key);
77 }
78
79 int stateCount() const
80 {
81 return m_states.size();
82 }
83
85 const QHash<PlacementStateKey, StateT*>& states() const
86 {
87 return m_states;
88 }
89
90 // ── Reverse (window -> key) map ──────────────────────────────────────────
91 bool hasWindow(const QString& windowId) const
92 {
93 return m_windowToKey.contains(windowId);
94 }
95
98 PlacementStateKey keyForWindow(const QString& windowId) const
99 {
100 return m_windowToKey.value(windowId);
101 }
102
104 std::optional<PlacementStateKey> windowKey(const QString& windowId) const
105 {
106 auto it = m_windowToKey.constFind(windowId);
107 if (it == m_windowToKey.constEnd()) {
108 return std::nullopt;
109 }
110 return it.value();
111 }
112
113 void setKeyForWindow(const QString& windowId, const PlacementStateKey& key)
114 {
115 m_windowToKey.insert(windowId, key);
116 }
117
119 void removeWindow(const QString& windowId)
120 {
121 m_windowToKey.remove(windowId);
122 }
123
126 PlacementStateKey takeWindow(const QString& windowId)
127 {
128 return m_windowToKey.take(windowId);
129 }
130
132 const QHash<QString, PlacementStateKey>& windowKeys() const
133 {
134 return m_windowToKey;
135 }
136
139 StateT* forWindow(const QString& windowId, PlacementStateKey* outKey = nullptr) const
140 {
141 auto it = m_windowToKey.constFind(windowId);
142 if (it == m_windowToKey.constEnd()) {
143 return nullptr;
144 }
145 if (outKey) {
146 *outKey = it.value();
147 }
148 return m_states.value(it.value());
149 }
150
156 void migrate(const QString& windowId, const PlacementStateKey& oldKey, const PlacementStateKey& newKey)
157 {
158 Q_ASSERT(!m_windowToKey.contains(windowId) || m_windowToKey.value(windowId) == oldKey);
159 Q_UNUSED(oldKey)
160 m_windowToKey.insert(windowId, newKey);
161 }
162
165 void rekeyWindows(const PlacementStateKey& oldKey, const PlacementStateKey& newKey)
166 {
167 for (auto it = m_windowToKey.begin(); it != m_windowToKey.end(); ++it) {
168 if (it.value() == oldKey) {
169 it.value() = newKey;
170 }
171 }
172 }
173
179 void removeStatesIf(const std::function<bool(const PlacementStateKey&, StateT*)>& pred,
180 const std::function<void(const PlacementStateKey&, StateT*)>& onRemove)
181 {
182 for (auto it = m_states.begin(); it != m_states.end();) {
183 if (pred(it.key(), it.value())) {
184 if (onRemove) {
185 onRemove(it.key(), it.value());
186 }
187 it = m_states.erase(it);
188 } else {
189 ++it;
190 }
191 }
192 }
193
195 void removeWindowsIf(const std::function<bool(const QString&, const PlacementStateKey&)>& pred)
196 {
197 for (auto it = m_windowToKey.begin(); it != m_windowToKey.end();) {
198 if (pred(it.key(), it.value())) {
199 it = m_windowToKey.erase(it);
200 } else {
201 ++it;
202 }
203 }
204 }
205
206private:
207 QHash<PlacementStateKey, StateT*> m_states;
208 QHash<QString, PlacementStateKey> m_windowToKey;
209};
210
211} // namespace PhosphorEngine
The two cooperating maps a per-monitor placement engine keeps: a forward map from PlacementStateKey t...
Definition PerScreenStates.h:35
bool containsKey(const PlacementStateKey &key) const
Definition PerScreenStates.h:62
bool hasWindow(const QString &windowId) const
Definition PerScreenStates.h:91
StateT * takeState(const PlacementStateKey &key)
Remove and return the state at key (nullptr if absent). Does not delete.
Definition PerScreenStates.h:74
PlacementStateKey keyForWindow(const QString &windowId) const
The owning key for windowId, or a default-constructed key when untracked (mirrors QHash::value — an e...
Definition PerScreenStates.h:98
StateT * stateForKey(const PlacementStateKey &key) const
The state for key, or nullptr if none exists (never creates).
Definition PerScreenStates.h:57
void migrate(const QString &windowId, const PlacementStateKey &oldKey, const PlacementStateKey &newKey)
Move a window's reverse-map entry from oldKey to newKey.
Definition PerScreenStates.h:156
StateT * forKey(const PlacementStateKey &key, const std::function< StateT *()> &factory)
Lazily creates the state for key if absent.
Definition PerScreenStates.h:43
void removeWindow(const QString &windowId)
Drop the reverse-map entry for windowId (does not touch state objects).
Definition PerScreenStates.h:119
const QHash< QString, PlacementStateKey > & windowKeys() const
Read-only view of the reverse map for iteration.
Definition PerScreenStates.h:132
void removeStatesIf(const std::function< bool(const PlacementStateKey &, StateT *)> &pred, const std::function< void(const PlacementStateKey &, StateT *)> &onRemove)
Lockstep prune of the forward map: for every state matching pred, invoke onRemove (engine-specific te...
Definition PerScreenStates.h:179
StateT * forWindow(const QString &windowId, PlacementStateKey *outKey=nullptr) const
Resolve the state that owns windowId (no create).
Definition PerScreenStates.h:139
void insertState(const PlacementStateKey &key, StateT *state)
Insert/replace the state at key (caller retains ownership semantics).
Definition PerScreenStates.h:68
void setKeyForWindow(const QString &windowId, const PlacementStateKey &key)
Definition PerScreenStates.h:113
void rekeyWindows(const PlacementStateKey &oldKey, const PlacementStateKey &newKey)
Rewrite every reverse-map entry pointing at oldKey to newKey.
Definition PerScreenStates.h:165
int stateCount() const
Definition PerScreenStates.h:79
void removeWindowsIf(const std::function< bool(const QString &, const PlacementStateKey &)> &pred)
Drop reverse-map entries matching pred (e.g. a vanished desktop/activity).
Definition PerScreenStates.h:195
PlacementStateKey takeWindow(const QString &windowId)
Remove and return the reverse-map entry for windowId (default key when absent), mirroring QHash::take...
Definition PerScreenStates.h:126
const QHash< PlacementStateKey, StateT * > & states() const
Read-only view of the forward map for iteration.
Definition PerScreenStates.h:85
std::optional< PlacementStateKey > windowKey(const QString &windowId) const
The owning key for windowId, or nullopt when untracked.
Definition PerScreenStates.h:104
Definition EngineTypes.h:14
Identity of a per-screen placement state: a window's placement is scoped to the (screen,...
Definition EngineTypes.h:22