Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
FloatingCache.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
7
8#include <QSet>
9#include <QString>
10
11namespace PhosphorCompositor {
12
38{
39public:
40 bool isFloating(const QString& windowId) const
41 {
42 // Instance-specific float — survives appId (class) mutation.
43 if (m_byInstance.contains(::PhosphorIdentity::WindowId::extractInstanceId(windowId))) {
44 return true;
45 }
46 // App-wide float — a bare appId matches every instance of that app.
47 return m_byAppId.contains(::PhosphorIdentity::WindowId::extractAppId(windowId));
48 }
49
53 bool setFloating(const QString& windowId, bool floating)
54 {
55 const QString appId = ::PhosphorIdentity::WindowId::extractAppId(windowId);
56 const bool isComposite = (appId != windowId); // bare appId has no separator
57 if (isComposite) {
58 const QString instanceId = ::PhosphorIdentity::WindowId::extractInstanceId(windowId);
59 // A composite with an empty instanceId ("appId|") is malformed: keying
60 // it would alias every other empty-instance window onto one wildcard
61 // slot. Reject rather than corrupt the cache.
62 if (instanceId.isEmpty()) {
63 return false;
64 }
65 if (floating) {
66 if (m_byInstance.contains(instanceId)) {
67 return false;
68 }
69 m_byInstance.insert(instanceId);
70 return true;
71 }
72 const bool removedInstance = m_byInstance.remove(instanceId);
73 // Mirror WindowTrackingService::setFloating: an explicit instance
74 // unfloat also drops the coarse app-wide fallback. Siblings keep
75 // their own instance entries, so this only clears the appId marker.
76 const bool removedAppId = m_byAppId.remove(appId);
77 return removedInstance || removedAppId;
78 }
79 // Bare appId keyspace. Reject an empty id (no separator, nothing before
80 // it) the same way the composite branch rejects an empty instanceId —
81 // an empty key would alias every empty-id window onto one wildcard slot.
82 if (windowId.isEmpty()) {
83 return false;
84 }
85 if (floating) {
86 if (m_byAppId.contains(windowId)) {
87 return false;
88 }
89 m_byAppId.insert(windowId);
90 return true;
91 }
92 return m_byAppId.remove(windowId);
93 }
94
95 void clear()
96 {
97 m_byInstance.clear();
98 m_byAppId.clear();
99 }
100
105 int size() const
106 {
107 return m_byInstance.size() + m_byAppId.size();
108 }
109
113 bool insert(const QString& windowId)
114 {
115 return setFloating(windowId, true);
116 }
117
120 bool remove(const QString& windowId)
121 {
122 return setFloating(windowId, false);
123 }
124
125private:
126 QSet<QString> m_byInstance;
127 QSet<QString> m_byAppId;
128};
129
130} // namespace PhosphorCompositor
Compositor-agnostic floating window state cache.
Definition FloatingCache.h:38
bool setFloating(const QString &windowId, bool floating)
Set windowId's floating state.
Definition FloatingCache.h:53
void clear()
Definition FloatingCache.h:95
int size() const
Total entries across BOTH keyspaces (instance floats + app-wide floats).
Definition FloatingCache.h:105
bool remove(const QString &windowId)
Convenience alias for setFloating(windowId, false).
Definition FloatingCache.h:120
bool insert(const QString &windowId)
Convenience alias for setFloating(windowId, true).
Definition FloatingCache.h:113
bool isFloating(const QString &windowId) const
Definition FloatingCache.h:40
Definition DaemonClient.h:22
QString extractInstanceId(const QString &windowId)
Extract the stable KWin instance identifier (UUID) from a full window ID.
Definition WindowId.h:75
QString extractAppId(const QString &windowId)
Extract app identity from window ID (portion before the '|' separator) Format: "appId|internalUuid" →...
Definition WindowId.h:56