Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
WindowTrackingService.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): WindowTrackingService is the engine-
5// agnostic facade every placement engine and the daemon share, and this is an
6// INSTALLED public header — splitting the class is an API break for the
7// third-party consumers the LGPL boundary exists to serve. The implementation
8// is already split by concern across src/*.cpp (snap, resnap, navigation,
9// virtualscreenmigration, lifecycle), and the member ordering here encodes
10// which of those owns what. Same rationale as
11// PhosphorTileEngine/AutotileEngine.h.
12
13#pragma once
14
15#include <phosphorplacement_export.h>
16
28
29#include <QHash>
30#include <QObject>
31#include <QPointer>
32#include <QRect>
33#include <QSet>
34#include <QString>
35#include <QStringList>
36
37#include <functional>
38#include <optional>
39#include <utility>
40
41namespace PhosphorZones {
42class Layout;
43class LayoutRegistry;
44class Zone;
45}
46
47namespace PhosphorSnapEngine {
48class SnapState;
49}
50
54
55namespace PhosphorScreens {
56class ScreenManager;
57}
58
59namespace PhosphorPlacement {
60
84class PHOSPHORPLACEMENT_EXPORT WindowTrackingService : public QObject, public PhosphorEngine::IWindowTrackingService
85{
86 Q_OBJECT
87
88public:
90 PhosphorScreens::ScreenManager* screenManager,
92 IGeometryResolver* geometryResolver = nullptr, PlacementConfig config = {},
93 QObject* parent = nullptr);
94
100 const PlacementConfig& config() const
101 {
102 return m_config;
103 }
104
105 QObject* asQObject() override;
107
118
124
126
132
137
156 using ShouldTrackPredicate = std::function<bool(const QString& screenId, int virtualDesktop)>;
157
177
190
192
201 using AutotileModePredicate = std::function<bool(const QString& windowId)>;
203
213 bool isWindowInAutotileMode(const QString& windowId) const;
214
230 using EngineTiledPredicate = std::function<bool(const QString& windowId)>;
232
235 bool isWindowEngineTiled(const QString& windowId) const;
236
250 using ModeEngineIdResolver = std::function<QString(const QString& windowId, const QString& screenId)>;
252
260 QString owningModeEngineId(const QString& windowId, const QString& screenId) const;
261
275 const QString& recordedScreenId, const QString& closeScreenId);
276
281
283
284 // ═══════════════════════════════════════════════════════════════════════════
285 // PhosphorZones::Zone Assignment Management
286 // ═══════════════════════════════════════════════════════════════════════════
287
295 void assignWindowToZone(const QString& windowId, const QString& zoneId, const QString& screenId,
296 int virtualDesktop) override;
297
305 void assignWindowToZones(const QString& windowId, const QStringList& zoneIds, const QString& screenId,
306 int virtualDesktop) override;
307
312 void unassignWindow(const QString& windowId) override;
313
319 QString zoneForWindow(const QString& windowId) const override;
320
326 QStringList zonesForWindow(const QString& windowId) const override;
327
333 QString screenForWindow(const QString& windowId) const override;
334
337 QString screenForWindow(const QString& windowId, const QString& defaultScreen) const override;
338
344 QStringList windowsInZone(const QString& zoneId) const override;
345
350 QStringList snappedWindows() const;
351
354 int pruneStaleAssignments(const QSet<QString>& aliveWindowIds);
355
359 bool isWindowSnapped(const QString& windowId) const override;
360
361 // ═══════════════════════════════════════════════════════════════════════════
362 // Geometry Validation Utility
363 // ═══════════════════════════════════════════════════════════════════════════
364
379 std::optional<QRect> validateGeometryForScreen(const QRect& geo, const QString& savedScreen,
380 const QString& currentScreenName) const;
381
393 std::optional<QRect> validatedUnmanagedGeometry(const QString& windowId, const QString& screenId,
394 bool exactOnly = false) const override;
395
398 void recordFreeGeometry(const QString& windowId, const QString& screenId, const QRect& geometry,
399 bool overwrite) override;
400
410 void recordFloatingClose(const QString& windowId, const QString& screenId, const QRect& geometry);
411
414 void clearFreeGeometry(const QString& windowId) override;
415 void clearFreeGeometry(const QString& windowId, const QString& screenId) override;
416
423 void releaseEngineSlot(const QString& windowId, const QString& engineId) override;
424
425 // ═══════════════════════════════════════════════════════════════════════════
426 // Floating Window State
427 // ═══════════════════════════════════════════════════════════════════════════
428
444 using EngineFloatResolver = std::function<bool(const QString& windowId)>;
445 using EngineFloatWriter = std::function<void(const QString& windowId, bool floating)>;
446 using EngineFloatLister = std::function<QStringList()>;
447
453
460 bool isWindowFloating(const QString& windowId) const override;
461
477 bool isSuspensionFloat(const QString& windowId) const override;
478 void markSuspensionFloat(const QString& windowId);
479 void clearSuspensionFloat(const QString& windowId) override;
480
491 void setWindowFloating(const QString& windowId, bool floating) override;
492
496 QStringList floatingWindows() const;
497
502 void unsnapForFloat(const QString& windowId) override;
503
509 QString preFloatZone(const QString& windowId) const;
510
516 QStringList preFloatZones(const QString& windowId) const override;
517
523 QString preFloatScreen(const QString& windowId) const override;
524
535 void clearPreFloatZone(const QString& windowId) override;
536
547 bool clearFloatingForSnap(const QString& windowId) override;
548
549 // ═══════════════════════════════════════════════════════════════════════════
550 // Sticky Window Handling
551 // ═══════════════════════════════════════════════════════════════════════════
552
556 void setWindowSticky(const QString& windowId, bool sticky);
557
561 bool isWindowSticky(const QString& windowId) const override;
562
563 // ═══════════════════════════════════════════════════════════════════════════
564 // Auto-Snap Logic
565 // ═══════════════════════════════════════════════════════════════════════════
566
572 void recordSnapIntent(const QString& windowId, bool wasUserInitiated) override;
573
577 QString lastUsedZoneId() const;
578
585 QString lastUsedZoneClass() const;
586
593 QString lastUsedScreenName() const;
594
598 int lastUsedDesktop() const;
599
608 void retagLastUsedZoneClass(const QString& newClass);
609
613 void updateLastUsedZone(const QString& zoneId, const QString& screenId, const QString& windowClass,
614 int virtualDesktop) override;
615
625 void markAsAutoSnapped(const QString& windowId);
626
632 bool isAutoSnapped(const QString& windowId) const;
633
639 bool clearAutoSnapped(const QString& windowId) override;
640
670 bool consumePendingAssignment(const QString& windowId) override;
671
672 // ═══════════════════════════════════════════════════════════════════════════
673 // Navigation Helpers
674 // ═══════════════════════════════════════════════════════════════════════════
675
681 QString findEmptyZone(const QString& screenId = QString()) const override;
682
688 PhosphorProtocol::EmptyZoneList getEmptyZones(const QString& screenId) const;
689
696 QRect zoneGeometry(const QString& zoneId, const QString& screenId = QString()) const override;
697
704 QRect multiZoneGeometry(const QStringList& zoneIds, const QString& screenId = QString()) const;
705
728 void populateResnapBufferForAllScreens(const QSet<QString>& excludeScreens = {},
729 const QSet<QString>& includeScreens = {}, int desktopFilter = 0);
730
738
749 QStringList buildZoneOrderedWindowList(const QString& screenId) const;
750
751 // ═══════════════════════════════════════════════════════════════════════════
752 // Virtual Screen Migration
753 // ═══════════════════════════════════════════════════════════════════════════
754
774 void migrateScreenAssignmentsToVirtual(const QString& physicalScreenId, const QStringList& virtualScreenIds,
776
786 void migrateScreenAssignmentsFromVirtual(const QString& physicalScreenId);
787
811 QSet<QString> physicalScreensWithStaleVirtualAssignments(const QSet<QString>& subdividedPhysicalIds) const;
812
813 // ═══════════════════════════════════════════════════════════════════════════
814 // Resolution Change Handling
815 // ═══════════════════════════════════════════════════════════════════════════
816
823 QHash<QString, QRect> updatedWindowGeometries() const;
824
834 {
835 QRect geometry;
836 QString screenId;
837 };
838
857 QHash<QString, PendingRestoreTarget> pendingRestoreGeometries() const;
858
859 // ═══════════════════════════════════════════════════════════════════════════
860 // Window Lifecycle
861 // ═══════════════════════════════════════════════════════════════════════════
862
873
878
879 // ═══════════════════════════════════════════════════════════════════════════
880 // State Access
881 // ═══════════════════════════════════════════════════════════════════════════
882
885 QStringList recordedSnapZones(const QString& windowId) const override;
886
889
893 const QHash<QString, QList<PendingRestore>>& pendingRestoreQueues() const override;
894
895 QVector<ResnapEntry> takeResnapBuffer() override;
896
900 const QSet<QString>& userSnappedClasses() const;
901
910 void setPendingRestoreQueues(const QHash<QString, QList<PendingRestore>>& queues);
911
922 void setUserSnappedClasses(const QSet<QString>& classes);
923
927 void setLastUsedZone(const QString& zoneId, const QString& screenId, const QString& zoneClass, int desktop);
928
937 void setFloatingWindows(const QSet<QString>& windows);
938
939 // ═══════════════════════════════════════════════════════════════════════
940 // Dirty field tracking (Phase 3 of refactor/dbus-performance)
941 //
942 // Replaces "any mutation forces a full re-serialization" with a bitfield
943 // mask of which persisted state has changed since the last successful
944 // save. WindowTrackingAdaptor::saveState() reads this mask to decide
945 // which JSON maps to re-write, and the persistence worker's write-
946 // completed signal clears the committed bits — surviving bits either
947 // represent new mutations that landed during the in-flight write, or
948 // the write itself failed (same treatment in both cases: retry on the
949 // next tick).
950 //
951 // The mask is initialized to All so the first save after a daemon
952 // startup always writes every field. loadState() should clear the mask
953 // immediately after populating in-memory state so the first real save
954 // doesn't redundantly write back what we just loaded.
955 // ═══════════════════════════════════════════════════════════════════════
956 // NOTE: several bits below (DirtyZoneAssignments, DirtyPendingRestores,
957 // DirtyPreTileGeometries, DirtyPreFloatZones, DirtyPreFloatScreens,
958 // DirtyAutotileOrders, DirtyAutotilePending) no longer have a dedicated save
959 // block — their legacy keys were collapsed into DirtyWindowPlacements. The
960 // runtime mutators that still OR them in are retained because the act of
961 // marking ANY bit schedules a save, and saveState()'s refreshOpenWindowPlacements()
962 // re-derives the affected per-window state into the placement record. They are
963 // therefore "schedule a save" triggers, not independent persisted fields; only
964 // DirtyActiveLayoutId / DirtyLastUsedZone / DirtyUserSnapped / DirtyWindowPlacements
965 // map to their own on-disk key.
966 enum DirtyField : uint32_t {
967 DirtyNone = 0,
968 DirtyActiveLayoutId = 1u << 0,
969 DirtyZoneAssignments = 1u << 1, // legacy save-trigger → DirtyWindowPlacements
970 DirtyPendingRestores = 1u << 2, // legacy save-trigger → DirtyWindowPlacements
971 DirtyPreTileGeometries = 1u << 3, // legacy save-trigger → DirtyWindowPlacements
972 DirtyLastUsedZone = 1u << 4,
973 DirtyPreFloatZones = 1u << 5, // legacy save-trigger → DirtyWindowPlacements
974 DirtyPreFloatScreens = 1u << 6, // legacy save-trigger → DirtyWindowPlacements
975 DirtyUserSnapped = 1u << 7,
976 DirtyAutotileOrders = 1u << 8, // legacy save-trigger → DirtyWindowPlacements
977 DirtyAutotilePending = 1u << 9, // legacy save-trigger → DirtyWindowPlacements
978 // bit 10 reserved (was DirtyFloatRestores, removed with the FloatRestoreQueues key)
979 DirtyWindowPlacements = 1u << 11,
980 DirtyScrollStrips = 1u << 12,
981 DirtyAll = 0x1FFFu, // covers bits 0-12 incl. the reserved bit 10
982 };
983 using DirtyMask = uint32_t;
984
992 void markDirty(DirtyMask fields);
993
997
1001
1006
1007Q_SIGNALS:
1008 // WARNING: AutotileEngine connects to this signal via string-based SIGNAL/SLOT
1009 // (it holds IWindowTrackingService*, not WindowTrackingService*, so PMF connect
1010 // is unavailable). Renaming this signal will silently break autotile zone tracking.
1011 void windowZoneChanged(const QString& windowId, const QString& zoneId);
1012
1017
1018private:
1019 // Minimum visible area for geometry validation
1020 static constexpr int MinVisibleWidth = 100;
1021 static constexpr int MinVisibleHeight = 100;
1022
1023 // Helpers
1024 //
1025 // scheduleSaveState() wraps markDirty(DirtyAll). Retained as the
1026 // default entry point for mutators that haven't been updated to
1027 // declare which specific fields they touch — marking everything dirty
1028 // is behaviorally equivalent to the pre-refactor code. Hot-path
1029 // mutators (assign/unassign zone, storePreTileGeometry, etc.) should
1030 // call markDirty() directly with a narrow mask so the next save
1031 // only re-serializes the fields that actually changed.
1032 void scheduleSaveState(DirtyMask fields = DirtyAll);
1033 bool isGeometryOnScreen(const QRect& geometry) const;
1034 QRect adjustGeometryToScreen(const QRect& geometry) const;
1035 PhosphorZones::Zone* findZoneById(const QString& zoneId) const;
1036
1039 template<typename Func>
1040 auto preFloatLookup(const QString& windowId, Func&& getter) const
1041 -> decltype(getter(std::declval<PhosphorSnapEngine::SnapState*>(), windowId));
1042
1050 void validateLastUsedZone(const QString& targetScreen);
1051
1054 static QString findNearestVirtualScreen(const QStringList& vsIds, int oldIndex);
1055
1058 struct ZoneLookupResult
1059 {
1060 PhosphorZones::Zone* zone = nullptr;
1061 PhosphorZones::Layout* layout = nullptr;
1062 };
1063 ZoneLookupResult findZoneInAllLayouts(const QUuid& zoneUuid) const;
1064
1065public:
1068 QString resolveEffectiveScreenId(const QString& screenId) const override;
1069
1072 QRect resolveZoneGeometry(const QStringList& zoneIds, const QString& screenId) const override;
1073
1074 QString findEmptyZoneInLayout(PhosphorZones::Layout* layout, const QString& screenId,
1075 int desktopFilter = 0) const override;
1076
1077 // Zone sort / position-map helpers now live in PhosphorZones::LayoutUtils.
1078 // Call PhosphorZones::LayoutUtils::sortZonesByNumber / buildZonePositionMap directly.
1079
1090 QSet<QUuid> buildOccupiedZoneSet(const QString& screenFilter = QString(), int desktopFilter = 0) const override;
1091
1100 QString currentAppIdFor(const QString& anyWindowId) const override;
1101
1108 QString canonicalizeForLookup(const QString& rawWindowId) const;
1109
1110private:
1111 // ── Snap-state resolution helpers (wrap the injected resolver) ───────────
1112 // Each returns nullptr / empty when the resolver is unwired, preserving the
1113 // historical "no SnapState" no-op guards at the call sites.
1114 PhosphorSnapEngine::SnapState* snapForWindow(const QString& windowId) const;
1115 PhosphorSnapEngine::SnapState* snapForWindowOnScreen(const QString& windowId, const QString& screenId);
1116 PhosphorSnapEngine::SnapState* snapForScreen(const QString& screenId) const;
1122 PhosphorSnapEngine::SnapState* snapRepresentativeLastUsed() const;
1128 bool clearGlobalLastUsedIfRemoved(const QStringList& removedZones,
1129 const PhosphorSnapEngine::SnapState* owningStore);
1130
1142 bool pruneMigratedWindows(const QStringList& windowsToRemove);
1143 PhosphorSnapEngine::SnapState* snapGlobals() const;
1146 QList<PhosphorSnapEngine::SnapState*> snapAllStates() const;
1149 bool hasSnapState() const;
1160 void forEachZoneAssignedWindow(const std::function<void(const QString& windowId, const QStringList& zoneIds,
1161 const QString& screenId, int desktop)>& fn) const;
1162
1167 void flushPendingUserSnappedClasses();
1168
1169 // Dependencies
1170 PhosphorZones::LayoutRegistry* m_layoutManager;
1171 SnapStateResolver m_snapResolver;
1174 std::optional<QSet<QString>> m_pendingUserSnappedClasses;
1175 PhosphorEngine::WindowPlacementStore m_placementStore;
1176 IGeometryResolver* m_geometryResolver;
1177 PlacementConfig m_config;
1178 PhosphorWorkspaces::VirtualDesktopManager* m_virtualDesktopManager;
1179 // Shared registry for current-class queries and canonical key translation.
1180 // Not owned. Null in unit tests. QPointer (not raw): both are Daemon
1181 // children whose destruction order relative to this service is not
1182 // contractual — a raw borrow dangled during Daemon child teardown, while
1183 // the QPointer auto-nulls and every use site already null-guards.
1184 QPointer<PhosphorEngine::WindowRegistry> m_windowRegistry;
1185 QPointer<PhosphorScreens::ScreenManager> m_screenManager;
1186 QPointer<PhosphorEngine::PlacementEngineBase> m_snapEngine;
1187 AutotileModePredicate m_autotileModePredicate{};
1188 EngineTiledPredicate m_engineTiledPredicate{};
1189 ModeEngineIdResolver m_modeEngineIdResolver{};
1190
1191 // Floating windows: full windowId at runtime, appId for session-restored entries
1192 // Converted from windowId to appId on window close for persistence.
1193 //
1194 // LEGACY FALLBACK ONLY: used when no per-engine resolver/writer is wired
1195 // (unit tests / early init). In production the daemon injects
1196 // m_engineFloatResolver / m_engineFloatWriter and this set is never read or
1197 // written by isWindowFloating / setWindowFloating.
1198 QSet<QString> m_floatingWindows;
1199
1200 // Suspension-float classification — see isSuspensionFloat(). Canonical-
1201 // keyed. Session-transient (never persisted): a restart's restored floats
1202 // are re-classified when their windows re-report minimize state.
1203 QSet<QString> m_suspensionFloats;
1204
1205 // Daemon-injected per-engine float reader/writer/lister. See setEngineFloatResolver.
1206 EngineFloatResolver m_engineFloatResolver{};
1207 EngineFloatWriter m_engineFloatWriter{};
1208 EngineFloatLister m_engineFloatLister{};
1209
1210 // Session persistence: consumption queue (appId -> list of pending restores, consumed FIFO)
1211 QHash<QString, QList<PendingRestore>> m_pendingRestoreQueues;
1212
1213 // Optional daemon-injected gate consulted before recording a PendingRestore
1214 // on windowClosed. When unset (e.g. unit tests), every context is treated
1215 // as active and the historical write-everything behavior is preserved.
1216 ShouldTrackPredicate m_shouldTrackPredicate{};
1217
1218 // Pre-float zone and screen state is owned by SnapState (authoritative store).
1219 // WTS preFloat getter methods add appId-fallback queries for session-restored
1220 // entries keyed by appId. SnapState itself uses windowId-only keys.
1221
1222 // Sticky window states
1223 QHash<QString, bool> m_windowStickyStates;
1224
1225 QVector<ResnapEntry> m_resnapBuffer;
1226
1227 // Delta-persistence dirty mask. Initial value DirtyAll forces the first
1228 // save after daemon startup to serialize every field. Cleared by
1229 // loadState() once in-memory state mirrors the disk file.
1230 DirtyMask m_dirtyMask = DirtyAll;
1231
1232 // Note: No save timer - persistence handled by WindowTrackingAdaptor via KConfig
1233 // Service emits stateChanged() signal when state needs saving
1234};
1235
1236} // namespace PhosphorPlacement
Definition IWindowTrackingService.h:34
Abstract base class for placement engines.
Definition PlacementEngineBase.h:32
The single source of truth for window restore state in the unified model.
Definition WindowPlacementStore.h:34
Definition WindowRegistry.h:101
Definition IGeometryResolver.h:17
Window-zone tracking service (business logic layer)
Definition WindowTrackingService.h:85
void recordFreeGeometry(const QString &windowId, const QString &screenId, const QRect &geometry, bool overwrite) override
Write the window's shared free/float geometry into the unified record (the single float-back store).
const QHash< QString, QList< PendingRestore > > & pendingRestoreQueues() const override
Get pending restore queues (consumption queue: appId -> list of pending restores)
bool consumePendingAssignment(const QString &windowId) override
Pop the oldest pending restore entry for this window's appId.
QString zoneForWindow(const QString &windowId) const override
Get the primary zone ID for a window.
bool isWindowInAutotileMode(const QString &windowId) const
True if the window's CURRENT screen mode is autotile.
void markDirty(DirtyMask fields)
OR the given fields into the dirty mask AND emit stateChanged.
void clearSuspensionFloat(const QString &windowId) override
Drop the suspension classification.
PhosphorProtocol::EmptyZoneList getEmptyZones(const QString &screenId) const
Get typed list of all empty zones for Snap Assist continuation.
bool isWindowSnapped(const QString &windowId) const override
Check if a window is assigned to any zone.
void assignWindowToZone(const QString &windowId, const QString &zoneId, const QString &screenId, int virtualDesktop) override
Assign a window to a zone.
void clearResnapBuffer()
Clear the resnap buffer.
QString screenForWindow(const QString &windowId, const QString &defaultScreen) const override
Same, but returns defaultScreen when the window has no screen assignment — the canonicalizing with-de...
void recordSnapIntent(const QString &windowId, bool wasUserInitiated) override
Record that a window class was user-snapped.
QVector< ResnapEntry > takeResnapBuffer() override
bool isWindowFloating(const QString &windowId) const override
Check if a window is floating (excluded from snapping)
QString findEmptyZoneInLayout(PhosphorZones::Layout *layout, const QString &screenId, int desktopFilter=0) const override
void setFloatingWindows(const QSet< QString > &windows)
Set floating windows (test / bulk-seed entry point)
void clearFreeGeometry(const QString &windowId, const QString &screenId) override
Screen-scoped consume-once variant: clears only screenId's remembered float-back, preserving other mo...
QString preFloatScreen(const QString &windowId) const override
Get the screen name where the window was snapped before floating.
QStringList buildZoneOrderedWindowList(const QString &screenId) const
Build a zone-ordered window list for a screen from current zone assignments.
bool isWindowSticky(const QString &windowId) const override
Check if window is sticky.
uint32_t DirtyMask
Definition WindowTrackingService.h:983
DirtyMask peekDirty() const
Return the current dirty mask without clearing.
const PhosphorEngine::WindowPlacementStore & placementStore() const
void setSnapEngine(PhosphorEngine::PlacementEngineBase *engine)
Wire the snap-mode placement engine.
QString currentAppIdFor(const QString &anyWindowId) const override
Current app class for a windowId, preferring the live registry.
void markSuspensionFloat(const QString &windowId)
static void downgradeMismatchedManagedSlots(PhosphorEngine::WindowPlacement &placement, const QString &recordedScreenId, const QString &closeScreenId)
Downgrade managed slots recorded against a different screen.
QSet< QString > physicalScreensWithStaleVirtualAssignments(const QSet< QString > &subdividedPhysicalIds) const
Find physical screens whose state still references virtual ids, excluding screens the caller knows ar...
bool isAutoSnapped(const QString &windowId) const
Check if a window was auto-snapped.
void setPendingRestoreQueues(const QHash< QString, QList< PendingRestore > > &queues)
Set pending restore queues (test / bulk-seed entry point)
void unassignWindow(const QString &windowId) override
Remove window from its assigned zone.
void migrateScreenAssignmentsToVirtual(const QString &physicalScreenId, const QStringList &virtualScreenIds, PhosphorScreens::ScreenManager *mgr)
Migrate window screen assignments from physical to virtual screen IDs.
PhosphorScreens::ScreenManager * screenManager() const override
QString preFloatZone(const QString &windowId) const
Get primary zone to restore to when unfloating.
void setEngineFloatResolver(EngineFloatResolver resolver)
QHash< QString, QRect > updatedWindowGeometries() const
Get updated geometries for all tracked windows.
bool clearAutoSnapped(const QString &windowId) override
Clear auto-snapped flag for a window.
std::function< QString(const QString &windowId, const QString &screenId)> ModeEngineIdResolver
Resolver: which engine id owns windowId's mode on screenId?
Definition WindowTrackingService.h:250
void clearPreFloatZone(const QString &windowId) override
Clear pre-float zone after restore (both windowId and appId keys)
QRect zoneGeometry(const QString &zoneId, const QString &screenId=QString()) const override
Get geometry for a zone on a specific screen.
QString lastUsedScreenName() const
Screen name companion of the last-used-zone tracking.
int pruneStaleAssignments(const QSet< QString > &aliveWindowIds)
Remove zone/screen/desktop assignments for windows not in the alive set.
void populateResnapBufferForAllScreens(const QSet< QString > &excludeScreens={}, const QSet< QString > &includeScreens={}, int desktopFilter=0)
Populate the resnap buffer for all screens independently.
std::function< void(const QString &windowId, bool floating)> EngineFloatWriter
Definition WindowTrackingService.h:445
bool isWindowEngineTiled(const QString &windowId) const
True if a tiling-family engine (autotile / scrolling) reports the window actively tiled.
std::optional< QRect > validateGeometryForScreen(const QRect &geo, const QString &savedScreen, const QString &currentScreenName) const
Validate and adjust a saved geometry for screen-aware restore.
QStringList snappedWindows() const
Get all snapped windows.
QString lastUsedZoneId() const
Get last used zone ID.
bool clearFloatingForSnap(const QString &windowId) override
Clear floating state when snapping a floating window.
void releaseEngineSlot(const QString &windowId, const QString &engineId) override
Downgrade engineId's slot to released on windowId's record(s) and mark the placements dirty — the dir...
void assignWindowToZones(const QString &windowId, const QStringList &zoneIds, const QString &screenId, int virtualDesktop) override
Assign a window to multiple zones (multi-zone snap)
void recordFloatingClose(const QString &windowId, const QString &screenId, const QRect &geometry)
Authoritative float-back capture for a window closing on screenId.
QStringList recordedSnapZones(const QString &windowId) const override
Live snap zones if present, else the durable placement-record snap slot.
QStringList preFloatZones(const QString &windowId) const override
Get all zones to restore to when unfloating (multi-zone support)
void setEngineFloatLister(EngineFloatLister lister)
Aggregates every engine's floating windows for the engine-agnostic floatingWindows() enumeration.
DirtyField
Definition WindowTrackingService.h:966
void clearDirty()
Clear every dirty bit.
void windowZoneChanged(const QString &windowId, const QString &zoneId)
QRect resolveZoneGeometry(const QStringList &zoneIds, const QString &screenId) const override
Resolve zone geometry: combined geometry for multi-zone, single for single zone.
PhosphorEngine::WindowPlacementStore & placementStore() override
The unified, engine-agnostic placement store (one WindowPlacement record per window).
void migrateScreenAssignmentsFromVirtual(const QString &physicalScreenId)
Reverse migration: virtual screen IDs → physical screen ID.
int lastUsedDesktop() const
Virtual-desktop companion of the last-used-zone tracking.
void setModeEngineIdResolver(ModeEngineIdResolver resolver)
QStringList floatingWindows() const
Get all floating window IDs.
PhosphorEngine::WindowRegistry * windowRegistry() const
Accessor for consumers that need direct access (effect, adaptor).
std::optional< QRect > validatedUnmanagedGeometry(const QString &windowId, const QString &screenId, bool exactOnly=false) const override
Look up a window's free (unmanaged) geometry from the unified WindowPlacementStore,...
void setLastUsedZone(const QString &zoneId, const QString &screenId, const QString &zoneClass, int desktop)
Set last used zone info (loaded from KConfig by adaptor)
void setAutotileModePredicate(AutotileModePredicate predicate)
QString canonicalizeForLookup(const QString &rawWindowId) const
Canonicalize for read-only callers (no map mutation).
QHash< QString, PendingRestoreTarget > pendingRestoreGeometries() const
Pre-compute zone geometries for all pending restore entries.
void setShouldTrackPredicate(ShouldTrackPredicate predicate)
Inject a context-active predicate.
void unsnapForFloat(const QString &windowId) override
Unsnap window for floating (saves zone for later restore)
QString findEmptyZone(const QString &screenId=QString()) const override
Find the first empty zone in the layout for a screen.
DirtyMask takeDirty()
Return the current dirty mask, clearing it atomically.
void setEngineTiledPredicate(EngineTiledPredicate predicate)
void setSnapStateResolver(SnapStateResolver resolver)
QString screenForWindow(const QString &windowId) const override
The screen a window is assigned to, or empty when it has none.
std::function< QStringList()> EngineFloatLister
Definition WindowTrackingService.h:446
void setWindowFloating(const QString &windowId, bool floating) override
Set window floating state.
QSet< QUuid > buildOccupiedZoneSet(const QString &screenFilter=QString(), int desktopFilter=0) const override
Build set of occupied zone UUIDs, optionally filtered by screen and virtual desktop.
void updateLastUsedZone(const QString &zoneId, const QString &screenId, const QString &windowClass, int virtualDesktop) override
Update last used zone tracking.
void onLayoutChanged()
Handle layout change - validate/clear stale zone assignments.
QRect multiZoneGeometry(const QStringList &zoneIds, const QString &screenId=QString()) const
Get combined geometry for multiple zones on a specific screen.
std::function< bool(const QString &windowId)> EngineTiledPredicate
Predicate: is the window ACTIVELY TILED by a tiling-family engine (autotile / scrolling) right now (e...
Definition WindowTrackingService.h:230
void setWindowSticky(const QString &windowId, bool sticky)
Record whether a window is sticky (on all desktops)
QString owningModeEngineId(const QString &windowId, const QString &screenId) const
The owning engine id for windowId on screenId per the resolver; snap's engine id when the resolver is...
void clearFreeGeometry(const QString &windowId) override
Clear a window's shared free/float geometry from the record.
void setWindowRegistry(PhosphorEngine::WindowRegistry *registry)
Wire up the shared WindowRegistry.
void setUserSnappedClasses(const QSet< QString > &classes)
Set user-snapped classes (loaded from KConfig by adaptor)
void stateChanged()
Emitted when state needs to be saved.
QStringList windowsInZone(const QString &zoneId) const override
Get all windows in a specific zone.
void windowClosed(const QString &windowId, PhosphorEngine::WindowKind kind=PhosphorEngine::WindowKind::Unknown)
Clean up all tracking data for a closed window.
std::function< bool(const QString &windowId)> AutotileModePredicate
Predicate: is the window currently in Autotile mode?
Definition WindowTrackingService.h:201
std::function< bool(const QString &windowId)> EngineFloatResolver
Per-engine float resolver/writer.
Definition WindowTrackingService.h:444
void setSnapState(PhosphorSnapEngine::SnapState *state)
Convenience wiring for a SINGLE snap store (unit tests / the collapsed Phase-2 store).
const QSet< QString > & userSnappedClasses() const
Get user-snapped classes.
QStringList zonesForWindow(const QString &windowId) const override
Get all zone IDs for a window (multi-zone support)
const PlacementConfig & config() const
The placement config installed at construction.
Definition WindowTrackingService.h:100
void markAsAutoSnapped(const QString &windowId)
Mark a window as auto-snapped.
void retagLastUsedZoneClass(const QString &newClass)
Update the last-used-zone class tag without touching zone/screen.
bool isSuspensionFloat(const QString &windowId) const override
Suspension-float classification (minimize-floats).
PhosphorEngine::PlacementEngineBase * snapEngine() const
QString lastUsedZoneClass() const
App class string stamped on the last-used-zone tracking.
QString resolveEffectiveScreenId(const QString &screenId) const override
Resolve a screen ID to an effective screen ID, falling back to the physical screen ID if a virtual sc...
void setEngineFloatWriter(EngineFloatWriter writer)
std::function< bool(const QString &screenId, int virtualDesktop)> ShouldTrackPredicate
Predicate type for "is this snap-mode context active?".
Definition WindowTrackingService.h:156
WindowTrackingService(PhosphorZones::LayoutRegistry *layoutManager, PhosphorScreens::ScreenManager *screenManager, PhosphorWorkspaces::VirtualDesktopManager *vdm, IGeometryResolver *geometryResolver=nullptr, PlacementConfig config={}, QObject *parent=nullptr)
Centralized screen-topology service.
Definition Manager.h:75
Per-screen snap placement state.
Definition SnapState.h:32
Definition VirtualDesktopManager.h:19
Manual zone-layout registry + per-context assignment store.
Definition LayoutRegistry.h:89
Represents a collection of zones that form a layout.
Definition Layout.h:42
Represents a single zone within a layout.
Definition Zone.h:44
WindowKind
Coarse structural classification for the snap-restore consume gate.
Definition EngineTypes.h:66
Definition IGeometryResolver.h:14
constexpr QLatin1String LayoutRegistry("org.plasmazones.LayoutRegistry")
QList< EmptyZoneEntry > EmptyZoneList
Definition ZoneTypes.h:58
Definition IWindowTrackingService.h:27
Definition SnapStateResolver.h:11
Definition WindowTrackingService.h:51
Definition IWindowTrackingService.h:23
Definition EngineTypes.h:103
Definition EngineTypes.h:95
One window's single, authoritative placement record — the unit of the unified, engine-agnostic restor...
Definition WindowPlacement.h:68
Definition PlacementConfig.h:11
Seam onto the snap engine's per-(screen,desktop,activity) SnapState stores.
Definition SnapStateResolver.h:27
Pre-computed snap restore target: zone geometry + the saved screen it lives on.
Definition WindowTrackingService.h:834
QString screenId
Definition WindowTrackingService.h:836
QRect geometry
Definition WindowTrackingService.h:835