Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
WindowRegistry.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#include <phosphorengine_export.h>
9#include <QHash>
10#include <QMultiHash>
11#include <QObject>
12#include <QSet>
13#include <QString>
14#include <QStringList>
15#include <optional>
16
17namespace PhosphorEngine {
18
20{
21 QString appId;
22 QString desktopFile;
23 QString title;
24 QString windowRole{};
25 int pid = 0;
30 QList<int> virtualDesktops{};
31 QString activity{};
33
34 // ── Extended window properties. The kwin-effect snapshots these at metadata-push
35 // time so the daemon's window-rule resolvers (shouldFloatByRule /
36 // shouldRestoreFloatedPosition) can match the same KWin-property / geometry
37 // fields the effect path resolves live. std::optional so an absent value (the
38 // compositor could not report it — e.g. no underlying KWin::Window) leaves the
39 // corresponding WindowQuery field disengaged, keeping a predicate over it inert,
40 // mirroring window_query.cpp's engage-only-when-known contract. ──
41 std::optional<bool> isMinimized{};
47 std::optional<bool> isDemandingAttention{};
53 std::optional<bool> isFullscreen{};
54 std::optional<bool> isSticky{};
55 std::optional<bool> isMaximized{};
56 std::optional<bool> isFocused{};
61 std::optional<bool> isTransient{};
62 std::optional<bool> isNotification{};
63 std::optional<bool> keepAbove{};
64 std::optional<bool> keepBelow{};
65 std::optional<bool> skipTaskbar{};
66 std::optional<bool> skipPager{};
67 std::optional<bool> skipSwitcher{};
68 std::optional<bool> isModal{};
69 std::optional<bool> hasDecoration{};
70 std::optional<bool> isResizable{};
71 std::optional<bool> isMovable{};
72 std::optional<bool> isMaximizable{};
73 std::optional<int> width{};
74 std::optional<int> height{};
75 std::optional<int> positionX{};
76 std::optional<int> positionY{};
77 std::optional<QString> captionNormal{};
78
79 bool operator==(const WindowMetadata& other) const
80 {
81 return appId == other.appId && desktopFile == other.desktopFile && title == other.title
82 && windowRole == other.windowRole && pid == other.pid && virtualDesktop == other.virtualDesktop
83 && virtualDesktops == other.virtualDesktops && activity == other.activity && windowType == other.windowType
85 && isFullscreen == other.isFullscreen && isSticky == other.isSticky && isMaximized == other.isMaximized
86 && isFocused == other.isFocused && isTransient == other.isTransient
87 && isNotification == other.isNotification && keepAbove == other.keepAbove && keepBelow == other.keepBelow
88 && skipTaskbar == other.skipTaskbar && skipPager == other.skipPager && skipSwitcher == other.skipSwitcher
89 && isModal == other.isModal && hasDecoration == other.hasDecoration && isResizable == other.isResizable
90 && isMovable == other.isMovable && isMaximizable == other.isMaximizable && width == other.width
91 && height == other.height && positionX == other.positionX && positionY == other.positionY
92 && captionNormal == other.captionNormal;
93 }
94 bool operator!=(const WindowMetadata& other) const
95 {
96 return !(*this == other);
97 }
98};
99
100class PHOSPHORENGINE_EXPORT WindowRegistry : public QObject, public IWindowRegistry
101{
102 Q_OBJECT
103
104public:
105 explicit WindowRegistry(QObject* parent = nullptr);
106 ~WindowRegistry() override;
107
108 void upsert(const QString& instanceId, const WindowMetadata& metadata);
111 void remove(const QString& instanceId);
112
113 std::optional<WindowMetadata> metadata(const QString& instanceId) const;
120 {
121 int virtualDesktop = 0;
122 QList<int> virtualDesktops;
123 QString activity;
124
134 int effectiveDesktop(int screenCurrentDesktop) const
135 {
136 if (virtualDesktops.size() > 1 && virtualDesktops.contains(screenCurrentDesktop)) {
137 return screenCurrentDesktop;
138 }
139 return virtualDesktop > 0 ? virtualDesktop : screenCurrentDesktop;
140 }
141
147 QString effectiveActivity(const QString& currentActivity) const
148 {
149 return activity.isEmpty() ? currentActivity : activity;
150 }
151 };
152 std::optional<WindowContext> windowContext(const QString& instanceId) const;
153 Q_INVOKABLE QString appIdFor(const QString& instanceId) const override;
158 bool isMinimized(const QString& windowId) const;
163 std::optional<bool> minimizedState(const QString& windowId) const override;
168 QStringList instancesWithAppId(const QString& appId) const;
169 bool contains(const QString& instanceId) const;
170 int size() const;
175 void clear();
176
177 Q_INVOKABLE QString canonicalizeWindowId(const QString& rawWindowId) override;
178 Q_INVOKABLE QString canonicalizeForLookup(const QString& rawWindowId) const override;
179
189 int pruneStaleInstances(const QSet<QString>& aliveInstanceIds);
190
191Q_SIGNALS:
192 void windowAppeared(const QString& instanceId);
193 void metadataChanged(const QString& instanceId, const WindowMetadata& oldMetadata,
194 const WindowMetadata& newMetadata);
195 void windowDisappeared(const QString& instanceId);
196
197private:
198 QHash<QString, WindowMetadata> m_records;
199 QMultiHash<QString, QString> m_appIdIndex;
200 QHash<QString, QString> m_canonicalByInstance;
205 QSet<QString> m_disappearingInstances;
206 QHash<QString, WindowMetadata> m_pendingUpserts;
215 int m_clearing = 0;
216
217 void indexInsert(const QString& instanceId, const QString& appId);
218 void indexRemove(const QString& instanceId, const QString& appId);
219};
220
221} // namespace PhosphorEngine
Definition IWindowRegistry.h:14
Definition WindowRegistry.h:101
void clear()
Remove every record and canonical mapping, firing windowDisappeared for each.
bool isMinimized(const QString &windowId) const
Live compositor minimize state, collapsed to a bool: unknown reads as false.
std::optional< WindowContext > windowContext(const QString &instanceId) const
void windowDisappeared(const QString &instanceId)
int pruneStaleInstances(const QSet< QString > &aliveInstanceIds)
Defensive cleanup for windows that died WITHOUT a close signal reaching the registry (compositor cras...
WindowRegistry(QObject *parent=nullptr)
void metadataChanged(const QString &instanceId, const WindowMetadata &oldMetadata, const WindowMetadata &newMetadata)
QString appIdFor(const QString &instanceId) const override
The app identity recorded for instanceId, or empty when the instance is unknown.
std::optional< WindowMetadata > metadata(const QString &instanceId) const
QStringList instancesWithAppId(const QString &appId) const
Every instance currently recorded under appId, in UNSPECIFIED order (QMultiHash bucket order,...
void remove(const QString &instanceId)
Remove metadata and canonical state, emitting windowDisappeared exactly once while the canonical mapp...
void upsert(const QString &instanceId, const WindowMetadata &metadata)
bool contains(const QString &instanceId) const
QString canonicalizeForLookup(const QString &rawWindowId) const override
void windowAppeared(const QString &instanceId)
std::optional< bool > minimizedState(const QString &windowId) const override
Tri-state minimize state (IWindowRegistry contract): engaged when a record exists AND the compositor ...
QString canonicalizeWindowId(const QString &rawWindowId) override
Freeze (on first contact) and return the canonical id for rawWindowId's instance.
Definition EngineTypes.h:14
WindowType
Window-type vocabulary shared by the compositor effect, the daemon's WindowRegistry,...
Definition WindowTypeEnum.h:23
@ Unknown
type could not be determined
Definition WindowRegistry.h:20
std::optional< bool > isFocused
focused at metadata-push time (point-in-time, NOT refreshed on focus change) — the open-path Float / ...
Definition WindowRegistry.h:56
bool operator!=(const WindowMetadata &other) const
Definition WindowRegistry.h:94
std::optional< bool > isTransient
dialog/utility/popup/menu/tooltip/splash family or has a transient parent
Definition WindowRegistry.h:61
std::optional< int > positionY
frame top edge Y in px
Definition WindowRegistry.h:76
QString activity
activity UUID; empty = all activities / unknown
Definition WindowRegistry.h:31
std::optional< bool > skipPager
Definition WindowRegistry.h:66
std::optional< bool > isSticky
on all virtual desktops
Definition WindowRegistry.h:54
std::optional< bool > keepBelow
Definition WindowRegistry.h:64
std::optional< bool > isDemandingAttention
Urgency (KWin's demandsAttention).
Definition WindowRegistry.h:47
std::optional< bool > isFullscreen
Definition WindowRegistry.h:53
std::optional< bool > isMinimized
Kept current as of the LAST DELIVERED push, unlike isFocused: the effect re-pushes full metadata on e...
Definition WindowRegistry.h:41
std::optional< bool > keepAbove
Definition WindowRegistry.h:63
std::optional< int > width
frame width in px
Definition WindowRegistry.h:73
std::optional< bool > isMaximizable
window can be maximized
Definition WindowRegistry.h:72
std::optional< bool > isResizable
Definition WindowRegistry.h:70
std::optional< int > height
frame height in px
Definition WindowRegistry.h:74
int virtualDesktop
1-based x11 desktop number; 0 = all desktops / unknown
Definition WindowRegistry.h:26
QString appId
Definition WindowRegistry.h:21
std::optional< bool > hasDecoration
server-side title-bar / border
Definition WindowRegistry.h:69
QString windowRole
X11 WM_WINDOW_ROLE; empty for Wayland-native windows.
Definition WindowRegistry.h:24
std::optional< bool > skipSwitcher
Definition WindowRegistry.h:67
std::optional< int > positionX
frame left edge X in px
Definition WindowRegistry.h:75
QList< int > virtualDesktops
Full desktop list when the window spans SEVERAL (but not all) desktops; empty for the common single-d...
Definition WindowRegistry.h:30
QString title
Definition WindowRegistry.h:23
bool operator==(const WindowMetadata &other) const
Definition WindowRegistry.h:79
std::optional< bool > isMaximized
MaximizeFull (both axes)
Definition WindowRegistry.h:55
std::optional< bool > isNotification
notification / critical-notification / on-screen-display
Definition WindowRegistry.h:62
int pid
process id; 0 = unknown
Definition WindowRegistry.h:25
std::optional< bool > isModal
Definition WindowRegistry.h:68
std::optional< QString > captionNormal
title without the WM-added app-name suffix
Definition WindowRegistry.h:77
std::optional< bool > skipTaskbar
Definition WindowRegistry.h:65
std::optional< bool > isMovable
window can be moved
Definition WindowRegistry.h:71
PhosphorProtocol::WindowType windowType
Definition WindowRegistry.h:32
QString desktopFile
Definition WindowRegistry.h:22
The window's own context for per-window mode resolution: its virtual desktop (0 = all/unknown),...
Definition WindowRegistry.h:120
QList< int > virtualDesktops
Definition WindowRegistry.h:122
QString effectiveActivity(const QString &currentActivity) const
Effective activity: the window's own when known, else currentActivity.
Definition WindowRegistry.h:147
QString activity
Definition WindowRegistry.h:123
int effectiveDesktop(int screenCurrentDesktop) const
Effective desktop for per-window mode resolution: the window's own desktop when known (virtualDesktop...
Definition WindowRegistry.h:134