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#pragma once
5
6#include <phosphorplacement_export.h>
7
17
18#include <QHash>
19#include <QObject>
20#include <QPointer>
21#include <QRect>
22#include <QSet>
23#include <QString>
24#include <QStringList>
25
26#include <functional>
27#include <optional>
28#include <utility>
29
30namespace PhosphorZones {
31class IZoneDetector;
32class Layout;
33class LayoutRegistry;
34class Zone;
35}
36
38class SnapState;
39}
40
41namespace PhosphorEngine {
42class WindowRegistry;
43}
44
48
49namespace Phosphor::Screens {
50class ScreenManager;
51}
52
53namespace PhosphorPlacement {
54
78class PHOSPHORPLACEMENT_EXPORT WindowTrackingService : public QObject, public PhosphorEngine::IWindowTrackingService
79{
80 Q_OBJECT
81
82public:
84 PhosphorZones::IZoneDetector* zoneDetector,
87 IGeometryResolver* geometryResolver = nullptr, PlacementConfig config = {},
88 QObject* parent = nullptr);
89
90 void setConfig(const PlacementConfig& config)
91 {
92 m_config = config;
93 }
94 const PlacementConfig& config() const
95 {
96 return m_config;
97 }
98
99 QObject* asQObject() override
100 {
101 return this;
102 }
104
115 {
116 m_windowRegistry = registry;
117 }
118
120 {
121 m_snapState = state;
122 }
123
142 using ShouldTrackPredicate = std::function<bool(const QString& screenId, int virtualDesktop)>;
143
163 {
164 m_shouldTrackPredicate = std::move(predicate);
165 }
166
177 {
178 m_snapEngine = engine;
179 }
180
182 {
183 return m_snapEngine.data();
184 }
185
190 {
191 return m_windowRegistry;
192 }
193
195 {
196 return m_screenManager;
197 }
198
199 // ═══════════════════════════════════════════════════════════════════════════
200 // PhosphorZones::Zone Assignment Management
201 // ═══════════════════════════════════════════════════════════════════════════
202
210 void assignWindowToZone(const QString& windowId, const QString& zoneId, const QString& screenId,
211 int virtualDesktop) override;
212
220 void assignWindowToZones(const QString& windowId, const QStringList& zoneIds, const QString& screenId,
221 int virtualDesktop) override;
222
227 void unassignWindow(const QString& windowId) override;
228
234 QString zoneForWindow(const QString& windowId) const override;
235
241 QStringList zonesForWindow(const QString& windowId) const override;
242
248 QStringList windowsInZone(const QString& zoneId) const override;
249
254 QStringList snappedWindows() const;
255
258 int pruneStaleAssignments(const QSet<QString>& aliveWindowIds);
259
263 bool isWindowSnapped(const QString& windowId) const override;
264
265 // ═══════════════════════════════════════════════════════════════════════════
266 // Geometry Validation Utility
267 // ═══════════════════════════════════════════════════════════════════════════
268
283 std::optional<QRect> validateGeometryForScreen(const QRect& geo, const QString& savedScreen,
284 const QString& currentScreenName) const;
285
297 std::optional<QRect> validatedUnmanagedGeometry(const QString& windowId, const QString& screenId,
298 bool exactOnly = false) const override;
299
300 // ═══════════════════════════════════════════════════════════════════════════
301 // Floating Window State
302 // ═══════════════════════════════════════════════════════════════════════════
303
307 bool isWindowFloating(const QString& windowId) const override;
308
314 void setWindowFloating(const QString& windowId, bool floating) override;
315
319 QStringList floatingWindows() const;
320
325 void unsnapForFloat(const QString& windowId) override;
326
332 QString preFloatZone(const QString& windowId) const;
333
339 QStringList preFloatZones(const QString& windowId) const override;
340
346 QString preFloatScreen(const QString& windowId) const override;
347
351 void clearPreFloatZone(const QString& windowId);
352
358 void clearPreFloatZoneForWindow(const QString& windowId);
359
370 bool clearFloatingForSnap(const QString& windowId) override;
371
372 // ═══════════════════════════════════════════════════════════════════════════
373 // Sticky Window Handling
374 // ═══════════════════════════════════════════════════════════════════════════
375
379 void setWindowSticky(const QString& windowId, bool sticky);
380
384 bool isWindowSticky(const QString& windowId) const override;
385
386 // ═══════════════════════════════════════════════════════════════════════════
387 // Auto-Snap Logic
388 // ═══════════════════════════════════════════════════════════════════════════
389
395 void recordSnapIntent(const QString& windowId, bool wasUserInitiated) override;
396
400 QString lastUsedZoneId() const;
401
408 QString lastUsedZoneClass() const;
409
418 void retagLastUsedZoneClass(const QString& newClass);
419
423 void updateLastUsedZone(const QString& zoneId, const QString& screenId, const QString& windowClass,
424 int virtualDesktop) override;
425
435 void markAsAutoSnapped(const QString& windowId);
436
442 bool isAutoSnapped(const QString& windowId) const;
443
449 bool clearAutoSnapped(const QString& windowId) override;
450
480 bool consumePendingAssignment(const QString& windowId) override;
481
512 int pruneExcludedPendingRestores(const QStringList& exclusionPatterns);
513
514 // ═══════════════════════════════════════════════════════════════════════════
515 // Navigation Helpers
516 // ═══════════════════════════════════════════════════════════════════════════
517
523 QString findEmptyZone(const QString& screenId = QString()) const override;
524
530 PhosphorProtocol::EmptyZoneList getEmptyZones(const QString& screenId) const;
531
538 QRect zoneGeometry(const QString& zoneId, const QString& screenId = QString()) const override;
539
546 QRect multiZoneGeometry(const QStringList& zoneIds, const QString& screenId = QString()) const;
547
567 void populateResnapBufferForAllScreens(const QSet<QString>& excludeScreens = {},
568 const QSet<QString>& includeScreens = {}, int desktopFilter = 0);
569
577 {
578 m_resnapBuffer.clear();
579 }
580
591 QStringList buildZoneOrderedWindowList(const QString& screenId) const;
592
593 // ═══════════════════════════════════════════════════════════════════════════
594 // Virtual Screen Migration
595 // ═══════════════════════════════════════════════════════════════════════════
596
615 void migrateScreenAssignmentsToVirtual(const QString& physicalScreenId, const QStringList& virtualScreenIds,
617
627 void migrateScreenAssignmentsFromVirtual(const QString& physicalScreenId);
628
652 QSet<QString> physicalScreensWithStaleVirtualAssignments(const QSet<QString>& subdividedPhysicalIds) const;
653
654 // ═══════════════════════════════════════════════════════════════════════════
655 // Resolution Change Handling
656 // ═══════════════════════════════════════════════════════════════════════════
657
664 QHash<QString, QRect> updatedWindowGeometries() const;
665
675 {
676 QRect geometry;
677 QString screenId;
678 };
679
693 QHash<QString, PendingRestoreTarget> pendingRestoreGeometries() const;
694
695 // ═══════════════════════════════════════════════════════════════════════════
696 // Window Lifecycle
697 // ═══════════════════════════════════════════════════════════════════════════
698
709
714
715 // ═══════════════════════════════════════════════════════════════════════════
716 // State Access (for adaptor persistence via KConfig)
717 // ═══════════════════════════════════════════════════════════════════════════
718
723 const QHash<QString, QStringList>& zoneAssignments() const override;
724
728 const QHash<QString, QString>& screenAssignments() const override;
729
733 const QHash<QString, int>& desktopAssignments() const;
734
737
741 const QHash<QString, QList<PendingRestore>>& pendingRestoreQueues() const override
742 {
743 return m_pendingRestoreQueues;
744 }
745
746 QVector<ResnapEntry> takeResnapBuffer() override
747 {
748 return std::exchange(m_resnapBuffer, {});
749 }
750
754 const QSet<QString>& userSnappedClasses() const;
755
763 void setActiveAssignments(const QHash<QString, QStringList>& zones, const QHash<QString, QString>& screens,
764 const QHash<QString, int>& desktops);
765
769 void setPendingRestoreQueues(const QHash<QString, QList<PendingRestore>>& queues)
770 {
771 m_pendingRestoreQueues = queues;
772 }
773
777 void setUserSnappedClasses(const QSet<QString>& classes);
778
782 void setLastUsedZone(const QString& zoneId, const QString& screenId, const QString& zoneClass, int desktop);
783
787 void setFloatingWindows(const QSet<QString>& windows)
788 {
789 m_floatingWindows = windows;
790 }
791
797 const QHash<QString, QStringList>& preFloatZoneAssignments() const;
798 const QHash<QString, QString>& preFloatScreenAssignments() const;
799
805 void setPreFloatZoneAssignments(const QHash<QString, QStringList>& assignments);
806 void setPreFloatScreenAssignments(const QHash<QString, QString>& assignments);
807
808 // ═══════════════════════════════════════════════════════════════════════
809 // Dirty field tracking (Phase 3 of refactor/dbus-performance)
810 //
811 // Replaces "any mutation forces a full re-serialization" with a bitfield
812 // mask of which persisted state has changed since the last successful
813 // save. WindowTrackingAdaptor::saveState() reads this mask to decide
814 // which JSON maps to re-write, and the persistence worker's write-
815 // completed signal clears the committed bits — surviving bits either
816 // represent new mutations that landed during the in-flight write, or
817 // the write itself failed (same treatment in both cases: retry on the
818 // next tick).
819 //
820 // The mask is initialized to All so the first save after a daemon
821 // startup always writes every field. loadState() should clear the mask
822 // immediately after populating in-memory state so the first real save
823 // doesn't redundantly write back what we just loaded.
824 // ═══════════════════════════════════════════════════════════════════════
825 enum DirtyField : uint32_t {
826 DirtyNone = 0,
827 DirtyActiveLayoutId = 1u << 0,
828 DirtyZoneAssignments = 1u << 1, // zones + screens + desktops (always written together)
829 DirtyPendingRestores = 1u << 2,
830 DirtyPreTileGeometries = 1u << 3,
831 DirtyLastUsedZone = 1u << 4,
832 DirtyPreFloatZones = 1u << 5,
833 DirtyPreFloatScreens = 1u << 6,
834 DirtyUserSnapped = 1u << 7,
835 DirtyAutotileOrders = 1u << 8,
836 DirtyAutotilePending = 1u << 9,
837 DirtyAll = 0x3FFu,
838 };
839 using DirtyMask = uint32_t;
840
848 void markDirty(DirtyMask fields);
849
853
857 {
858 return m_dirtyMask;
859 }
860
865
866Q_SIGNALS:
867 // WARNING: AutotileEngine connects to this signal via string-based SIGNAL/SLOT
868 // (it holds IWindowTrackingService*, not WindowTrackingService*, so PMF connect
869 // is unavailable). Renaming this signal will silently break autotile zone tracking.
870 void windowZoneChanged(const QString& windowId, const QString& zoneId);
871
876
877private:
878 // Minimum visible area for geometry validation
879 static constexpr int MinVisibleWidth = 100;
880 static constexpr int MinVisibleHeight = 100;
881
882 // Helpers
883 //
884 // scheduleSaveState() wraps markDirty(DirtyAll). Retained as the
885 // default entry point for mutators that haven't been updated to
886 // declare which specific fields they touch — marking everything dirty
887 // is behaviorally equivalent to the pre-refactor code. Hot-path
888 // mutators (assign/unassign zone, storePreTileGeometry, etc.) should
889 // call markDirty() directly with a narrow mask so the next save
890 // only re-serializes the fields that actually changed.
891 void scheduleSaveState(DirtyMask fields = DirtyAll);
892 bool isGeometryOnScreen(const QRect& geometry) const;
893 QRect adjustGeometryToScreen(const QRect& geometry) const;
894 PhosphorZones::Zone* findZoneById(const QString& zoneId) const;
895
897 template<typename Func>
898 auto preFloatLookup(const QString& windowId, Func&& getter) const -> decltype(getter(windowId));
899
901 void validateLastUsedZone(const QString& targetScreen);
902
905 static QString findNearestVirtualScreen(const QStringList& vsIds, int oldIndex);
906
909 struct ZoneLookupResult
910 {
911 PhosphorZones::Zone* zone = nullptr;
912 PhosphorZones::Layout* layout = nullptr;
913 };
914 ZoneLookupResult findZoneInAllLayouts(const QUuid& zoneUuid) const;
915
916public:
919 QString resolveEffectiveScreenId(const QString& screenId) const override;
920
923 QRect resolveZoneGeometry(const QStringList& zoneIds, const QString& screenId) const override;
924
925 QString findEmptyZoneInLayout(PhosphorZones::Layout* layout, const QString& screenId,
926 int desktopFilter = 0) const override;
927
928 // Zone sort / position-map helpers now live in PhosphorZones::LayoutUtils.
929 // Call PhosphorZones::LayoutUtils::sortZonesByNumber / buildZonePositionMap directly.
930
941 QSet<QUuid> buildOccupiedZoneSet(const QString& screenFilter = QString(), int desktopFilter = 0) const override;
942
951 QString currentAppIdFor(const QString& anyWindowId) const override;
952
959 QString canonicalizeForLookup(const QString& rawWindowId) const;
960
961private:
962 // Dependencies
963 PhosphorZones::LayoutRegistry* m_layoutManager;
964 PhosphorZones::IZoneDetector* m_zoneDetector;
965 PhosphorSnapEngine::SnapState* m_snapState = nullptr;
966 IGeometryResolver* m_geometryResolver;
967 PlacementConfig m_config;
968 PhosphorWorkspaces::VirtualDesktopManager* m_virtualDesktopManager;
969 // Shared registry for current-class queries and canonical key translation.
970 // Not owned. Null in unit tests.
971 PhosphorEngine::WindowRegistry* m_windowRegistry = nullptr;
972 Phosphor::Screens::ScreenManager* m_screenManager = nullptr;
973 QPointer<PhosphorEngine::PlacementEngineBase> m_snapEngine;
974
975 // Floating windows: full windowId at runtime, appId for session-restored entries
976 // Converted from windowId to appId on window close for persistence
977 QSet<QString> m_floatingWindows;
978
979 // Session persistence: consumption queue (appId -> list of pending restores, consumed FIFO)
980 QHash<QString, QList<PendingRestore>> m_pendingRestoreQueues;
981
982 // Optional daemon-injected gate consulted before recording a PendingRestore
983 // on windowClosed. When unset (e.g. unit tests), every context is treated
984 // as active and the historical write-everything behavior is preserved.
985 ShouldTrackPredicate m_shouldTrackPredicate{};
986
987 // Pre-float zone and screen state is owned by SnapState (authoritative store).
988 // WTS preFloat getter methods add appId-fallback queries for session-restored
989 // entries keyed by appId. SnapState itself uses windowId-only keys.
990
991 // Sticky window states
992 QHash<QString, bool> m_windowStickyStates;
993
994 QVector<ResnapEntry> m_resnapBuffer;
995
996 // Delta-persistence dirty mask. Initial value DirtyAll forces the first
997 // save after daemon startup to serialize every field. Cleared by
998 // loadState() once in-memory state mirrors the disk file.
999 DirtyMask m_dirtyMask = DirtyAll;
1000
1001 // Note: No save timer - persistence handled by WindowTrackingAdaptor via KConfig
1002 // Service emits stateChanged() signal when state needs saving
1003};
1004
1005} // namespace PhosphorPlacement
Definition IWindowTrackingService.h:33
Abstract base class for placement engines.
Definition PlacementEngineBase.h:37
Definition WindowRegistry.h:34
Definition IGeometryResolver.h:17
Window-zone tracking service (business logic layer)
Definition WindowTrackingService.h:79
const QHash< QString, QList< PendingRestore > > & pendingRestoreQueues() const override
Get pending restore queues (consumption queue: appId -> list of pending restores)
Definition WindowTrackingService.h:741
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.
void markDirty(DirtyMask fields)
OR the given fields into the dirty mask AND emit stateChanged.
Phosphor::Screens::ScreenManager * screenManager() const override
Definition WindowTrackingService.h:194
PhosphorProtocol::EmptyZoneList getEmptyZones(const QString &screenId) const
Get typed list of all empty zones for Snap Assist continuation.
void setConfig(const PlacementConfig &config)
Definition WindowTrackingService.h:90
const QHash< QString, QStringList > & zoneAssignments() const override
Get all zone assignments for persistence.
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.
Definition WindowTrackingService.h:576
void recordSnapIntent(const QString &windowId, bool wasUserInitiated) override
Record that a window class was user-snapped.
QVector< ResnapEntry > takeResnapBuffer() override
Definition WindowTrackingService.h:746
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 (loaded from KConfig by adaptor)
Definition WindowTrackingService.h:787
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.
void clearPreFloatZoneForWindow(const QString &windowId)
Clear pre-float zone for a specific window only (not appId)
uint32_t DirtyMask
Definition WindowTrackingService.h:839
DirtyMask peekDirty() const
Return the current dirty mask without clearing.
Definition WindowTrackingService.h:856
void setPreFloatScreenAssignments(const QHash< QString, QString > &assignments)
void clearPreFloatZone(const QString &windowId)
Clear pre-float zone after restore (both windowId and appId keys)
void setSnapEngine(PhosphorEngine::PlacementEngineBase *engine)
Wire the snap-mode placement engine for unmanaged geometry queries.
Definition WindowTrackingService.h:176
QString currentAppIdFor(const QString &anyWindowId) const override
Current app class for a windowId, preferring the live registry.
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 (loaded from KConfig by adaptor)
Definition WindowTrackingService.h:769
void unassignWindow(const QString &windowId) override
Remove window from its assigned zone.
QObject * asQObject() override
Definition WindowTrackingService.h:99
void setPreFloatZoneAssignments(const QHash< QString, QStringList > &assignments)
Set pre-float zone assignments (loaded from KConfig by adaptor)
WindowTrackingService(PhosphorZones::LayoutRegistry *layoutManager, PhosphorZones::IZoneDetector *zoneDetector, Phosphor::Screens::ScreenManager *screenManager, PhosphorWorkspaces::VirtualDesktopManager *vdm, IGeometryResolver *geometryResolver=nullptr, PlacementConfig config={}, QObject *parent=nullptr)
QString preFloatZone(const QString &windowId) const
Get primary zone to restore to when unfloating.
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.
QRect zoneGeometry(const QString &zoneId, const QString &screenId=QString()) const override
Get geometry for a zone on a specific screen.
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::optional< QRect > validateGeometryForScreen(const QRect &geo, const QString &savedScreen, const QString &currentScreenName) const
Validate and adjust a saved geometry for screen-aware restore.
void setActiveAssignments(const QHash< QString, QStringList > &zones, const QHash< QString, QString > &screens, const QHash< QString, int > &desktops)
Set active zone/screen/desktop assignments (loaded from KConfig by adaptor)
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 assignWindowToZones(const QString &windowId, const QStringList &zoneIds, const QString &screenId, int virtualDesktop) override
Assign a window to multiple zones (multi-zone snap)
QStringList preFloatZones(const QString &windowId) const override
Get all zones to restore to when unfloating (multi-zone support)
DirtyField
Definition WindowTrackingService.h:825
int pruneExcludedPendingRestores(const QStringList &exclusionPatterns)
Drop pending-restore queues whose appId matches any exclusion pattern.
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.
void migrateScreenAssignmentsFromVirtual(const QString &physicalScreenId)
Reverse migration: virtual screen IDs → physical screen ID.
const QHash< QString, int > & desktopAssignments() const
Get all desktop assignments for persistence.
QStringList floatingWindows() const
Get all floating window IDs.
PhosphorEngine::WindowRegistry * windowRegistry() const
Accessor for consumers that need direct access (effect, adaptor).
Definition WindowTrackingService.h:189
std::optional< QRect > validatedUnmanagedGeometry(const QString &windowId, const QString &screenId, bool exactOnly=false) const override
Look up unmanaged geometry from the snap engine with appId fallback and validate.
void setLastUsedZone(const QString &zoneId, const QString &screenId, const QString &zoneClass, int desktop)
Set last used zone info (loaded from KConfig by adaptor)
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.
Definition WindowTrackingService.h:162
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 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.
const QHash< QString, QString > & preFloatScreenAssignments() const
void setWindowSticky(const QString &windowId, bool sticky)
Record whether a window is sticky (on all desktops)
void setWindowRegistry(PhosphorEngine::WindowRegistry *registry)
Wire up the shared WindowRegistry.
Definition WindowTrackingService.h:114
const QHash< QString, QStringList > & preFloatZoneAssignments() const
Get pre-float zone assignments for persistence.
void setUserSnappedClasses(const QSet< QString > &classes)
Set user-snapped classes (loaded from KConfig by adaptor)
const QHash< QString, QString > & screenAssignments() const override
Get all screen assignments for persistence.
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.
void setSnapState(PhosphorSnapEngine::SnapState *state)
Definition WindowTrackingService.h:119
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
Definition WindowTrackingService.h:94
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.
PhosphorEngine::PlacementEngineBase * snapEngine() const
Definition WindowTrackingService.h:181
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...
std::function< bool(const QString &screenId, int virtualDesktop)> ShouldTrackPredicate
Predicate type for "is this snap-mode context active?".
Definition WindowTrackingService.h:142
void migrateScreenAssignmentsToVirtual(const QString &physicalScreenId, const QStringList &virtualScreenIds, Phosphor::Screens::ScreenManager *mgr)
Migrate window screen assignments from physical to virtual screen IDs.
Per-screen snap placement state.
Definition SnapState.h:32
Definition VirtualDesktopManager.h:17
Abstract interface for zone detection + highlight lifecycle.
Definition IZoneDetector.h:84
Manual zone-layout registry + per-context assignment store.
Definition LayoutRegistry.h:48
Represents a collection of zones that form a layout.
Definition Layout.h:74
Represents a single zone within a layout.
Definition Zone.h:44
Centralized screen-topology service.
Definition Manager.h:75
Definition EngineTypes.h:13
WindowKind
Coarse structural classification for the snap-restore consume gate.
Definition EngineTypes.h:39
Definition IGeometryResolver.h:14
constexpr QLatin1String LayoutRegistry("org.plasmazones.LayoutRegistry")
QList< EmptyZoneEntry > EmptyZoneList
Definition ZoneTypes.h:58
Definition WindowTrackingService.h:37
Definition WindowTrackingService.h:45
Definition IWindowTrackingService.h:22
Definition IWindowTrackingService.h:26
Definition EngineTypes.h:55
Definition EngineTypes.h:46
Definition PlacementConfig.h:11
Pre-computed snap restore target: zone geometry + the saved screen it lives on.
Definition WindowTrackingService.h:675
QString screenId
Definition WindowTrackingService.h:677
QRect geometry
Definition WindowTrackingService.h:676