Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorTiles::ScriptedAlgorithm Class Reference

#include <phosphor-tiles/include/PhosphorTiles/ScriptedAlgorithm.h>

Inheritance diagram for PhosphorTiles::ScriptedAlgorithm:
[legend]

Public Member Functions

 ScriptedAlgorithm (const QString &filePath, std::shared_ptr< ScriptedAlgorithmWatchdog > watchdog=nullptr, QObject *parent=nullptr)
 Construct a ScriptedAlgorithm from a JavaScript file.
 
 ~ScriptedAlgorithm () override
 
bool isValid () const
 Whether the script loaded successfully and has a calculateZones function.
 
QString filePath () const
 Absolute path to the source script file.
 
QString scriptId () const
 Identifier derived from the filename without extension.
 
QString id () const
 Optional algorithm ID from metadata.
 
void setUserScript (bool isUser)
 Mark whether this script was loaded from a user directory.
 
QString name () const override
 Human-readable name of the algorithm.
 
QString description () const override
 Description of the algorithm behavior.
 
QVector< QRect > calculateZones (const TilingParams &params) 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 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.
 
const QVector< ScriptedHelpers::CustomParamDef > & customParamDefs () const
 Get the custom parameter definitions declared by this script.
 
- Public Member Functions inherited from PhosphorTiles::TilingAlgorithm
 TilingAlgorithm (QObject *parent=nullptr)
 
 ~TilingAlgorithm () override=default
 
 TilingAlgorithm (const TilingAlgorithm &)=delete
 
