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
99 bool addWindow(const QString& windowId, int position = -1);
100
106 bool removeWindow(const QString& windowId);
107
114 bool moveWindow(int fromIndex, int toIndex);
115
122 bool swapWindows(int index1, int index2);
123
130 bool swapWindowsById(const QString& windowId1, const QString& windowId2);
131
137 int windowIndex(const QString& windowId) const;
138
142 bool containsWindow(const QString& windowId) const override;
143
144 // ═══════════════════════════════════════════════════════════════════════
145 // Master Management
146 // ═══════════════════════════════════════════════════════════════════════
147
151 int masterCount() const override;
152
159 void setMasterCount(int count);
160
164 bool isMaster(const QString& windowId) const;
165
169 QStringList masterWindows() const;
170
174 QStringList stackWindows() const;
175
181 bool promoteToMaster(const QString& windowId);
182
188 bool moveToFront(const QString& windowId);
189
195 bool insertAfterFocused(const QString& windowId);
196
203 bool moveToPosition(const QString& windowId, int position);
204
212 int windowPosition(const QString& windowId) const;
213
219 int tiledWindowIndex(const QString& windowId) const;
220
227 bool moveToTiledPosition(const QString& windowId, int tiledPosition);
228
238 bool rotateWindows(bool clockwise = true);
239
240 // ═══════════════════════════════════════════════════════════════════════
241 // Split Ratio
242 // ═══════════════════════════════════════════════════════════════════════
243
248 qreal splitRatio() const;
249
254 void setSplitRatio(qreal ratio);
255
260 void increaseSplitRatio(qreal delta = 0.05);
261
266 void decreaseSplitRatio(qreal delta = 0.05);
267
268 // ═══════════════════════════════════════════════════════════════════════
269 // Per-Window Floating State
270 // ═══════════════════════════════════════════════════════════════════════
271
275 bool isFloating(const QString& windowId) const override;
276
282 void setFloating(const QString& windowId, bool floating);
283
289 bool toggleFloating(const QString& windowId);
290
294 QStringList floatingWindows() const override;
295
296 // ═══════════════════════════════════════════════════════════════════════
297 // IPlacementState
298 // ═══════════════════════════════════════════════════════════════════════
299
300 QStringList managedWindows() const override;
301 QString placementIdForWindow(const QString& windowId) const override;
302
303 // ═══════════════════════════════════════════════════════════════════════
304 // Focus Tracking
305 // ═══════════════════════════════════════════════════════════════════════
306
310 QString focusedWindow() const;
311
316 void setFocusedWindow(const QString& windowId);
317
323 int focusedTiledIndex() const;
324
345 QString lastTiledFocus() const;
346 QString lastFloatingFocus() const;
348
361 bool floatingHasFocus() const;
362
366 void clear();
367
368 // ═══════════════════════════════════════════════════════════════════════
369 // Calculated Zone Storage
370 // ═══════════════════════════════════════════════════════════════════════
371
380 void setCalculatedZones(const QVector<QRect>& zones);
381
386 QVector<QRect> calculatedZones() const;
387
388 // ═══════════════════════════════════════════════════════════════════════
389 // Split Tree (persistent BSP tree for memory-based algorithms)
390 // ═══════════════════════════════════════════════════════════════════════
391
399
404 void setSplitTree(std::unique_ptr<SplitTree> tree);
405
410
418 std::unique_ptr<SplitTree> takeSplitTree();
419
429
430 // ═══════════════════════════════════════════════════════════════════════
431 // Script state (opaque persistent bag for scripted algorithms)
432 // ═══════════════════════════════════════════════════════════════════════
433
442 QJsonObject scriptState() const;
443
452 void setScriptState(const QJsonObject& state);
453
464 static QJsonObject sanitizeScriptState(const QJsonObject& state);
465
466Q_SIGNALS:
471
476
481
486
495 void floatingChanged(const QString& windowId, bool floating);
496
501
506
507private:
508 QString m_screenId;
509 QStringList m_windowOrder;
510 QSet<QString> m_floatingWindows;
511 QString m_focusedWindow;
512 QString m_lastTiledFocus;
513 QString m_lastFloatingFocus;
514 int m_masterCount = AutotileDefaults::DefaultMasterCount;
515 qreal m_splitRatio = AutotileDefaults::DefaultSplitRatio;
516 QVector<QRect> m_calculatedZones;
517 std::unique_ptr<SplitTree> m_splitTree;
518 QJsonObject m_scriptState;
519
520 // Helper to emit stateChanged after other signals
521 void notifyStateChanged();
522
528 void forEachTiledWindow(const std::function<bool(const QString& windowId, int tiledIndex)>& func) const;
529
530 // ── Clamping helpers (DRY: shared by the setters and the script-state sanitizer) ──
531 static int clampMasterCount(int value);
532 static qreal clampSplitRatio(qreal value);
533
534 // ── Tree synchronization helpers (SRP/DRY: single place for null-check + op) ──
535 void syncTreeInsert(const QString& windowId, int position = -1);
536 void syncTreeRemove(const QString& windowId);
537 void syncTreeSwap(const QString& idA, const QString& idB);
538 void syncTreeLazyCreate();
539};
540
541} // namespace PhosphorTiles
Algorithm-layer constants for the autotile/tile primitives.
Per-screen placement state contract.
Definition IPlacementState.h:28
A binary split tree for interactive window tiling.
Definition SplitTree.h:57
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)
QJsonObject scriptState() const
Get the persistent per-algorithm script-state bag.
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)
void setScriptState(const QJsonObject &state)
Replace the script-state bag wholesale.
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.
bool removeWindow(const QString &windowId)
Remove a window from the tiling.
QString lastFloatingFocus() const
std::unique_ptr< SplitTree > takeSplitTree()
Hand the split tree to the caller, leaving this state without one.
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)
static QJsonObject sanitizeScriptState(const QJsonObject &state)
Validate and bound a script-written state bag at the trust boundary.
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.
QString lastTiledFocus() const
Layer-side focus memory for switch-focus-between-floating-and-tiling.
bool floatingHasFocus() const
Whether the float layer holds focus right now (derived)
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:59