Abstract base class for tiling algorithms. More...
#include <phosphor-tiles/include/PhosphorTiles/TilingAlgorithm.h>
Signals | |
| void | configurationChanged () |
| Emitted when algorithm parameters change. | |
Public Member Functions | |
| TilingAlgorithm (QObject *parent=nullptr) | |
| ~TilingAlgorithm () override=default | |
| TilingAlgorithm (const TilingAlgorithm &)=delete | |
| TilingAlgorithm & | operator= (const TilingAlgorithm &)=delete |
| void | setAppIdResolver (std::function< QString(const QString &)> resolver) |
| Inject a resolver that maps an opaque instance id to its live app class. | |
| std::function< QString(const QString &)> | appIdResolver () const |
| Access the current resolver. | |
| QString | registryId () const |
| The id this algorithm is registered under. | |
| void | setRegistryId (const QString &id) |
| Registry-internal setter. | |
| virtual QString | name () const =0 |
| Human-readable name of the algorithm. | |
| virtual QString | description () const =0 |
| Description of the algorithm behavior. | |
| virtual QVector< QRect > | calculateZones (const TilingParams ¶ms) const =0 |
| Calculate zone geometries for N windows. | |
| virtual int | masterZoneIndex () const |
| Get the index of the "master" zone (if applicable) | |
| virtual bool | supportsMasterCount () const |
| Check if algorithm supports variable master count. | |
| virtual bool | supportsSplitRatio () const |
| Check if algorithm supports split ratio adjustment. | |
| virtual qreal | defaultSplitRatio () const |
| Get default split ratio for this algorithm. | |
| virtual int | minimumWindows () const |
| Get minimum number of windows for meaningful tiling. | |
| virtual int | defaultMaxWindows () const |
| Get default maximum number of windows for this algorithm. | |
| virtual bool | producesOverlappingZones () const |
| Whether this algorithm intentionally produces overlapping zones. | |
| virtual QString | zoneNumberDisplay () const noexcept |
| How zone numbers should be displayed in previews. | |
| virtual bool | centerLayout () const |
| Whether this algorithm uses a center layout. | |
| virtual bool | supportsSingleWindow () const noexcept |
| Whether this algorithm lays out the single-window case itself. | |
| virtual bool | retilesOnFocusChange () const noexcept |
| Whether the layout must be recomputed when focus moves. | |
| virtual bool | isScripted () const noexcept |
| Whether this algorithm is a user-provided scripted algorithm. | |
| virtual bool | supportsMinSizes () const noexcept |
| Whether this algorithm supports per-window minimum size constraints. | |
| virtual QString | overlapStacking () const noexcept |
| Stacking direction for overlap layouts. | |
| virtual bool | supportsMemory () const noexcept |
| Whether this algorithm maintains persistent state across retiles. | |
| virtual void | prepareTilingState (TilingState *state) const |
| Prepare the TilingState before calculateZones() is called. | |
| virtual bool | isUserScript () const noexcept |
| Whether this scripted algorithm was loaded from a user directory. | |
| virtual bool | supportsLifecycleHooks () const noexcept |
| Whether this algorithm implements any lifecycle hooks. | |
| virtual void | onWindowAdded (TilingState *state, int windowIndex) |
| Called when a window is added to the tiling before retile. | |
| virtual void | onWindowRemoved (TilingState *state, int windowIndex) |
| Called when a window is removed from the tiling before retile. | |
| virtual bool | supportsResizeHook () const noexcept |
| Whether this algorithm reacts to interactive window resizes. | |
| virtual void | onWindowResized (TilingState *state, const ResizeEvent &resize) |
| Called when a tiled window finished an interactive resize. | |
| virtual bool | supportsScriptState () const noexcept |
| Whether this algorithm persists an opaque per-screen script-state bag (TilingState::scriptState) across retiles and sessions. | |
| virtual bool | supportsCustomParams () const noexcept |
| Whether this algorithm declares custom parameters. | |
| virtual QVariantList | customParamDefList () const |
| Get custom parameter definitions as a QVariantList for QML. | |
| virtual bool | hasCustomParam (const QString &name) const |
| Check if a named custom parameter is declared by this algorithm. | |
Static Protected Member Functions | |
| static QRect | innerRect (const QRect &screenGeometry, int outerGap) |
| Compute the usable area after subtracting uniform outer gap from screen edges. | |
| static QRect | innerRect (const QRect &screenGeometry, const EdgeGaps &gaps) |
| Compute the usable area after subtracting per-side outer gaps from screen edges. | |
Protected Attributes | |
| std::function< QString(const QString &)> | m_appIdResolver |
| QString | m_registryId |
Abstract base class for tiling algorithms.
Each algorithm generates zone geometries based on:
Zone geometries are returned as absolute pixel coordinates matching the provided screen geometry. This matches KWin's setFrameGeometry() API.
Subclasses must implement:
Optionally override capability methods to indicate support for:
|
explicit |
|
overridedefault |
|
delete |
|
inline |
Access the current resolver.
Returns a no-op (empty-string) resolver if none has been injected.
|
pure virtual |
Calculate zone geometries for N windows.
This is the core algorithm method. Given tiling parameters (window count, screen geometry, state, gaps, min sizes), generate zone rectangles.
| params | Tiling parameters (see TilingParams) |
Implemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Whether this algorithm uses a center layout.
Center layout algorithms (e.g., ThreeColumn, CenteredMaster) have a center column whose width is controlled by the split ratio. The UI labels the ratio/count controls as "Center" instead of "Master".
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
signal |
Emitted when algorithm parameters change.
Connect to this signal to trigger retiling when algorithm configuration is modified at runtime.
|
virtual |
Get custom parameter definitions as a QVariantList for QML.
Each entry is a QVariantMap with keys: name, type, defaultValue, description, minValue, maxValue, enumOptions (as applicable).
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Get default maximum number of windows for this algorithm.
Used as the initial value of the "Max Windows" slider in the KCM, and reported as the zone count on layout previews (LayoutGridDelegate, zone selector). The slider resets to this value when switching algorithms.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Get default split ratio for this algorithm.
Used when creating initial tiling state.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
pure virtual |
Description of the algorithm behavior.
Implemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Check if a named custom parameter is declared by this algorithm.
Lighter-weight alternative to customParamDefList() for filtering stale params on the retile hot path — avoids QVariantList/QVariantMap allocation.
| name | Parameter name to check |
| with | this name |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
staticprotected |
Compute the usable area after subtracting per-side outer gaps from screen edges.
| screenGeometry | Full screen rectangle |
| gaps | Per-side gap values |
|
staticprotected |
Compute the usable area after subtracting uniform outer gap from screen edges.
| screenGeometry | Full screen rectangle |
| outerGap | Gap at each edge in pixels |
|
virtualnoexcept |
Whether this algorithm is a user-provided scripted algorithm.
Scripted algorithms are loaded from Luau (.luau) files at runtime. Used by the UI to group algorithms into "Built-in" vs "Custom" sections.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this scripted algorithm was loaded from a user directory.
System-installed scripts (shipped with Phosphor) return false. User-created scripts in ~/.local/share/plasmazones/algorithms/ return true. Non-scripted algorithms always return false.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Get the index of the "master" zone (if applicable)
For algorithms with a master/stack concept, this returns the index of the primary window zone.
This describes the algorithm for a caller that asks, and nothing in this tree reads it outside of tests. In particular the engine's focusMaster() focuses the first tiled window directly rather than consulting this, so overriding it does not change any built-in behaviour. It stays on the exported API because a third-party algorithm can declare it and a third-party consumer can read it, which is what this library is LGPL for.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Get minimum number of windows for meaningful tiling.
Some algorithms (like Three Column) need a minimum number of windows to produce a sensible layout.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
pure virtual |
Human-readable name of the algorithm.
Implemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Called when a window is added to the tiling before retile.
Algorithms can use this to update internal state (e.g., BSP tree insertion) instead of rebuilding from scratch in calculateZones().
Unlike calculateZones() (which receives a const TilingState*), lifecycle hooks receive a mutable pointer so algorithms can update internal structures (e.g., split trees) incrementally.
| state | Current tiling state (mutable for tree updates) |
| windowIndex | Index where the window was inserted |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Called when a window is removed from the tiling before retile.
The window is still present in state when this hook fires; it will be removed immediately after the hook returns. This means state->tiledWindowCount() still includes the departing window. Algorithms should use windowIndex to identify the departing window but must not assume the tiled window list will remain unchanged after the call. Hooks must NOT reorder or mutate the tiled window list — the engine relies on list stability for the subsequent removal.
Unlike calculateZones() (which receives a const TilingState*), lifecycle hooks receive a mutable pointer so algorithms can update internal structures (e.g., split trees) incrementally.
| state | Current tiling state (window still present, count not yet decremented) |
| windowIndex | Index the window occupied before removal |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Called when a tiled window finished an interactive resize.
Only invoked for non-memory algorithms that return true from supportsResizeHook. The algorithm may mutate state (e.g. write TilingState::scriptState) so the immediately-following retile lays the windows out to honour the resize. Default no-op.
| state | Mutable tiling state (window list unchanged by the resize) |
| resize | Which window/edges moved, with old/new frames |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
delete |
|
virtualnoexcept |
Stacking direction for overlap layouts.
Only meaningful when producesOverlappingZones() is true. Declares the z-order the compositor should impose on the tiled windows so overlap layouts keep a deterministic stack across retiles:
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Prepare the TilingState before calculateZones() is called.
Memory-based algorithms override this to lazily create their SplitTree. The engine calls this unconditionally before calculateZones(), removing the need for concrete algorithm casts in the engine.
The method is const on the algorithm (it doesn't mutate algorithm state) but mutates the TilingState argument — the engine owns that mutation.
| state | TilingState to prepare (may be nullptr, implementations must check) |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Whether this algorithm intentionally produces overlapping zones.
Algorithms like Cascade, Stair, and Monocle overlap zones by design. When true, the post-layout enforceMinSizes pass is skipped to avoid removeRectOverlaps destroying the intended layout.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
inline |
The id this algorithm is registered under.
Populated by AlgorithmRegistry::registerAlgorithm at registration time and unset when the algorithm is removed. Empty for algorithms that exist but aren't currently registered (fixture stubs, transient instances). Lets callers that have only a TilingAlgorithm* recover the id without the O(N) reverse lookup through the registry.
|
virtualnoexcept |
Whether the layout must be recomputed when focus moves.
Most layouts place a window by its tiled index, so a focus change alone does not move anything and the engine skips retiling. Focus-driven layouts (e.g. Theater, where the focused window occupies the centered spotlight) opt in so the engine reflows when focus moves between tiled windows.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
inline |
Inject a resolver that maps an opaque instance id to its live app class.
Used by algorithms that need per-window class info (currently only LuauTileAlgorithm, which exposes it to user-authored Luau scripts). Built-in geometry algorithms don't care and ignore the resolver.
Injected by AutotileEngine::setWindowRegistry() so every algorithm returned from AlgorithmRegistry::algorithm() is seeded with the live registry's lookup before any lifecycle hook fires. The resolver is a std::function rather than a raw WindowRegistry* so tests can plug in canned answers without constructing a real registry.
Thread safety: setter must be called from the main thread; the resolver itself is invoked only from algorithm methods that already run on the main thread (buildStateMap / onWindowAdded / etc.).
|
inline |
Registry-internal setter.
Not intended for direct use; AlgorithmRegistry calls this from registerAlgorithm / unregisterAlgorithm.
|
virtualnoexcept |
Whether this algorithm declares custom parameters.
Algorithms that support custom parameters (e.g., scripted algorithms with
| declarations) | return true. Used to avoid downcasting. |
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm implements any lifecycle hooks.
When true, the engine calls onWindowAdded/onWindowRemoved before the next calculateZones() call, giving the algorithm a chance to update internal state incrementally.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Check if algorithm supports variable master count.
If true, the algorithm can handle multiple windows in the master area.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm maintains persistent state across retiles.
Memory algorithms (like DwindleMemory) remember per-split ratios and tree structure. The UI shows an indicator for memory-enabled algorithms.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm supports per-window minimum size constraints.
Most algorithms respect the minSizes parameter. Algorithms that ignore it (e.g., Tatami, Cluster) return false to say so.
Returning false opts the algorithm out of the engine's min-size pass: AutotileEngine skips enforceMinSizes (and the removeRectOverlaps implied by it) for the algorithm's zones, alongside the separate producesOverlappingZones() opt-out. An algorithm that declares this is saying min sizes are not a concept it works in, so having the engine post-process its output into honouring them would contradict the declaration.
There is no settings control keyed on it: it describes the algorithm rather than exposing a user choice.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm reacts to interactive window resizes.
When true, the engine calls onWindowResized for a non-tree algorithm after the user finishes resizing a tiled window, letting the algorithm record the adjustment (typically into TilingState::scriptState) before the follow-up retile. Tree/memory algorithms do not use this — the engine reflows their SplitTree directly. Default false.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm persists an opaque per-screen script-state bag (TilingState::scriptState) across retiles and sessions.
Scripted algorithms opt in via their metadata so the engine sanitizes and round-trips the bag (e.g. an aligned grid remembering column widths). Built-in algorithms do not use it. Used by the picker to surface a "remembers script state" filter/indicator. Default false.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
Whether this algorithm lays out the single-window case itself.
By default an algorithm does not own the single-window case: a scripted algorithm's calculateZones() fills the work area for a lone window without invoking its tile(). An algorithm that opts in (e.g. a layout that centers a lone window) receives the single-window case in its tile() and owns the resulting geometry.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtual |
Check if algorithm supports split ratio adjustment.
If true, the master/stack ratio can be dynamically adjusted.
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
virtualnoexcept |
How zone numbers should be displayed in previews.
Controls which zones show their number label in layout cards and previews. Values: "all" (default), "last", "first", "firstAndLast", "none"
Reimplemented in PhosphorTiles::LuauTileAlgorithm.
|
protected |
|
protected |