A tiling algorithm backed by a user-provided Luau script. More...
#include <phosphor-tiles/include/PhosphorTiles/LuauTileAlgorithm.h>
Public Member Functions | |
| LuauTileAlgorithm (const QString &filePath, std::shared_ptr< PhosphorScripting::LuauWatchdog > watchdog=nullptr, QObject *parent=nullptr) | |
| Owned-engine ctor: creates an isolated, per-engine-capped VM for this script. | |
| LuauTileAlgorithm (const QString &filePath, std::shared_ptr< PhosphorScripting::LuauEngine > sharedEngine, std::shared_ptr< PhosphorScripting::LuauWatchdog > watchdog, QObject *parent=nullptr) | |
Shared-engine ctor: loads this script's module into sharedEngine (an already init+prelude+sandbox'd VM) instead of creating its own. | |
| ~LuauTileAlgorithm () override | |
| bool | isValid () const |
| Whether the script loaded and exposes a callable tile() function. | |
| QString | filePath () const |
| QString | id () const |
| Optional algorithm id declared in metadata (empty if unset). | |
| void | setUserScript (bool isUser) |
| QString | name () const override |
| Human-readable name of the algorithm. | |
| QString | description () const override |
| Description of the algorithm behavior. | |
| QVector< QRect > | calculateZones (const TilingParams ¶ms) const override |
| Calculate zone geometries for N windows. | |
| int | masterZoneIndex () const override |
| Get the index of the "master" zone (if applicable) | |
| bool | supportsMasterCount () const override |
| Check if algorithm supports variable master count. | |
| bool | supportsSplitRatio () const override |
| Check if algorithm supports split ratio adjustment. | |
| qreal | defaultSplitRatio () const override |
| Get default split ratio for this algorithm. | |
| int | minimumWindows () const override |
| Get minimum number of windows for meaningful tiling. | |
| int | defaultMaxWindows () const override |
| Get default maximum number of windows for this algorithm. | |
| bool | producesOverlappingZones () const override |
| Whether this algorithm intentionally produces overlapping zones. | |
| bool | supportsMinSizes () const noexcept override |
| Whether this algorithm supports per-window minimum size constraints. | |
| bool | supportsMemory () const noexcept override |
| Whether this algorithm maintains persistent state across retiles. | |
| QString | zoneNumberDisplay () const noexcept override |
| How zone numbers should be displayed in previews. | |
| bool | centerLayout () const override |
| Whether this algorithm uses a center layout. | |
| bool | isScripted () const noexcept override |
| Whether this algorithm is a user-provided scripted algorithm. | |
| bool | isUserScript () const noexcept override |
| Whether this scripted algorithm was loaded from a user directory. | |
| void | prepareTilingState (TilingState *state) const override |
| Prepare the TilingState before calculateZones() is called. | |
| bool | supportsLifecycleHooks () const noexcept override |
| Whether this algorithm implements any lifecycle hooks. | |
| void | onWindowAdded (TilingState *state, int windowIndex) override |
| Called when a window is added to the tiling before retile. | |
| void | onWindowRemoved (TilingState *state, int windowIndex) override |
| Called when a window is removed from the tiling before retile. | |
| bool | supportsResizeHook () const noexcept override |
| Whether this algorithm reacts to interactive window resizes. | |
| void | onWindowResized (TilingState *state, const ResizeEvent &resize) override |
| Called when a tiled window finished an interactive resize. | |
| bool | supportsScriptState () const noexcept override |
| Whether this algorithm persists an opaque per-screen script-state bag (TilingState::scriptState) across retiles and sessions. | |
| bool | supportsCustomParams () const noexcept override |
| Whether this algorithm declares custom parameters. | |
| QVariantList | customParamDefList () const override |
| Get custom parameter definitions as a QVariantList for QML. | |
| bool | hasCustomParam (const QString &name) const override |
| Check if a named custom parameter is declared by this algorithm. | |
Public Member Functions inherited from PhosphorTiles::TilingAlgorithm | |
| 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. | |
Static Public Member Functions | |
| static std::shared_ptr< PhosphorScripting::LuauEngine > | createSandboxedEngine (std::shared_ptr< PhosphorScripting::LuauWatchdog > watchdog, QString *error=nullptr) |
Build a sandboxed VM with the pluau standard library installed and frozen, ready for loadModule(). | |
Additional Inherited Members | |
Signals inherited from PhosphorTiles::TilingAlgorithm | |
| void | configurationChanged () |
| Emitted when algorithm parameters change. | |
Static Protected Member Functions inherited from PhosphorTiles::TilingAlgorithm | |
| 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 inherited from PhosphorTiles::TilingAlgorithm | |
| std::function< QString(const QString &)> | m_appIdResolver |
| QString | m_registryId |
A tiling algorithm backed by a user-provided Luau script.
The script's module is loaded into a PhosphorScripting::LuauEngine whose pluau standard library has been injected and frozen. There are two engine modes, chosen by which constructor is used:
pluau prelude is paid once instead of per script. The shared engine is held by shared_ptr so a deferred-deleted algorithm keeps it alive until its own teardown (which releases just this algorithm's module handle).The script is a Luau chunk that returns a module table, conventionally via pluau.algorithm{...}:
return pluau.algorithm {
metadata = { id = "columns", name = "Columns" },
tile = function(ctx) return ctx.area:columns(ctx.count, ctx.gap) end,
}
Params/state are marshalled to/from the script as nested QVariant structures; no Lua types cross into this class. Runaway scripts are bounded by a shared LuauWatchdog.
Not thread-safe — all calls must occur on the owning (main) thread.
|
explicit |
Owned-engine ctor: creates an isolated, per-engine-capped VM for this script.
Use for untrusted user scripts.
| PhosphorTiles::LuauTileAlgorithm::LuauTileAlgorithm | ( | const QString & | filePath, |
| std::shared_ptr< PhosphorScripting::LuauEngine > | sharedEngine, | ||
| std::shared_ptr< PhosphorScripting::LuauWatchdog > | watchdog, | ||
| QObject * | parent = nullptr |
||
| ) |
Shared-engine ctor: loads this script's module into sharedEngine (an already init+prelude+sandbox'd VM) instead of creating its own.
Use for trusted bundled scripts so the VM baseline + prelude are shared. The engine must be created via createSandboxedEngine().
|
override |
|
overridevirtual |
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) |
Implements PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
static |
Build a sandboxed VM with the pluau standard library installed and frozen, ready for loadModule().
Returns nullptr (and sets error) on failure. Shared by the owned-engine path and the shared-engine factory in ScriptedAlgorithmLoader so the prelude is loaded identically.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
Get default split ratio for this algorithm.
Used when creating initial tiling state.
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
Description of the algorithm behavior.
Implements PhosphorTiles::TilingAlgorithm.
| QString PhosphorTiles::LuauTileAlgorithm::filePath | ( | ) | const |
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
| QString PhosphorTiles::LuauTileAlgorithm::id | ( | ) | const |
Optional algorithm id declared in metadata (empty if unset).
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
| bool PhosphorTiles::LuauTileAlgorithm::isValid | ( | ) | const |
Whether the script loaded and exposes a callable tile() function.
|
overridevirtual |
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. Used for "focus master" and "swap with master".
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
Human-readable name of the algorithm.
Implements PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
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 from PhosphorTiles::TilingAlgorithm.
| void PhosphorTiles::LuauTileAlgorithm::setUserScript | ( | bool | isUser | ) |
|
overridevirtualnoexcept |
Whether this algorithm declares custom parameters.
Algorithms that support custom parameters (e.g., scripted algorithms with
| declarations) | return true. Used to avoid downcasting. |
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
Check if algorithm supports variable master count.
If true, the algorithm can handle multiple windows in the master area.
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
Whether this algorithm supports per-window minimum size constraints.
Most algorithms respect the minSizes parameter. Algorithms that ignore it (e.g., Floating Center, Tatami) return false so the settings UI can disable min-size controls for them.
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.
|
overridevirtual |
Check if algorithm supports split ratio adjustment.
If true, the master/stack ratio can be dynamically adjusted.
Reimplemented from PhosphorTiles::TilingAlgorithm.
|
overridevirtualnoexcept |
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 from PhosphorTiles::TilingAlgorithm.