TilingAlgorithmoperator= (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.
 

Additional Inherited Members

- Signals inherited from PhosphorTiles::TilingAlgorithm
void configurationChanged ()
 Emitted when algorithm parameters change.
 
- Protected Types inherited from PhosphorTiles::TilingAlgorithm
using ThreeColumnWidths = ::PhosphorTiles::ThreeColumnWidths
 Result of solving three-column width distribution.
 
using CumulativeMinDims = ::PhosphorTiles::CumulativeMinDims
 Result of precomputing cumulative min dimensions for alternating V/H splits.
 
- Static Protected Member Functions inherited from PhosphorTiles::TilingAlgorithm
static QVector< int > distributeEvenly (int total, int count)
 Distribute a total evenly among N parts with pixel-perfect remainder handling.
 
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.
 
static QVector< int > distributeWithGaps (int total, int count, int gap)
 Distribute total space among count items with gaps between them.
 
static QVector< int > distributeWithMinSizes (int total, int count, int gap, const QVector< int > &minDims)
 Distribute total space among count items with gaps, respecting per-item minimums.
 
static int minWidthAt (const QVector< QSize > &minSizes, int index)
 Extract minimum width from minSizes at the given index.
 
static int minHeightAt (const QVector< QSize > &minSizes, int index)
 Extract minimum height from minSizes at the given index.
 
static void solveTwoPartMinSizes (int contentDim, int &firstDim, int &secondDim, int minFirst, int minSecond)
 Solve two-column/two-row dimension distribution with min-size constraints.
 
static void applyPerWindowMinSize (int &width, int &height, const QVector< QSize > &minSizes, int index)
 Apply per-window minimum size constraints (used by overlapping algorithms)
 
static ThreeColumnWidths solveThreeColumnWidths (int areaX, int contentWidth, int innerGap, qreal splitRatio, int minLeftWidth, int minCenterWidth, int minRightWidth)
 Solve three-column width distribution with ratio and min-size constraints.
 
static CumulativeMinDims computeAlternatingCumulativeMinDims (int windowCount, const QVector< QSize > &minSizes, int innerGap)
 Precompute direction-aware cumulative min dimensions for alternating splits.
 
static void appendGracefulDegradation (QVector< QRect > &zones, const QRect &remaining, int leftover, int innerGap)
 Append graceful degradation zones when remaining area is too small.
 
static qreal clampOrProportionalFallback (qreal ratio, qreal minFirstRatio, qreal maxFirstRatio, int firstDim, int secondDim)
 Clamp split ratio to min/max range, or fall back to proportional split.
 
- Protected Attributes inherited from PhosphorTiles::TilingAlgorithm
std::function< QString(const QString &)> m_appIdResolver
 
QString m_registryId
 

Constructor & Destructor Documentation

◆ ScriptedAlgorithm()

PhosphorTiles::ScriptedAlgorithm::ScriptedAlgorithm ( const QString &  filePath,
std::shared_ptr< ScriptedAlgorithmWatchdog watchdog = nullptr,
QObject *  parent = nullptr 
)
explicit

Construct a ScriptedAlgorithm from a JavaScript file.

Parameters
filePathAbsolute path to the .js script file
watchdogShared ownership of the watchdog that monitors this algorithm's guarded JS calls. The algorithm holds a strong reference so the watchdog cannot disappear while the algorithm is still alive — required because the registry destroys algorithms via deleteLater(), which can defer the ~ScriptedAlgorithm dtor past the loader's own destructor (and past the loader's owning shared_ptr being released). The watchdog thread joins when the LAST strong reference is released — typically the loader's, occasionally a deferred-delete algorithm's. Replaces the prior ScriptedAlgorithmWatchdog::instance() process-wide singleton. nullptr disables the JS-timeout safety net entirely — used by headless unit tests that exercise metadata parsing and short, well-behaved scripts where a runaway-guard would only add a thread-creation cost. Production code paths (the loader) always pass a non-null watchdog.
parentParent QObject

◆ ~ScriptedAlgorithm()

PhosphorTiles::ScriptedAlgorithm::~ScriptedAlgorithm ( )
override

Member Function Documentation

◆ calculateZones()

QVector< QRect > PhosphorTiles::ScriptedAlgorithm::calculateZones ( const TilingParams params) const
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.

Parameters
paramsTiling parameters (see TilingParams)
Returns
Vector of zone geometries in absolute pixel coordinates
Note
The returned vector should have exactly params.windowCount elements. For windowCount == 0, return an empty vector. For windowCount == 1, typically return a single zone inset by outerGap.

Implements PhosphorTiles::TilingAlgorithm.

◆ centerLayout()

bool PhosphorTiles::ScriptedAlgorithm::centerLayout ( ) const
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".

Returns
true if this is a center layout algorithm (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ customParamDefList()

QVariantList PhosphorTiles::ScriptedAlgorithm::customParamDefList ( ) const
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).

Returns
List of param definition maps, or empty if none declared

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ customParamDefs()

const QVector< ScriptedHelpers::CustomParamDef > & PhosphorTiles::ScriptedAlgorithm::customParamDefs ( ) const

Get the custom parameter definitions declared by this script.

◆ defaultMaxWindows()

int PhosphorTiles::ScriptedAlgorithm::defaultMaxWindows ( ) const
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.

Returns
Default max window count for this algorithm (typically 4-10)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ defaultSplitRatio()

qreal PhosphorTiles::ScriptedAlgorithm::defaultSplitRatio ( ) const
overridevirtual

Get default split ratio for this algorithm.

Used when creating initial tiling state.

Returns
Default ratio (0.0-1.0), typically 0.5-0.6

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ description()

QString PhosphorTiles::ScriptedAlgorithm::description ( ) const
overridevirtual

Description of the algorithm behavior.

Returns
Description suitable for tooltips/help text

Implements PhosphorTiles::TilingAlgorithm.

◆ filePath()

QString PhosphorTiles::ScriptedAlgorithm::filePath ( ) const

Absolute path to the source script file.

◆ hasCustomParam()

bool PhosphorTiles::ScriptedAlgorithm::hasCustomParam ( const QString &  name) 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.

Parameters
nameParameter name to check
Returns
true if the algorithm declares a
Parameters
withthis name

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ id()

QString PhosphorTiles::ScriptedAlgorithm::id ( ) const

Optional algorithm ID from metadata.

When non-empty, the loader uses this ID instead of "script:filename" for algorithm registration.

◆ isScripted()

bool PhosphorTiles::ScriptedAlgorithm::isScripted ( ) const
overridevirtualnoexcept

Whether this algorithm is a user-provided scripted algorithm.

Scripted algorithms are loaded from JavaScript files at runtime. Used by the UI to group algorithms into "Built-in" vs "Custom" sections.

Returns
true if this is a ScriptedAlgorithm (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ isUserScript()

bool PhosphorTiles::ScriptedAlgorithm::isUserScript ( ) const
overridevirtualnoexcept

Whether this scripted algorithm was loaded from a user directory.

System-installed scripts (shipped with PlasmaZones) return false. User-created scripts in ~/.local/share/plasmazones/algorithms/ return true. Non-scripted algorithms always return false.

Returns
true if loaded from user's writable data directory (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ isValid()

bool PhosphorTiles::ScriptedAlgorithm::isValid ( ) const

Whether the script loaded successfully and has a calculateZones function.

◆ masterZoneIndex()

int PhosphorTiles::ScriptedAlgorithm::masterZoneIndex ( ) const
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".

Returns
Master zone index (0-based), or -1 if no master concept

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ minimumWindows()

int PhosphorTiles::ScriptedAlgorithm::minimumWindows ( ) const
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.

Returns
Minimum window count (typically 1)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ name()

QString PhosphorTiles::ScriptedAlgorithm::name ( ) const
overridevirtual

Human-readable name of the algorithm.

Returns
Algorithm name (e.g., "Master + Stack", "BSP")

Implements PhosphorTiles::TilingAlgorithm.

◆ onWindowAdded()

void PhosphorTiles::ScriptedAlgorithm::onWindowAdded ( TilingState state,
int  windowIndex 
)
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.

Parameters
stateCurrent tiling state (mutable for tree updates)
windowIndexIndex where the window was inserted

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ onWindowRemoved()

void PhosphorTiles::ScriptedAlgorithm::onWindowRemoved ( TilingState state,
int  windowIndex 
)
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.

Parameters
stateCurrent tiling state (window still present, count not yet decremented)
windowIndexIndex the window occupied before removal

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ prepareTilingState()

void PhosphorTiles::ScriptedAlgorithm::prepareTilingState ( TilingState state) const
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.

Parameters
stateTilingState to prepare (may be nullptr, implementations must check)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ producesOverlappingZones()

bool PhosphorTiles::ScriptedAlgorithm::producesOverlappingZones ( ) const
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.

Returns
true if zones intentionally overlap (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ scriptId()

QString PhosphorTiles::ScriptedAlgorithm::scriptId ( ) const

Identifier derived from the filename without extension.

For example, "my-layout.js" yields scriptId "my-layout".

◆ setUserScript()

void PhosphorTiles::ScriptedAlgorithm::setUserScript ( bool  isUser)

Mark whether this script was loaded from a user directory.

Parameters
isUsertrue if from ~/.local/share/plasmazones/algorithms/

◆ supportsCustomParams()

bool PhosphorTiles::ScriptedAlgorithm::supportsCustomParams ( ) const
overridevirtualnoexcept

Whether this algorithm declares custom parameters.

Algorithms that support custom parameters (e.g., scripted algorithms with

Parameters
declarations)return true. Used to avoid downcasting.
Returns
true if the algorithm has custom parameter definitions (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ supportsLifecycleHooks()

bool PhosphorTiles::ScriptedAlgorithm::supportsLifecycleHooks ( ) const
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.

Returns
true if the algorithm defines lifecycle hooks (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ supportsMasterCount()

bool PhosphorTiles::ScriptedAlgorithm::supportsMasterCount ( ) const
overridevirtual

Check if algorithm supports variable master count.

If true, the algorithm can handle multiple windows in the master area.

Returns
true if master count can be adjusted

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ supportsMemory()

bool PhosphorTiles::ScriptedAlgorithm::supportsMemory ( ) const
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.

Returns
true if the algorithm uses a persistent SplitTree (default: false)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ supportsMinSizes()

bool PhosphorTiles::ScriptedAlgorithm::supportsMinSizes ( ) const
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.

Returns
true if the algorithm honors minSizes (default: true)

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ supportsSplitRatio()

bool PhosphorTiles::ScriptedAlgorithm::supportsSplitRatio ( ) const
overridevirtual

Check if algorithm supports split ratio adjustment.

If true, the master/stack ratio can be dynamically adjusted.

Returns
true if split ratio can be adjusted

Reimplemented from PhosphorTiles::TilingAlgorithm.

◆ zoneNumberDisplay()

QString PhosphorTiles::ScriptedAlgorithm::zoneNumberDisplay ( ) const
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"

Returns
Display mode string

Reimplemented from PhosphorTiles::TilingAlgorithm.


The documentation for this class was generated from the following file: