Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
TilingState.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 "AutotileConstants.h"
8#include <phosphortiles_export.h>
9#include <QObject>
10#include <QJsonObject>
11#include <QRect>
12#include <QSet>
13#include <QString>
14#include <QStringList>
15#include <QVector>
16
17#include <functional>
18#include <memory>
19
20namespace PhosphorTiles {
21
22class SplitTree;
23struct SplitNode;
24
39class PHOSPHORTILES_EXPORT TilingState : public QObject, public PhosphorEngine::IPlacementState
40{
41 Q_OBJECT
42
43 Q_PROPERTY(QString screenId READ screenId CONSTANT)
44 Q_PROPERTY(int windowCount READ windowCount NOTIFY windowCountChanged)
45 Q_PROPERTY(int tiledWindowCount READ tiledWindowCount NOTIFY windowCountChanged)
46 Q_PROPERTY(int masterCount READ masterCount WRITE setMasterCount NOTIFY masterCountChanged)
47 Q_PROPERTY(qreal splitRatio READ splitRatio WRITE setSplitRatio NOTIFY splitRatioChanged)
48
49public:
55 explicit TilingState(const QString& screenId, QObject* parent = nullptr);
56 ~TilingState() override;
57
58 // Prevent copying (QObject rule)
59 TilingState(const TilingState&) = delete;
61
65 QString screenId() const override;
66
67 // ═══════════════════════════════════════════════════════════════════════
68 // Window Order Management
69 // ═══════════════════════════════════════════════════════════════════════
70
74 int windowCount() const override;
75
79 int tiledWindowCount() const override;
80
85 QStringList windowOrder() const;
86
90 QStringList tiledWindows() const;
91
98 bool addWindow(const QString& windowId, int position = -1);
99
105 bool removeWindow(const QString& windowId);
106
113 bool moveWindow(int fromIndex, int toIndex);
114
121 bool swapWindows(int index1, int index2);
122
129 bool swapWindowsById(const QString& windowId1, const QString& windowId2);
130
136 int windowIndex(const QString& windowId) const;
137
141 bool containsWindow(const QString& windowId) const override;
142
143 // ═══════════════════════════════════════════════════════════════════════
144 // Master Management
145 // ═══════════════════════════════════════════════════════════════════════
146
150 int masterCount() const override;
151
156 void setMasterCount(int count);
157
161 bool isMaster(const QString& windowId) const;
162
166 QStringList masterWindows() const;
167
171 QStringList stackWindows() const;
172
178 bool promoteToMaster(const QString& windowId);
179
185 bool moveToFront(const QString& windowId);
186
192 bool insertAfterFocused(const QString& windowId);
193
200 bool moveToPosition(const QString& windowId, int position);
201
207 int windowPosition(const QString& windowId) const;
208
214 int tiledWindowIndex(const QString& windowId) const;
215
222 bool moveToTiledPosition(const QString& windowId, int tiledPosition);
223
233 bool rotateWindows(bool clockwise = true);
234
235 // ═══════════════════════════════════════════════════════════════════════
236 // Split Ratio
237 // ═══════════════════════════════════════════════════════════════════════
238
243 qreal splitRatio() const;
244
249 void setSplitRatio(qreal ratio);
250
255 void increaseSplitRatio(qreal delta = 0.05);
256
261 void decreaseSplitRatio(qreal delta = 0.05);
262
263 // ═══════════════════════════════════════════════════════════════════════
264 // Per-Window Floating State
265 // ═══════════════════════════════════════════════════════════════════════
266
270 bool isFloating(const QString& windowId) const override;
271
277 void setFloating(const QString& windowId, bool floating);
278
284 bool toggleFloating(const QString& windowId);
285
289 QStringList floatingWindows() const override;
290
291 // ═══════════════════════════════════════════════════════════════════════
292 // IPlacementState
293 // ═══════════════════════════════════════════════════════════════════════
294
295 QStringList managedWindows() const override;
296 QString placementIdForWindow(const QString& windowId) const override;
297
298 // ═══════════════════════════════════════════════════════════════════════
299 // Focus Tracking
300 // ═══════════════════════════════════════════════════════════════════════
301
305 QString focusedWindow() const;
306
311 void setFocusedWindow(const QString& windowId);
312
317 int focusedTiledIndex() const;
318
319 // ═══════════════════════════════════════════════════════════════════════
320 // Serialization
321 // ═══════════════════════════════════════════════════════════════════════
322
326 QJsonObject toJson() const override;
327
336 static TilingState* fromJson(const QJsonObject& json, QObject* parent = nullptr);
337
341 void clear();
342
343 // ═══════════════════════════════════════════════════════════════════════
344 // Calculated Zone Storage
345 // ═══════════════════════════════════════════════════════════════════════
346
355 void setCalculatedZones(const QVector<QRect>& zones);
356
361 QVector<QRect> calculatedZones() const;
362
363 // ═══════════════════════════════════════════════════════════════════════
364 // Split Tree (persistent BSP tree for memory-based algorithms)
365 // ═══════════════════════════════════════════════════════════════════════
366
374
379 void setSplitTree(std::unique_ptr<SplitTree> tree);
380
385
395
396Q_SIGNALS:
401
406
411
416
425 void floatingChanged(const QString& windowId, bool floating);
426
431
436
437private:
438 QString m_screenId;
439 QStringList m_windowOrder;
440 QSet<QString> m_floatingWindows;
441 QString m_focusedWindow;
442 int m_masterCount = AutotileDefaults::DefaultMasterCount;
443 qreal m_splitRatio = AutotileDefaults::DefaultSplitRatio;
444 QVector<QRect> m_calculatedZones;
445 std::unique_ptr<SplitTree> m_splitTree;
446
447 // Helper to emit stateChanged after other signals
448 void notifyStateChanged();
449
455 void forEachTiledWindow(const std::function<bool(const QString& windowId, int tiledIndex)>& func) const;
456
457 // ── Clamping helpers (DRY: shared by setters and fromJson) ──
458 static int clampMasterCount(int value);
459 static qreal clampSplitRatio(qreal value);
460
461 // ── Tree synchronization helpers (SRP/DRY: single place for null-check + op) ──
462 void syncTreeInsert(const QString& windowId, int position = -1);
463 void syncTreeRemove(const QString& windowId);
464 void syncTreeSwap(const QString& idA, const QString& idB);
465 void syncTreeLazyCreate();
466};
467
468} // namespace PhosphorTiles
Algorithm-layer constants for the autotile/tile primitives.
Per-screen placement state contract.
Definition IPlacementState.h:26
A binary split tree for interactive window tiling.
Definition SplitTree.h:58
Tracks tiling state for a single screen.
Definition TilingState.h:40
TilingState & operator=(const TilingState &)=delete
bool moveToFront(const QString &windowId)
Move a window to the front (alias for promoteToMaster)
void clear()
Clear all state (remove all windows, reset to defaults)
void setMasterCount(int count)
Set number of windows in master area.
void setSplitRatio(qreal ratio)
Set the master/stack split ratio.
void windowOrderChanged()
Emitted when window order changes (move/swap)
QStringList stackWindows() const
Get windows currently in stack area.
bool isMaster(const QString &windowId) const
Check if a window is in the master area.
bool rotateWindows(bool clockwise=true)
Rotate all windows by one position.
bool insertAfterFocused(const QString &windowId)
Insert a window after the currently focused window.
void setSplitTree(std::unique_ptr< SplitTree > tree)
Set or replace the split tree.
int tiledWindowCount() const override
Get number of tiled windows (excluding floating)
bool isFloating(const QString &windowId) const override
Check if a window is floating (excluded from tiling)
QStringList windowOrder() const
Get the ordered list of window IDs.
QStringList floatingWindows() const override
Get list of floating windows.
void setFloating(const QString &windowId, bool floating)
Set a window's floating state.
TilingState(const TilingState &)=delete
QStringList masterWindows() const
Get windows currently in master area.
void setCalculatedZones(const QVector< QRect > &zones)
Store calculated zone geometries.
QString screenId() const override
Get the screen ID this state belongs to.
QVector< QRect > calculatedZones() const
Get stored calculated zone geometries.
int windowCount() const override
Get total number of tracked windows (including floating)
TilingState(const QString &screenId, QObject *parent=nullptr)
Construct a TilingState for a specific screen.
int windowPosition(const QString &windowId) const
Get the position of a window (alias for windowIndex)
QStringList tiledWindows() const
Get only tiled (non-floating) windows in order.
int masterCount() const override
Get number of windows in master area.
QJsonObject toJson() const override
Serialize state to JSON.
bool removeWindow(const QString &windowId)
Remove a window from the tiling.
bool promoteToMaster(const QString &windowId)
Promote a window to master (move to position 0)
void decreaseSplitRatio(qreal delta=0.05)
Decrease split ratio by delta.
int tiledWindowIndex(const QString &windowId) const
Get the index of a window within the tiled-only list.
void setFocusedWindow(const QString &windowId)
Set the focused window.
void stateChanged()
Emitted when any state change requires retiling.
bool toggleFloating(const QString &windowId)
Toggle a window's floating state.
void rebuildSplitTree()
Rebuild the split tree from the current tiled window order.
bool moveToTiledPosition(const QString &windowId, int tiledPosition)
Move a window to a specific position in the tiled-only list.
void increaseSplitRatio(qreal delta=0.05)
Increase split ratio by delta.
bool swapWindows(int index1, int index2)
Swap two windows' positions.
bool swapWindowsById(const QString &windowId1, const QString &windowId2)
Swap two windows by their IDs.
void clearSplitTree()
Clear the split tree (e.g., on algorithm switch)
int windowIndex(const QString &windowId) const
Get the index of a window.
bool moveWindow(int fromIndex, int toIndex)
Move a window to a different position.
bool addWindow(const QString &windowId, int position=-1)
Add a window to the tiling.
QString focusedWindow() const
Get the currently focused window.
void splitRatioChanged()
Emitted when split ratio changes.
void masterCountChanged()
Emitted when master count changes.
void windowCountChanged()
Emitted when window count changes (add/remove)
SplitTree * splitTree() const
Get the persistent split tree (may be null)
bool moveToPosition(const QString &windowId, int position)
Move a window to a specific position by its ID.
static TilingState * fromJson(const QJsonObject &json, QObject *parent=nullptr)
Deserialize state from JSON.
void focusedWindowChanged()
Emitted when focused window changes.
void floatingChanged(const QString &windowId, bool floating)
Emitted when a window's floating state changes.
QString placementIdForWindow(const QString &windowId) const override
Opaque placement identifier for the window's current slot.
qreal splitRatio() const
Get the master/stack split ratio.
QStringList managedWindows() const override
All windows managed by this state (tiled + floating).
int focusedTiledIndex() const
Get index of focused window in tiled list.
bool containsWindow(const QString &windowId) const override
Check if a window is tracked.
Definition AutotileEngine.h:71