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

Engine for manual zone-based window snapping. More...

#include <phosphor-snap-engine/include/PhosphorSnapEngine/SnapEngine.h>

Inheritance diagram for PhosphorSnapEngine::SnapEngine:
[legend]

Public Types

using ShouldRestorePredicate = std::function< bool(const QString &screenId)>
 Predicate consulted on the auto-snap entry path to suppress zone restores onto a context the user disabled.
 
using RestorePositionPredicate = std::function< bool(const QString &windowId)>
 Predicate consulted in resolveWindowRestore to decide whether a FLOATED window should have its previous global position restored on open.
 
using ManagedRestorePredicate = std::function< bool(const QString &windowId)>
 Predicate consulted in resolveWindowRestore to decide whether a window that was SNAPPED at logout should be restored to its recorded zone on reopen/login (the "managed restore").
 
using LiveModeResolver = std::function< PhosphorZones::AssignmentEntry::Mode(const QString &screenId)>
 Live placement-mode resolver injected by the daemon (its ScreenModeRouter): engine-live-set-first with cascade fallback and the tiling-mode→Snapping downgrade for unclaimed screens.
 
using TilingEngineLiveResolver = std::function< bool(PhosphorZones::AssignmentEntry::Mode mode, const QString &screenId)>
 Whether the tiling engine owning mode is actually LIVE on screenId — the liveness half of resolveWindowRestore's cross-screen tile-defer gate.
 
using FloatPredicate = std::function< bool(const QString &windowId, const QString &screenId)>
 Predicate deciding whether an opening window should start FLOATING because a "Float this app" rule matched it.
 
using UnfloatFallbackPredicate = std::function< bool(const QString &windowId, const QString &screenId)>
 Predicate deciding whether an unfloat with NO remembered pre-float zone falls back to a zone anyway (the SetUnfloatFallbackToZone rule layered over the global unfloatFallbackToZone setting — the predicate itself implements rule ?? config).
 
using PlacementZonesResolver = std::function< PlacementDirective(const QString &windowId, const QString &screenId)>
 Resolver yielding the open-placement directive — SnapToZone ordinals and/or zone names, plus an optional RouteToScreen target and an optional RouteToDesktop target — for an opening window because a placement rule matched it.
 
using ExclusionQueryProvider = std::function< std::optional< PhosphorRules::WindowQuery >(const QString &windowId, const QString &screenHint)>
 Provider that builds the full WindowQuery (window class / title / role / frame size / flags) for a live windowId.
 
- Public Types inherited from PhosphorEngine::IPlacementEngine
enum class  LayoutSupport { None , Placement , Templates }
 How this engine relates to user-selectable layouts — the entries the layout picker, drag layout popup, quick-layout slots and layout cycle operate on. More...
 

Signals

void windowSnapStateChanged (const QString &windowId, const PhosphorProtocol::WindowStateEntry &entry)
 Snap state changed (commit / uncommit). WTA relays to D-Bus windowStateChanged.
 
void windowFloatingClearedForSnap (const QString &windowId, const QString &screenId)
 Floating state cleared as part of a commit. WTA relays as windowFloatingChanged(id, false, screen).
 
void applyGeometryRequested (const QString &windowId, int x, int y, int width, int height, const QString &zoneId, const QString &screenId, bool sizeOnly)
 Daemon-driven geometry application (used by autotile float restore)
 
void resnapToNewLayoutRequested (const QString &resnapData)
 Batched resnap data (routed through WTA::handleBatchedResnap for bookkeeping)
 
void snapAllWindowsRequested (const QString &screenId)
 Request KWin effect to collect unsnapped windows and snap them all.
 
void applyGeometriesBatch (const PhosphorProtocol::WindowGeometryList &geometries, const QString &action)
 Batch of window-geometry updates, applied by the KWin effect in a single operation.
 
- Signals inherited from PhosphorEngine::PlacementEngineBase
void geometryRestoreRequested (const QString &windowId, const QRect &geometry, const QString &screenId)
 
void navigationFeedback (bool success, const QString &action, const QString &reason, const QString &sourceId, const QString &targetId, const QString &screenId)
 
void windowFloatingChanged (const QString &windowId, bool floating, const QString &screenId)
 
void activateWindowRequested (const QString &windowId)
 
void windowDesktopMoveRequested (const QString &windowId, int desktop)
 Emitted when directional navigation moves a window across virtual desktops: the engine has already re-keyed its own tiling state, and the compositor must move the real window to desktop (1-based).
 
void windowOutputMoveExpected (const QString &windowId, const QString &targetScreenId)
 Emitted when daemon-initiated directional navigation moves a window across physical outputs: the engine has already migrated its own tiling state (removed from the source key, re-added on targetScreenId) and scheduled both reflows.
 
void crossModeMoveRequested (const QString &windowId, const QString &targetScreenId, int targetDesktop, const QString &direction)
 Emitted when a directional MOVE reaches a context boundary whose target is a DIFFERENT tiling mode than the source — the source engine cannot place the window itself (it has no state for the other mode), so it defers to the daemon.
 
void crossModeSwapRequested (const QString &windowId, const QString &targetScreenId, int targetDesktop, const QString &direction)
 Emitted when a directional SWAP reaches a context boundary whose target is a DIFFERENT tiling mode than the source — the two-way cross-mode exchange.
 
void crossModeFocusRequested (const QString &targetScreenId, const QString &direction, bool *handled)
 Emitted when a directional FOCUS reaches a monitor boundary whose neighbour context runs a DIFFERENT tiling mode — the source engine cannot name that surface's entry-edge window (it holds no state for the other mode), so it defers to the daemon, which asks the target engine for the window facing the source in direction and activates it.
 
void windowFloatingStateSynced (const QString &windowId, bool floating, const QString &screenId)
 Emitted to sync floating state without restoring geometry.
 
void windowsBatchFloated (const QStringList &windowIds, const QString &screenId)
 Emitted when overflow windows are batch-floated during applyTiling.
 
void algorithmChanged (const QString &algorithmId)
 Emitted when the active tiling algorithm changes.
 
void placementChanged (const QString &screenId)
 Emitted when the placement layout changes for a screen.
 
void windowsReleased (const QStringList &windowIds, const QSet< QString > &releasedScreenIds)
 Emitted when windows are released from engine management.
 
void settingsPersistRequested ()
 Emitted when the engine writes tuning values back to the settings object and wants the daemon to persist them to disk.
 

Public Member Functions

 SnapEngine (PhosphorZones::LayoutRegistry *layoutManager, PhosphorEngine::IWindowTrackingService *windowTracker, PhosphorZones::IZoneDetector *zoneDetector, PhosphorEngine::IVirtualDesktopManager *vdm, QObject *parent=nullptr)
 
 ~SnapEngine () override
 
int currentVirtualDesktop () const
 Current virtual desktop (1-based; 0 when no virtual-desktop manager is wired) and activity, forwarded from the injected managers.
 
int currentVirtualDesktopForScreen (const QString &screenId) const
 This screen's current virtual desktop (Plasma 6.7 per-output virtual desktops, #648).
 
QString currentActivity () const
 
std::pair< QString, QRect > resolveCrossDesktopZone (const QString &currentZoneId, const QString &screenId, int targetDesktop) const
 Resolve the zone on screenId's targetDesktop layout that is positionally equivalent to currentZoneId (1-based index of zones sorted by number), plus its pixel geometry.
 
QString entryZoneForCrossing (const QString &direction, const QString &neighbourScreen) const
 The zone a window ENTERS when it crosses onto neighbourScreen moving in direction: the first zone on the edge facing back toward the source (crossing "right" enters the neighbour's left-edge zone).
 
QString windowInZoneOnScreen (const QString &zoneId, const QString &screenId) const
 The window snapped to zoneId on screenId (the daemon's stored assignment pins it to that output), or empty if the zone is unoccupied there.
 
bool isActiveOnScreen (const QString &screenId) const override
 Whether this engine is active on the given screen.
 
bool isEnabled () const noexcept override
 True when snapping is globally enabled.
 
void windowOpened (const QString &windowId, const QString &screenId, int minWidth, int minHeight) override
 A new window appeared on this engine's screen.
 
void setShouldRestorePredicate (ShouldRestorePredicate predicate)
 Inject the auto-snap-restore gate.
 
void setRestorePositionPredicate (RestorePositionPredicate predicate)
 Inject the unsnapped-position-restore gate.
 
void setManagedRestorePredicate (ManagedRestorePredicate predicate)
 Inject the managed (snapped-to-zone) restore gate.
 
void setLiveModeResolver (LiveModeResolver resolver)
 
void setTilingEngineLiveResolver (TilingEngineLiveResolver resolver)
 
void setFloatPredicate (FloatPredicate predicate)
 
void setUnfloatFallbackPredicate (UnfloatFallbackPredicate predicate)
 
void setPlacementZonesResolver (PlacementZonesResolver resolver)
 
void windowClosed (const QString &windowId) override
 A window was closed.
 
void windowFocused (const QString &windowId, const QString &screenId) override
 A window gained focus (called when the compositor reports activation).
 
void toggleWindowFloat (const QString &windowId, const QString &screenId) override
 Toggle between managed and floating.
 
void setWindowFloat (const QString &windowId, bool shouldFloat, const QString &screenId=QString()) override
 Set floating state explicitly (directional, not toggle).
 
void saveState () override
 
void loadState () override
 
LayoutSupport layoutSupport () const override
 Snap placement is driven by user-selectable zone layouts.
 
QString engineId () const override
 Stable engine identity for HandoffContext.fromEngineId.
 
void handoffReceive (const HandoffContext &ctx) override
 Receive ownership of a window from another engine.
 
void handoffRelease (const QString &windowId) override
 Release ownership of a window WITHOUT modifying its geometry.
 
QString screenForTrackedWindow (const QString &windowId) const override
 Return the screen this engine considers the window to be on, or empty if the window isn't tracked by this engine.
 
bool isWindowTracked (const QString &windowId) const override
 Whether this engine considers the window owned (snapped, snap-floated, or otherwise carried in SnapState's screen/zone maps).
 
void resnapToNewLayout ()
 Resnap windows from previous layout to current layout after layout switch.
 
void resnapCurrentAssignments (const QString &screenFilter=QString())
 Resnap windows to their current zone assignments (re-apply geometries)
 
void resnapFromAutotileOrder (const QStringList &autotileWindowOrder, const QString &screenId)
 Resnap windows using autotile window order as assignment source.
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateResnapEntriesFromAutotileOrder (const QStringList &autotileWindowOrder, const QString &screenId, const QStringList &preClaimedZoneIds={})
 Calculate resnap entries from autotile order WITHOUT emitting signal.
 
PhosphorProtocol::SnapAllResultList calculateSnapAllWindows (const QStringList &windowIds, const QString &screenId)
 Calculate snap-all-windows assignments without applying them.
 
void emitBatchedResnap (const QVector< PhosphorEngine::ZoneAssignmentEntry > &entries)
 Emit a single batched resnapToNewLayoutRequested signal.
 
void snapAllWindows (const QString &screenId)
 Request the KWin effect to collect and snap all unsnapped windows.
 
PhosphorEngine::SnapResult resolveWindowRestore (const QString &windowId, const QString &screenId, bool sticky, PhosphorEngine::WindowKind kind=PhosphorEngine::WindowKind::Unknown)
 Resolve auto-snap for a newly opened window.
 
void setAutotileEngine (PhosphorEngine::IPlacementEngine *engine)
 Set the autotile engine for screen ownership checks.
 
void setWindowRegistry (QObject *registry) override
 Attach the daemon's shared window registry.
 
SnapStatestateForWindow (const QString &windowId)
 The SnapState that owns windowId (via the reverse map), or the global holder when the window is untracked — NEVER null (the holder is constructed in the ctor; see the fallback rationale on the definition).
 
const SnapStatestateForWindow (const QString &windowId) const
 
SnapStateglobalState () const
 The global-scalar holder (last-used-zone + user-snapped classes).
 
SnapStatesnapState () const
 The global-scalar holder (alias of globalState).
 
QList< SnapState * > allSnapStates () const
 Every SnapState the engine owns, including the global holder, for whole-store enumerations (occupied zones, snapped/floating windows, flat-map views).
 
SnapStatestateForWindowOnScreen (const QString &windowId, const QString &screenId)
 Resolve-or-register the owning state for windowId placed/acting on screenId, and return it.
 
void forgetWindow (const QString &windowId)
 Drop the reverse-map entry for windowId (window closed / fully removed).
 
bool migrateWindowToScreen (const QString &windowId, const QString &newScreenId)
 Re-home a tracked window's snap state onto newScreenId's per-key store when it crosses monitors.
 
void setCurrentDesktop (int desktop) override
 
void setCurrentDesktopForScreen (const QString &screenId, int desktop) override
 Set a single screen's current virtual desktop (Plasma 6.7 "switch desktops independently for each screen").
 
void setCurrentActivity (const QString &activity) override
 
QSet< int > desktopsWithActiveState () const override
 
void pruneStatesForDesktop (int removedDesktop) override
 
void pruneStatesForActivities (const QStringList &validActivities) override
 
void pruneStatesForRemovedScreen (const QString &physicalScreenId) override
 Prune per-(screen, desktop, activity) state for a PHYSICALLY REMOVED output (monitor hot-unplug), matching every virtual sub-screen of the removed physical id.
 
bool isFloating (const QString &windowId) const
 
void setFloating (const QString &windowId, bool floating)
 
QStringList floatingWindows () const
 
void applyNoMatchFloatDefault (const QString &windowId, const QString &screenId)
 The no-match float-default terminal of resolveWindowRestore, callable by the SnapAdaptor when a SnapResult::deferredToTilingEngine verdict was returned and the offered reclaim then DECLINED — without this fallback a defer-then-decline left the window with no state in any engine.
 
QString zoneForWindow (const QString &windowId) const
 Primary zone of windowId across the per-screen stores (empty if none).
 
void setZoneAdjacencyResolver (IZoneAdjacencyResolver *resolver)
 Set typed zone-adjacency resolver for directional navigation.
 
void setCrossSurfaceResolver (PhosphorEngine::ICrossSurfaceResolver *resolver) override
 Inject the cross-surface resolver (neighbour output / desktop lookup), threaded into the navigation target resolver so a no-adjacent-zone boundary crosses into the neighbouring output instead of failing.
 
void setNavigationStateProvider (INavigationStateProvider *provider)
 Wire the typed navigation-state provider.
 
void focusInDirection (const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
 Walk to the adjacent window in direction and transfer keyboard focus.
 
void moveFocusedInDirection (const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
 Move the focused window into the adjacent zone in direction (displacing or filling the target).
 
void spanFocusedInDirection (const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
 Grow the focused window's zone span into the adjacent zone(s) in direction, or retract the opposite edge when nothing lies that way (pressing back toward the span undoes the last grow).
 
void swapFocusedInDirection (const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
 Swap the focused window with whatever's in the adjacent zone in direction.
 
void moveFocusedToPosition (int zoneNumber, const PhosphorEngine::NavigationContext &ctx) override
 Move the focused window to the layout zone with zoneNumber (1-based) on ctx.screenId.
 
void rotateWindows (bool clockwise, const PhosphorEngine::NavigationContext &ctx) override
 Rotate snapped windows through the layout's zone order, dispatched via IPlacementEngine.
 
void reapplyLayout (const PhosphorEngine::NavigationContext &ctx) override
 Re-apply the current layout to all managed windows.
 
void reapplyManagedWindowAppearance () override
 Re-emit the snap geometry for every currently-snapped (non-floating) window so the compositor re-applies its snap border / hidden title bar after a bridge reconnect.
 
std::optional< PhosphorEngine::WindowPlacementcapturePlacement (const QString &windowId) const override
 Unified placement model — report this window's current snap state (snapped or floated) for persistence, or nullopt if untracked.
 
std::optional< PhosphorEngine::WindowPlacementcapturePlacementAtDesktop (const QString &windowId, int gateDesktop) const
 capturePlacement with the mode gate resolved at an EXPLICIT desktop.
 
void snapAllWindows (const PhosphorEngine::NavigationContext &ctx) override
 Snap every unmanaged window on the screen.
 
void pushToEmptyZone (const PhosphorEngine::NavigationContext &ctx) override
 Move the focused window to the first empty zone on ctx.screenId.
 
void restoreFocusedWindow (const PhosphorEngine::NavigationContext &ctx) override
 Restore the focused window to its captured pre-snap size and unsnap.
 
void toggleFocusedFloat (const PhosphorEngine::NavigationContext &ctx) override
 Toggle the focused window between snapped and floating.
 
void switchFocusBetweenFloatingAndTiling (const QString &screenId) override
 Jump focus between the float layer and the snapped layout (niri's switch-focus-between-floating-and-tiling).
 
void cycleFocus (bool forward, const PhosphorEngine::NavigationContext &ctx) override
 Cycle keyboard focus forward/backward through managed windows in the active zone (or the layout cycle order if single-window per zone).
 
void commitSnap (const QString &windowId, const QString &zoneId, const QString &screenId, PhosphorEngine::SnapIntent intent=PhosphorEngine::SnapIntent::UserInitiated, int virtualDesktop=0)
 virtualDesktop pins the assignment to a specific 1-based desktop; 0 (default) records it on the window's current desktop.
 
void commitMultiZoneSnap (const QString &windowId, const QStringList &zoneIds, const QString &screenId, PhosphorEngine::SnapIntent intent=PhosphorEngine::SnapIntent::UserInitiated, int virtualDesktop=0)
 
void uncommitSnap (const QString &windowId)
 
PhosphorEngine::UnfloatResult resolveUnfloatGeometry (const QString &windowId, const QString &fallbackScreen) const
 Unconfined (user-toggle) form.
 
PhosphorEngine::UnfloatResult resolveUnfloatGeometry (const QString &windowId, const QString &fallbackScreen, bool confineToFallbackScreen) const
 confineToFallbackScreen refuses (returns not-found) when the RECORDED (raw, unresolved) home screen names a different physical monitor than fallbackScreen — the comparison runs BEFORE resolveUnfloatScreen, so a home screen that no longer resolves (monitor unplugged) also refuses rather than degrading into snapping a foreign layout's zone onto the live screen.
 
PhosphorEngine::UnfloatResult resolveFallbackUnfloatGeometry (const QString &windowId, const QString &fallbackScreen) const
 Fallback unfloat target for a window with NO pre-float zone (a never-snapped window that defaulted to floating).
 
PhosphorProtocol::WindowGeometryList applyBatchAssignments (const QVector< PhosphorEngine::ZoneAssignmentEntry > &entries, PhosphorEngine::SnapIntent intent=PhosphorEngine::SnapIntent::UserInitiated, std::function< QString()> fallbackScreenResolver={})
 
PhosphorEngine::SnapResult calculateSnapToPlacementRule (const QString &windowId, const QString &windowScreenName, bool isSticky) const
 
PhosphorEngine::SnapResult calculateSnapToLastZone (const QString &windowId, const QString &windowScreenId, bool isSticky) const
 
PhosphorEngine::SnapResult calculateSnapToEmptyZone (const QString &windowId, const QString &windowScreenId, bool isSticky) const
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateResnapFromPreviousLayout ()
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateResnapFromCurrentAssignments (const QString &screenFilter=QString()) const
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateResnapFromAutotileOrder (const QStringList &autotileWindowOrder, const QString &screenId, const QStringList &preClaimedZoneIds={}) const
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateSnapAllWindowEntries (const QStringList &windowIds, const QString &screenId) const
 
QVector< PhosphorEngine::ZoneAssignmentEntrycalculateRotation (bool clockwise, const QString &screenFilter=QString()) const
 
void markWindowReported (const QString &windowId)
 
const QSet< QString > & effectReportedWindows () const
 
int pruneStaleWindows (const QSet< QString > &aliveWindowIds) override
 Drop any per-engine bookkeeping for windows not in aliveWindowIds.
 
PhosphorEngine::IPlacementStatestateForScreen (const QString &screenId) override
 Per-screen state object for the given screen.
 
const PhosphorEngine::IPlacementStatestateForScreen (const QString &screenId) const override
 
void pushFocusedToEmptyZone (const PhosphorEngine::NavigationContext &ctx)
 Move the focused window to the first empty zone on ctx.screenId.
 
void rotateWindowsInLayout (bool clockwise, const QString &screenId)
 Rotate snapped windows through the layout's zone order on screenId.
 
void setPersistenceDelegate (std::function< void()> saveFn, std::function< void()> loadFn)
 Set persistence callbacks for save/load.
 
QString lastActiveScreenId () const
 Last screen the engine saw via windowFocused.
 
void setExcludeRuleSet (const PhosphorRules::RuleSet *ruleSet)
 Wire the daemon's filtered placement-exclusion rule set (rules carrying an Exclude or ExcludePlacement action) into the snap engine.
 
void setExclusionQueryProvider (ExclusionQueryProvider provider)
 Inject the exclusion query provider.
 
bool isAppIdExcluded (const QString &appId) const
 True if appId matches an enabled rule in the borrowed placement-exclusion set (Exclude or ExcludePlacement action) resolved against an appId-ONLY WindowQuery.
 
bool isWindowExcluded (const QString &windowId, const QString &screenHint=QString()) const
 Resolve exclusion for a live windowId using the FULL window attributes when the exclusion query provider is wired (matching the autotile engine): evaluates the Exclude rule set against the complete WindowQuery and applies the minimum-window-size thresholds to the query's frame size.
 
- Public Member Functions inherited from PhosphorEngine::PlacementEngineBase
virtual QRect lastManagedRect (const QString &windowId) const
 The exact rect this engine last APPLIED to windowId while managing it (its tile rect), remembered PAST the window's transition out of the managed state.
 
void setEngineSettings (QObject *settings)
 
QObject * engineSettings () const
 
 ~PlacementEngineBase () override
 
- Public Member Functions inherited from PhosphorEngine::IPlacementEngine
virtual ~IPlacementEngine ()=default
 
 IPlacementEngine (const IPlacementEngine &)=delete
 
IPlacementEngineoperator= (const IPlacementEngine &)=delete
 
void windowOpened (const QString &windowId, const QString &screenId)
 Convenience overload — equivalent to windowOpened(id, screen, 0, 0).
 
virtual bool claimCrossScreenReopen (const QString &windowId, const QString &openingScreenId, int minWidth=0, int minHeight=0)
 OPTIONAL: cross-screen session reclaim, the tiling-engine counterpart of the snap engine's recorded-screen restore.
 
virtual QString heldScreenForWindow (const QString &windowId) const
 OPTIONAL: the screen this engine genuinely HOLDS the window on IN THE SCREEN'S CURRENT CONTEXT — a MEMBERSHIP answer (tiled or engine-floating both count; a phantom reverse-map key does not), empty when the engine does not hold it or holds it only in a background context.
 
virtual void beginArrivalBurst ()
 Bracket a BURST of windowOpened calls delivered together (the adaptor's three dispatch loops: windowsOpenedBatch, the deferred-open flush, and the parked-open replay — daemon bring-up re-announce and mode flips).
 
virtual void endArrivalBurst ()
 
virtual QSet< QString > activeScreens () const
 
virtual void setActiveScreens (const QSet< QString > &screens)
 
virtual bool restorePlacement (const WindowPlacement &placement, const QString &screenId)
 Apply placement to a (re)opening window on screenId.
 
virtual QStringList managedWindowOrder (const QString &screenId) const
 
virtual void setInitialWindowOrder (const QString &screenId, const QStringList &windowIds)
 
virtual QString managedFocusedWindow (const QString &screenId) const
 The window this engine considers focused on screenId, or empty.
 
virtual int stickyPinnedDesktopForScreen (const QString &screenId) const
 The desktop this engine has PINNED screenId to, or 0 when it has not pinned it (which is the normal case, and the default here).
 
virtual void setInitialFocusedWindow (const QString &screenId, const QString &windowId)
 Hand the incoming engine the focus captured from the outgoing one.
 
virtual void applyPerScreenConfig (const QString &screenId, const QVariantMap &overrides)
 
virtual void clearPerScreenConfig (const QString &screenId)
 
virtual QVariantMap perScreenOverrides (const QString &screenId) const
 
virtual void markModeSpecificFloated (const QString &windowId)
 
virtual bool isModeSpecificFloated (const QString &windowId) const
 
virtual void clearModeSpecificFloatMarker (const QString &windowId)
 
virtual bool hasDragInsertPreview () const
 
virtual bool beginDragInsertPreview (const QString &windowId, const QString &screenId)
 
virtual void commitDragInsertPreview ()
 
virtual void cancelDragInsertPreview ()
 
virtual QString dragInsertPreviewScreenId () const
 
virtual QString dragInsertPreviewPriorScreenId () const
 The screen the previewed window was on BEFORE begin adopted it, or empty when it had no prior state (begin took it from untracked) or no preview is live.
 
virtual DragInsertTarget computeDragInsertTargetAtPoint (const QString &screenId, const QPoint &cursorPos) const
 Compute the drop target for a cursor position on a managed screen.
 
virtual void updateDragInsertPreview (const DragInsertTarget &target)
 Update the drop target for an active drag-insert preview.
 
virtual bool dragAutoScrollTick (const QString &screenId, const QPoint &cursorPos, qreal dtSeconds)
 Advance edge auto-scroll for a live drag-insert preview (niri's dnd-edge-view-scroll): an engine whose layout is a scrollable viewport moves its VIEW while the cursor sits inside a band at the work area's edge, so a drop can reach a column that is off screen.
 
virtual bool dragAutoScrollActive () const
 Whether edge auto-scroll currently owns the drop target.
 
virtual void cancelDragAutoScroll ()
 Give the drop target back and forget any armed band, WITHOUT moving the view or re-aiming.
 
virtual QRect dragInsertIndicatorRect (const QString &screenId) const
 The rect the dragged window would occupy if the live preview were dropped now, in absolute px on screenId, for a caller that wants to PAINT the drop target.
 
virtual void setInteractiveDragWindow (const QString &windowId)
 The window currently under a compositor interactive move (the whole drag, preview or not).
 
virtual bool isWindowManaged (const QString &windowId) const
 Whether the engine considers the window "managed" (eligible for layout operations).
 
virtual bool isWindowTiled (const QString &windowId) const
 Whether the window is actively tiled (engine-owned, non-floating).
 
virtual QSize windowMinimumSize (const QString &windowId) const
 The window's client-reported minimum size as last known by this engine, or an UNKNOWN answer when it has none.
 
virtual void windowMinSizeUpdated (const QString &windowId, int minWidth, int minHeight)
 Update a window's minimum size after the initial windowOpened.
 
virtual void onWindowResized (const QString &windowId, const QRect &oldFrame, const QRect &newFrame, const QString &screenId)
 Notify the engine that a tracked window finished an interactive resize.
 
virtual bool providesDragInsertSelector () const
 Whether the daemon's edge-triggered drag popup (the zone selector surface) should render this engine's DRAG-INSERT vocabulary — strip column cards whose gap / join / half targets translate into DragInsertTarget — instead of zone layouts, on screens this engine owns.
 
virtual QString algorithmId () const
 
virtual void setAlgorithm (const QString &algorithmId)
 
virtual QString activeScreen () const
 
virtual void setActiveScreenHint (const QString &screenId)
 
virtual void clearCurrentDesktopForScreen (const QString &screenId)
 Drop a screen's per-output desktop, reverting it to the global current.
 
virtual void updateStickyScreenPins (const std::function< bool(const QString &)> &isWindowSticky)
 
virtual void refreshConfigFromSettings ()
 Re-read all tuning values from the engine's settings interface.
 
virtual qreal effectiveSplitRatioStep (const QString &screenId) const
 
virtual int runtimeMaxWindows () const
 Runtime max-windows limit.
 
virtual std::optional< int > savedMaxWindowsForAlgorithm (const QString &algorithmId) const
 The user's saved per-algorithm max-windows tuning for algorithmId, or std::nullopt when the engine keeps no such slot.
 
virtual void retile (const QString &screenId=QString())
 
virtual void scheduleRetileForScreen (const QString &screenId)
 
virtual void increaseMasterRatio (qreal delta=kDefaultSplitRatioStep)
 
virtual void decreaseMasterRatio (qreal delta=kDefaultSplitRatioStep)
 
virtual void increaseMasterCount ()
 
virtual void decreaseMasterCount ()
 
virtual void focusMaster ()
 
virtual void swapFocusedWithMaster ()
 

Additional Inherited Members

- Static Public Attributes inherited from PhosphorEngine::IPlacementEngine
static constexpr qreal kDefaultSplitRatioStep = 0.05
 One home for the master/split ratio step so the default return below and the two default arguments cannot drift apart.
 
- Protected Member Functions inherited from PhosphorEngine::PlacementEngineBase
 PlacementEngineBase (QObject *parent=nullptr)
 
void announceLayerSwitch (const LayerSwitchResult &result, const QString &action, const QString &screenId)
 Emit the activation + navigationFeedback pair for a resolved layer focus switch (resolveLayerFocusSwitch).
 
- Protected Member Functions inherited from PhosphorEngine::IPlacementEngine
 IPlacementEngine ()=default
 

Detailed Description

Engine for manual zone-based window snapping.

Implements IPlacementEngine for screens using manual zone layouts (non-autotile). Handles auto-snap on window open, zone-based navigation, floating state, rotation, and resnap operations.

Uses WindowTrackingService as a shared state store for zone assignments, pre-tile geometries, and floating state. The snap engine adds behavior on top: auto-snap fallback chains, directional navigation via zone adjacency, and layout-change resnapping.

See also
PhosphorEngine::IPlacementEngine, AutotileEngine, WindowTrackingService

Member Typedef Documentation

◆ ExclusionQueryProvider

using PhosphorSnapEngine::SnapEngine::ExclusionQueryProvider = std::function<std::optional<PhosphorRules::WindowQuery>(const QString& windowId, const QString& screenHint)>

Provider that builds the full WindowQuery (window class / title / role / frame size / flags) for a live windowId.

Daemon-injected, keyed by the live windowId — the daemon resolves it from its WindowRegistry (the same buildContextualRuleQuery the float / restore predicates use, so the query carries the screen-derived ScreenId / ActiveLayout context too). When set, exclusion evaluates a window's FULL attributes (matching the autotile engine) instead of appId alone, and the frame size carried in the query is checked against the minimum-window-size thresholds. When UNSET (default) the engine falls back to the appId-only query — the historical behaviour unit tests rely on. A null/empty optional from the provider (metadata not yet known) also falls back to appId-only.

screenHint is the screen the caller knows the window belongs to, and exists for the window-open path: a window being restored is not in any SnapState yet, so the daemon's own screen resolution comes back empty and the ScreenId / ActiveLayout leaves of an Exclude rule would not resolve. Callers that ask about an already-tracked window (the navigation actions) pass an empty hint and let the daemon resolve the screen from its trackers.

◆ FloatPredicate

using PhosphorSnapEngine::SnapEngine::FloatPredicate = std::function<bool(const QString& windowId, const QString& screenId)>

Predicate deciding whether an opening window should start FLOATING because a "Float this app" rule matched it.

Daemon-injected, keyed by the live windowId, evaluated on the window-open path. When UNSET (default) no window is rule-floated and the engine keeps its historical open behaviour (path unit tests rely on this). Same lifetime contract as setRestorePositionPredicate — clear with {} before destroying any state the closure captured. Takes the OPENING SCREEN as well, so the resolver can stamp ScreenId and derive Mode — without which a rule pairing either with Float is silently inert.

◆ LiveModeResolver

Live placement-mode resolver injected by the daemon (its ScreenModeRouter): engine-live-set-first with cascade fallback and the tiling-mode→Snapping downgrade for unclaimed screens.

The capture gate consults it so a screen ENTERING a tiling mode (the cascade already flipped but no engine claims it yet) can still presave its live snap state; the raw cascade would refuse it and the presave would silently write nothing. Falls back to the registry's cascade when unset. Clear with {} at teardown.

◆ ManagedRestorePredicate

using PhosphorSnapEngine::SnapEngine::ManagedRestorePredicate = std::function<bool(const QString& windowId)>

Predicate consulted in resolveWindowRestore to decide whether a window that was SNAPPED at logout should be restored to its recorded zone on reopen/login (the "managed restore").

This is the snapped-to-zone analogue of RestorePositionPredicate (which governs FLOATED records). Keyed by the live windowId so the daemon closure stays settings-agnostic (LGPL boundary) — the engine only asks. The daemon wires it to the restoreWindowsToZonesOnLogin setting.

When the predicate returns false the stored snap is not re-applied; the window falls through to the normal auto-snap policy chain, exactly as a disabled-context rejection does. When UNSET (default) the engine restores snapped records unconditionally — the historical behaviour unit tests rely on. This gate is independent of ShouldRestorePredicate (the disabled-context gate); both must opt in for a managed restore to proceed.

◆ PlacementZonesResolver

using PhosphorSnapEngine::SnapEngine::PlacementZonesResolver = std::function<PlacementDirective(const QString& windowId, const QString& screenId)>

Resolver yielding the open-placement directive — SnapToZone ordinals and/or zone names, plus an optional RouteToScreen target and an optional RouteToDesktop target — for an opening window because a placement rule matched it.

Daemon-injected, keyed by the live windowId plus the screen the window is opening on (so a rule carrying a ScreenId constraint resolves against the window's current screen), evaluated on the window-open path (calculateSnapToPlacementRule, the highest-priority restore chain level). See PhosphorSnapEngine::PlacementDirective. Both lists empty ⇒ no SnapToZone rule matched; multiple targets across the two lists request a zone span (their unioned bounding rect). The engine stays settings/rule- store-agnostic (LGPL boundary) — it only asks. When UNSET (default) no window is rule-snapped and the engine keeps its historical open behaviour (path unit tests rely on this). Same lifetime contract as setFloatPredicate — clear with {} before destroying any captured state.

◆ RestorePositionPredicate

using PhosphorSnapEngine::SnapEngine::RestorePositionPredicate = std::function<bool(const QString& windowId)>

Predicate consulted in resolveWindowRestore to decide whether a FLOATED window should have its previous global position restored on open.

(Snapping is two-state — snapped or floated; "floated" is the only unsnapped state.)

Keyed by the live windowId so the daemon closure can build a full WindowQuery (window class / title / role) from its WindowRegistry and evaluate the per-window RestorePosition rule, falling back to the snappingRestoreFloatedWindowsOnLogin setting. Like ShouldRestorePredicate the engine stays settings-agnostic (LGPL boundary) — it only asks.

Returns true to restore the recorded position (cross-screen allowed — stored geometry is in global compositor coordinates, so re-applying it lands the window back on its original monitor).

The gate governs two things for FLOATED records (snapped-to-zone restore is unaffected):

  • cross-screen CONSUMPTION eligibility — a record whose recorded screen differs from the reopening screen is only consumed when the predicate opts the window in; otherwise consumption stays gated on the opening screen;
  • the geometry MOVE — a floated record ALWAYS re-marks the window floating (windowFloatingChanged), but its recorded position is re-applied only when the predicate opts in.

When the predicate is UNSET (default), the engine preserves its historical behaviour: a floated record is consumed only on the screen it reopens on and is marked floating without a position move — the path unit tests rely on.

◆ ShouldRestorePredicate

using PhosphorSnapEngine::SnapEngine::ShouldRestorePredicate = std::function<bool(const QString& screenId)>

Predicate consulted on the auto-snap entry path to suppress zone restores onto a context the user disabled.

Returns true if the screenId is currently active for snap mode, false if disabled. The engine library is intentionally settings-agnostic (LGPL boundary) so the daemon adaptor injects the predicate; SnapEngine itself has no notion of disabled contexts. The daemon-side closure is responsible for resolving the current virtual desktop / activity at call time — SnapState does not track those.

Applied inside resolveWindowRestore so BOTH the engine's own windowOpened path AND the D-Bus SnapAdaptor::resolveWindowRestore path (used by the KWin effect for per-window restores) hit the same gate. A PendingRestore authored before the user disabled the context can no longer drag a freshly opened window into a zone the user told us to stay out of (discussion #461 item 7). Without this gate, restarting the daemon was the only way to evict stale in-memory entries — the isPersistedContextDisabled filter on disk load only fires on startup, so any restore queued during the running session leaked through.

When unset (default), the engine behaves as if every context is active — the historical default that unit tests rely on.

◆ TilingEngineLiveResolver

using PhosphorSnapEngine::SnapEngine::TilingEngineLiveResolver = std::function<bool(PhosphorZones::AssignmentEntry::Mode mode, const QString& screenId)>

Whether the tiling engine owning mode is actually LIVE on screenId — the liveness half of resolveWindowRestore's cross-screen tile-defer gate.

The gate must ask exactly what the CLAIMING side answers: both tiling engines' claimCrossScreenReopen require the recorded home in their live screen set on top of the record-context mode verdict, so a defer keyed on mode alone stands down for a window the tiling engine then declines — the both-skipped strand. Only the daemon sees the engines' live sets, hence the injection. Unset → the gate falls back to mode alone (headless/test path). Clear with {} at teardown.

◆ UnfloatFallbackPredicate

using PhosphorSnapEngine::SnapEngine::UnfloatFallbackPredicate = std::function<bool(const QString& windowId, const QString& screenId)>

Predicate deciding whether an unfloat with NO remembered pre-float zone falls back to a zone anyway (the SetUnfloatFallbackToZone rule layered over the global unfloatFallbackToZone setting — the predicate itself implements rule ?? config).

Daemon-injected, keyed by the live windowId plus the RESOLVED restore screen (so the resolver can stamp ScreenId and derive Mode), consulted inside resolveFallbackUnfloatGeometry — which covers both the live user-toggle unfloat and SnapAdaptor::calculateUnfloatRestore. When UNSET (default) the engine reads the ISnapSettings bool directly, preserving the historical behaviour the unit tests rely on. Same lifetime contract as setFloatPredicate — clear with {} before destroying any state the closure captured.

Constructor & Destructor Documentation

◆ SnapEngine()

PhosphorSnapEngine::SnapEngine::SnapEngine ( PhosphorZones::LayoutRegistry layoutManager,
PhosphorEngine::IWindowTrackingService windowTracker,
PhosphorZones::IZoneDetector zoneDetector,
PhosphorEngine::IVirtualDesktopManager vdm,
QObject *  parent = nullptr 
)
explicit

◆ ~SnapEngine()

PhosphorSnapEngine::SnapEngine::~SnapEngine ( )
override

Member Function Documentation

◆ allSnapStates()

QList< SnapState * > PhosphorSnapEngine::SnapEngine::allSnapStates ( ) const

Every SnapState the engine owns, including the global holder, for whole-store enumerations (occupied zones, snapped/floating windows, flat-map views).

◆ applyBatchAssignments()

PhosphorProtocol::WindowGeometryList PhosphorSnapEngine::SnapEngine::applyBatchAssignments ( const QVector< PhosphorEngine::ZoneAssignmentEntry > &  entries,
PhosphorEngine::SnapIntent  intent = PhosphorEngine::SnapIntent::UserInitiated,
std::function< QString()>  fallbackScreenResolver = {} 
)

◆ applyGeometriesBatch

void PhosphorSnapEngine::SnapEngine::applyGeometriesBatch ( const PhosphorProtocol::WindowGeometryList geometries,
const QString &  action 
)
signal

Batch of window-geometry updates, applied by the KWin effect in a single operation.

The engine itself only ever emits action="rotate"; the SnapAdaptor layer attaches "resnap" / "vs_reconfigure" when it relays its own batches over the same WTA D-Bus signal ("snap_all" batches never cross the wire — the effect builds those locally). The action label disambiguates the cause downstream.

◆ applyGeometryRequested

void PhosphorSnapEngine::SnapEngine::applyGeometryRequested ( const QString &  windowId,
int  x,
int  y,
int  width,
int  height,
const QString &  zoneId,
const QString &  screenId,
bool  sizeOnly 
)
signal

Daemon-driven geometry application (used by autotile float restore)

◆ applyNoMatchFloatDefault()

void PhosphorSnapEngine::SnapEngine::applyNoMatchFloatDefault ( const QString &  windowId,
const QString &  screenId 
)

The no-match float-default terminal of resolveWindowRestore, callable by the SnapAdaptor when a SnapResult::deferredToTilingEngine verdict was returned and the offered reclaim then DECLINED — without this fallback a defer-then-decline left the window with no state in any engine.

No-op when the window already has a definite snap state, when snapping is disabled, or on empty arguments.

◆ calculateResnapEntriesFromAutotileOrder()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateResnapEntriesFromAutotileOrder ( const QStringList &  autotileWindowOrder,
const QString &  screenId,
const QStringList &  preClaimedZoneIds = {} 
)

Calculate resnap entries from autotile order WITHOUT emitting signal.

Returns the computed PhosphorEngine::ZoneAssignmentEntry vector so the caller can batch entries from multiple screens into a single resnapToNewLayoutRequested emission. Falls back to current-assignment entries if autotile order yields nothing.

Parameters
autotileWindowOrderOrdered list of window IDs from autotile engine
screenIdScreen to resnap on
preClaimedZoneIdsZone IDs already reserved by OTHER restore producers (e.g. the daemon's windowsReleased snap-zone restores for windows that were floated in autotile and are absent from the tile order). Seeds the claim ledger so the positional fallback never re-uses a zone another producer is reclaiming — the two-windows-one-zone collision.
Returns
Vector of PhosphorEngine::ZoneAssignmentEntry (may be empty)

◆ calculateResnapFromAutotileOrder()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateResnapFromAutotileOrder ( const QStringList &  autotileWindowOrder,
const QString &  screenId,
const QStringList &  preClaimedZoneIds = {} 
) const

◆ calculateResnapFromCurrentAssignments()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateResnapFromCurrentAssignments ( const QString &  screenFilter = QString()) const

◆ calculateResnapFromPreviousLayout()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateResnapFromPreviousLayout ( )

◆ calculateRotation()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateRotation ( bool  clockwise,
const QString &  screenFilter = QString() 
) const

◆ calculateSnapAllWindowEntries()

QVector< PhosphorEngine::ZoneAssignmentEntry > PhosphorSnapEngine::SnapEngine::calculateSnapAllWindowEntries ( const QStringList &  windowIds,
const QString &  screenId 
) const

◆ calculateSnapAllWindows()

PhosphorProtocol::SnapAllResultList PhosphorSnapEngine::SnapEngine::calculateSnapAllWindows ( const QStringList &  windowIds,
const QString &  screenId 
)

Calculate snap-all-windows assignments without applying them.

Parameters
windowIdsList of window IDs to snap
screenIdScreen to snap on
Returns
JSON array of zone assignment entries for KWin effect to apply

◆ calculateSnapToEmptyZone()

PhosphorEngine::SnapResult PhosphorSnapEngine::SnapEngine::calculateSnapToEmptyZone ( const QString &  windowId,
const QString &  windowScreenId,
bool  isSticky 
) const

◆ calculateSnapToLastZone()

PhosphorEngine::SnapResult PhosphorSnapEngine::SnapEngine::calculateSnapToLastZone ( const QString &  windowId,
const QString &  windowScreenId,
bool  isSticky 
) const

◆ calculateSnapToPlacementRule()

PhosphorEngine::SnapResult PhosphorSnapEngine::SnapEngine::calculateSnapToPlacementRule ( const QString &  windowId,
const QString &  windowScreenName,
bool  isSticky 
) const

◆ capturePlacement()

std::optional< PhosphorEngine::WindowPlacement > PhosphorSnapEngine::SnapEngine::capturePlacement ( const QString &  windowId) const
overridevirtual

Unified placement model — report this window's current snap state (snapped or floated) for persistence, or nullopt if untracked.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ capturePlacementAtDesktop()

std::optional< PhosphorEngine::WindowPlacement > PhosphorSnapEngine::SnapEngine::capturePlacementAtDesktop ( const QString &  windowId,
int  gateDesktop 
) const

capturePlacement with the mode gate resolved at an EXPLICIT desktop.

The public capture gates on the window's screen at its CURRENT desktop, which is the right question for the periodic refresh but the wrong one for a cross-desktop handoff: the daemon routed the handoff here because (screen, toDesktop) resolves to Snapping, yet the screen's visible desktop may be a tiling one, so the current-desktop gate refused the capture and the durable record silently kept the OLD desktop. gateDesktop <= 0 means "the screen's current desktop" (the public capture's behaviour, including its live-resolver fast path).

◆ commitMultiZoneSnap()

void PhosphorSnapEngine::SnapEngine::commitMultiZoneSnap ( const QString &  windowId,
const QStringList &  zoneIds,
const QString &  screenId,
PhosphorEngine::SnapIntent  intent = PhosphorEngine::SnapIntent::UserInitiated,
int  virtualDesktop = 0 
)

◆ commitSnap()

void PhosphorSnapEngine::SnapEngine::commitSnap ( const QString &  windowId,
const QString &  zoneId,
const QString &  screenId,
PhosphorEngine::SnapIntent  intent = PhosphorEngine::SnapIntent::UserInitiated,
int  virtualDesktop = 0 
)

virtualDesktop pins the assignment to a specific 1-based desktop; 0 (default) records it on the window's current desktop.

Non-zero is used by the RouteToDesktop placement path (track the assignment on the destination desktop) and by batch resnap entries that preserve a window's recorded desktop through the commit (see ZoneAssignmentEntry::virtualDesktop).

◆ currentActivity()

QString PhosphorSnapEngine::SnapEngine::currentActivity ( ) const

◆ currentVirtualDesktop()

int PhosphorSnapEngine::SnapEngine::currentVirtualDesktop ( ) const

Current virtual desktop (1-based; 0 when no virtual-desktop manager is wired) and activity, forwarded from the injected managers.

Public for symmetry with AutotileEngine's analogous accessors and to keep the engine's "current context" surface coherent — the daemon uses Daemon::currentDesktop() / Daemon::currentActivity() directly rather than going through the engine. currentActivity() is used throughout the engine's own sources (calculate, lifecycle, navigation_actions, navigation_crosssurface, SnapEngine); the no-arg currentVirtualDesktop() has no in-tree caller. Note the fallback it mirrors lives in IVirtualDesktopManager, not here: currentVirtualDesktopForScreen goes straight to the VDM's currentDesktopForScreen and never routes through this accessor. Both stay public so a future adaptor that wants the engine's own view (e.g. for a per-engine OSD) doesn't have to wire its own VDM.

◆ currentVirtualDesktopForScreen()

int PhosphorSnapEngine::SnapEngine::currentVirtualDesktopForScreen ( const QString &  screenId) const

This screen's current virtual desktop (Plasma 6.7 per-output virtual desktops, #648).

Goes STRAIGHT to the VDM's currentDesktopForScreen — the per-screen-to-global fallback lives inside IVirtualDesktopManager, not here, so this never routes through currentVirtualDesktop().

◆ cycleFocus()

void PhosphorSnapEngine::SnapEngine::cycleFocus ( bool  forward,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Cycle keyboard focus forward/backward through managed windows in the active zone (or the layout cycle order if single-window per zone).

Implements PhosphorEngine::IPlacementEngine.

◆ desktopsWithActiveState()

QSet< int > PhosphorSnapEngine::SnapEngine::desktopsWithActiveState ( ) const
overridevirtual

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ effectReportedWindows()

const QSet< QString > & PhosphorSnapEngine::SnapEngine::effectReportedWindows ( ) const
inline

◆ emitBatchedResnap()

void PhosphorSnapEngine::SnapEngine::emitBatchedResnap ( const QVector< PhosphorEngine::ZoneAssignmentEntry > &  entries)

Emit a single batched resnapToNewLayoutRequested signal.

Serializes the given entries and emits the D-Bus signal once. Used by the daemon to combine entries from multiple screens into one signal, eliminating the per-screen race condition.

Parameters
entriesCombined PhosphorEngine::ZoneAssignmentEntry vector from all screens

◆ engineId()

QString PhosphorSnapEngine::SnapEngine::engineId ( ) const
inlineoverridevirtual

Stable engine identity for HandoffContext.fromEngineId.

Conventional values: "snap" / "autotile" / "scrolling". Empty string means "unidentified" and disables receive-side reasoning that depends on the source mode.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ entryZoneForCrossing()

QString PhosphorSnapEngine::SnapEngine::entryZoneForCrossing ( const QString &  direction,
const QString &  neighbourScreen 
) const

The zone a window ENTERS when it crosses onto neighbourScreen moving in direction: the first zone on the edge facing back toward the source (crossing "right" enters the neighbour's left-edge zone).

Empty when no zone-adjacency resolver is wired or the neighbour has no such zone. Used by the daemon cross-mode handoff to place a window arriving on a snap monitor.

◆ floatingWindows()

QStringList PhosphorSnapEngine::SnapEngine::floatingWindows ( ) const

◆ focusInDirection()

void PhosphorSnapEngine::SnapEngine::focusInDirection ( const QString &  direction,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Walk to the adjacent window in direction and transfer keyboard focus.

Empty direction is a no-op with feedback.

Implements PhosphorEngine::IPlacementEngine.

◆ forgetWindow()

void PhosphorSnapEngine::SnapEngine::forgetWindow ( const QString &  windowId)

Drop the reverse-map entry for windowId (window closed / fully removed).

Does not touch state objects.

◆ globalState()

SnapState * PhosphorSnapEngine::SnapEngine::globalState ( ) const
inline

The global-scalar holder (last-used-zone + user-snapped classes).

Also the fallback home for screenless float bookkeeping. Never null after construction.

◆ handoffReceive()

void PhosphorSnapEngine::SnapEngine::handoffReceive ( const HandoffContext ctx)
overridevirtual

Receive ownership of a window from another engine.

Implementations should:

  • Add the window to their own tracking (per-screen/per-state).
  • Decide placement (snap to zone / tile / float) using the context and engine-local policy. Drag drops typically place at dropPos; non-drag handoffs (cross-engine focus changes, programmatic moves) typically respect wasFloating (the window keeps its live frame, so no geometry is carried in the context).
  • Emit any windowFloatingChanged / placement signals their normal placement paths emit, so downstream state stays consistent.

Default is a no-op so engines that don't yet implement the handoff don't reject the call — the orchestrator falls back to its legacy path.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ handoffRelease()

void PhosphorSnapEngine::SnapEngine::handoffRelease ( const QString &  windowId)
overridevirtual

Release ownership of a window WITHOUT modifying its geometry.

Implementations should:

  • Remove the window from per-screen/per-state tracking.
  • Clear zone assignments (if any) WITHOUT triggering a resnap of neighbours — that's the receiving engine's job once it places the window in its layout.
  • Preserve any pre-tile / pre-float captured geometry that should survive the cross-engine move (the receiving engine may consult it via the HandoffContext for size preservation).

Default is a no-op for the same reason as handoffReceive.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ isActiveOnScreen()

bool PhosphorSnapEngine::SnapEngine::isActiveOnScreen ( const QString &  screenId) const
overridevirtual

Whether this engine is active on the given screen.

Implements PhosphorEngine::IPlacementEngine.

◆ isAppIdExcluded()

bool PhosphorSnapEngine::SnapEngine::isAppIdExcluded ( const QString &  appId) const

True if appId matches an enabled rule in the borrowed placement-exclusion set (Exclude or ExcludePlacement action) resolved against an appId-ONLY WindowQuery.

This is a narrow seam: the runtime exclusion path is isWindowExcluded, which evaluates the FULL window attributes; this method survives as (a) the early-init / no-metadata fallback inside isWindowExcluded and (b) a directly testable hook for the rule-set wiring (nullptr borrow, empty-set short-circuit, evaluator rebind on pointer change, revision-bump invalidation). An Exclude rule keyed on a non-AppId field (WindowClass Contains …, Title Regex …) does NOT match here — use isWindowExcluded for that. Pure const observer — no side effects beyond the mutable evaluator cache.

◆ isEnabled()

bool PhosphorSnapEngine::SnapEngine::isEnabled ( ) const
overridevirtualnoexcept

True when snapping is globally enabled.

Mirrors AutotileEngine::isEnabled() so callers (daemon shortcut dispatch, mode routing) can gate snap-mode operations through the IPlacementEngine interface uniformly. Without this override SnapEngine inherits IPlacementEngine's return false default, which made every snap engine a no-op to any isEnabled() caller.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ isFloating()

bool PhosphorSnapEngine::SnapEngine::isFloating ( const QString &  windowId) const

◆ isWindowExcluded()

bool PhosphorSnapEngine::SnapEngine::isWindowExcluded ( const QString &  windowId,
const QString &  screenHint = QString() 
) const

Resolve exclusion for a live windowId using the FULL window attributes when the exclusion query provider is wired (matching the autotile engine): evaluates the Exclude rule set against the complete WindowQuery and applies the minimum-window-size thresholds to the query's frame size.

Falls back to the appId-only path (isAppIdExcluded's query shape) when no provider is set or window metadata is not yet known. screenHint is forwarded to the provider — see ExclusionQueryProvider; pass the screen the window is opening on where it is known, and leave it empty for an already-tracked window. Public so the unit-test layer can drive the wiring directly.

◆ isWindowTracked()

bool PhosphorSnapEngine::SnapEngine::isWindowTracked ( const QString &  windowId) const
overridevirtual

Whether this engine considers the window owned (snapped, snap-floated, or otherwise carried in SnapState's screen/zone maps).

Used by the daemon to disambiguate which engine should handle a shortcut and to decide whether a cross-engine handoff is needed.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ lastActiveScreenId()

QString PhosphorSnapEngine::SnapEngine::lastActiveScreenId ( ) const
inline

Last screen the engine saw via windowFocused.

Used for OSD fallback when a navigation failure needs to cite a screen and the live cursor hasn't landed on one yet. Exposed as a const getter so tests can verify the focus-tracking contract without dummy signal stubs.

◆ layoutSupport()

LayoutSupport PhosphorSnapEngine::SnapEngine::layoutSupport ( ) const
inlineoverridevirtual

Snap placement is driven by user-selectable zone layouts.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ loadState()

void PhosphorSnapEngine::SnapEngine::loadState ( )
overridevirtual

◆ markWindowReported()

void PhosphorSnapEngine::SnapEngine::markWindowReported ( const QString &  windowId)

◆ migrateWindowToScreen()

bool PhosphorSnapEngine::SnapEngine::migrateWindowToScreen ( const QString &  windowId,
const QString &  newScreenId 
)

Re-home a tracked window's snap state onto newScreenId's per-key store when it crosses monitors.

Moves the window's per-window entries (zone, live screen, desktop, floating bit, pre-float zone/screen, auto-snap flag) from its current owning store to the store for newScreenId's current context and updates the reverse map. The live screen value is rewritten to newScreenId so screenForTrackedWindow reflects the destination (the #724 cross-monitor determinism requirement); the pre-float zone is preserved so an unfloat back on the source monitor still restores the home zone. No-op when the window is untracked here (e.g. adopted fresh from another engine) or the resolved key is unchanged. Returns true when a migration happened. Driven by the daemon's per-window screen handlers (windowScreenChanged / windowActivated) and by handoffReceive; the analogue of AutotileEngine's windowFocused cross-screen migration.

◆ moveFocusedInDirection()

void PhosphorSnapEngine::SnapEngine::moveFocusedInDirection ( const QString &  direction,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Move the focused window into the adjacent zone in direction (displacing or filling the target).

Empty direction is a no-op.

Implements PhosphorEngine::IPlacementEngine.

◆ moveFocusedToPosition()

void PhosphorSnapEngine::SnapEngine::moveFocusedToPosition ( int  zoneNumber,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Move the focused window to the layout zone with zoneNumber (1-based) on ctx.screenId.

PhosphorZones::Zone numbers outside [1,9] are rejected.

Implements PhosphorEngine::IPlacementEngine.

◆ pruneStaleWindows()

int PhosphorSnapEngine::SnapEngine::pruneStaleWindows ( const QSet< QString > &  aliveWindowIds)
overridevirtual

Drop any per-engine bookkeeping for windows not in aliveWindowIds.

The base keeps no per-window state of its own now, so it returns 0; engines override and add their own pruning (then call the base).

Reimplemented from PhosphorEngine::PlacementEngineBase.

◆ pruneStatesForActivities()

void PhosphorSnapEngine::SnapEngine::pruneStatesForActivities ( const QStringList &  validActivities)
overridevirtual

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ pruneStatesForDesktop()

void PhosphorSnapEngine::SnapEngine::pruneStatesForDesktop ( int  removedDesktop)
overridevirtual

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ pruneStatesForRemovedScreen()

void PhosphorSnapEngine::SnapEngine::pruneStatesForRemovedScreen ( const QString &  physicalScreenId)
overridevirtual

Prune per-(screen, desktop, activity) state for a PHYSICALLY REMOVED output (monitor hot-unplug), matching every virtual sub-screen of the removed physical id.

All three engines override this and the daemon drives each from its screenRemoved handling: snap's stores are created lazily on placement with no screens set to reap them, and the two tiling engines' screens-set sweeps only reap CURRENT-context states, so sibling-context states (other desktops/activities) of the removed output would leak without the explicit whole-output prune. A tiling-family engine must emit windowsReleased for the windows it drops here, AFTER its reverse-map cleanup, so the daemon's restore consumers can re-home them; snap does not, because it is the engine those releases are restored INTO.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ pushFocusedToEmptyZone()

void PhosphorSnapEngine::SnapEngine::pushFocusedToEmptyZone ( const PhosphorEngine::NavigationContext ctx)

Move the focused window to the first empty zone on ctx.screenId.

The IPlacementEngine override pushToEmptyZone() delegates here.

◆ pushToEmptyZone()

void PhosphorSnapEngine::SnapEngine::pushToEmptyZone ( const PhosphorEngine::NavigationContext ctx)
overridevirtual

Move the focused window to the first empty zone on ctx.screenId.

Implements PhosphorEngine::IPlacementEngine.

◆ reapplyLayout()

void PhosphorSnapEngine::SnapEngine::reapplyLayout ( const PhosphorEngine::NavigationContext ctx)
overridevirtual

Re-apply the current layout to all managed windows.

Forwards to resnapToNewLayout().

Implements PhosphorEngine::IPlacementEngine.

◆ reapplyManagedWindowAppearance()

void PhosphorSnapEngine::SnapEngine::reapplyManagedWindowAppearance ( )
overridevirtual

Re-emit the snap geometry for every currently-snapped (non-floating) window so the compositor re-applies its snap border / hidden title bar after a bridge reconnect.

Does not recompute zone assignments. See IPlacementEngine::reapplyManagedWindowAppearance().

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ resnapCurrentAssignments()

void PhosphorSnapEngine::SnapEngine::resnapCurrentAssignments ( const QString &  screenFilter = QString())

Resnap windows to their current zone assignments (re-apply geometries)

Parameters
screenFilterOptional screen name filter (empty = all screens)

◆ resnapFromAutotileOrder()

void PhosphorSnapEngine::SnapEngine::resnapFromAutotileOrder ( const QStringList &  autotileWindowOrder,
const QString &  screenId 
)

Resnap windows using autotile window order as assignment source.

Parameters
autotileWindowOrderOrdered list of window IDs from autotile engine
screenIdScreen to resnap on
Note
Falls back to resnapCurrentAssignments if no entries are calculated

◆ resnapToNewLayout()

void PhosphorSnapEngine::SnapEngine::resnapToNewLayout ( )

Resnap windows from previous layout to current layout after layout switch.

Maps windows by zone number (1->1, 2->2, etc.) with wrapping when new layout has fewer zones.

◆ resnapToNewLayoutRequested

void PhosphorSnapEngine::SnapEngine::resnapToNewLayoutRequested ( const QString &  resnapData)
signal

Batched resnap data (routed through WTA::handleBatchedResnap for bookkeeping)

◆ resolveCrossDesktopZone()

std::pair< QString, QRect > PhosphorSnapEngine::SnapEngine::resolveCrossDesktopZone ( const QString &  currentZoneId,
const QString &  screenId,
int  targetDesktop 
) const

Resolve the zone on screenId's targetDesktop layout that is positionally equivalent to currentZoneId (1-based index of zones sorted by number), plus its pixel geometry.

Returns an empty pair when the target desktop has no layout, no matching slot, or invalid geometry. Public (like the desktop/activity accessors) so cross-surface handoff logic and tests can map a window's slot onto another desktop's layout.

◆ resolveFallbackUnfloatGeometry()

PhosphorEngine::UnfloatResult PhosphorSnapEngine::SnapEngine::resolveFallbackUnfloatGeometry ( const QString &  windowId,
const QString &  fallbackScreen 
) const

Fallback unfloat target for a window with NO pre-float zone (a never-snapped window that defaulted to floating).

Opt-in: it returns a found result only when the fallback is enabled for this window, which is the injected predicate's verdict (rule ?? config layering) when one is wired via setUnfloatFallbackPredicate, else the unfloatFallbackToZone setting read through ISnapSettings. Enabled, it resolves last-used → first-empty → first zone in the resolved screen's layout. The screen is fallbackScreen (the caller's live output) when it still exists, else the window's tracked float screen, and it is resolved BEFORE the opt-in gate because the predicate is evaluated against it. Returns not-found when the fallback is disabled or no zone resolves (so the caller keeps the window floating with feedback).

◆ resolveUnfloatGeometry() [1/2]

PhosphorEngine::UnfloatResult PhosphorSnapEngine::SnapEngine::resolveUnfloatGeometry ( const QString &  windowId,
const QString &  fallbackScreen 
) const

Unconfined (user-toggle) form.

Also the ABI-stable signature the installed library exported before the confinement parameter existed.

◆ resolveUnfloatGeometry() [2/2]

PhosphorEngine::UnfloatResult PhosphorSnapEngine::SnapEngine::resolveUnfloatGeometry ( const QString &  windowId,
const QString &  fallbackScreen,
bool  confineToFallbackScreen 
) const

confineToFallbackScreen refuses (returns not-found) when the RECORDED (raw, unresolved) home screen names a different physical monitor than fallbackScreen — the comparison runs BEFORE resolveUnfloatScreen, so a home screen that no longer resolves (monitor unplugged) also refuses rather than degrading into snapping a foreign layout's zone onto the live screen.

True for suspension (minimize) unfloats — the minimize round trip must never move the window across monitors, and a cross-monitor home can only be stale state (Discussion #724). False for user float toggles, whose cross-monitor unfloat-to-home restore is deliberate.

◆ resolveWindowRestore()

PhosphorEngine::SnapResult PhosphorSnapEngine::SnapEngine::resolveWindowRestore ( const QString &  windowId,
const QString &  screenId,
bool  sticky,
PhosphorEngine::WindowKind  kind = PhosphorEngine::WindowKind::Unknown 
)

Resolve auto-snap for a newly opened window.

A matched SnapToZone placement rule has highest priority and overrides any stored placement (the store still re-binds the record first, so the window's float-back geometry survives the override). Otherwise the unified WindowPlacementStore reopens the window from its snapped or floated record (cross-screen where the predicates allow). With neither, the fallback chain runs:

  1. Auto-assign to empty zone
  2. Snap to last zone (final fallback)

Returns a PhosphorEngine::SnapResult so the D-Bus adaptor can unpack geometry for the KWin effect. Also handles floating windows (skips snap, emits feedback).

Parameters
windowIdWindow identifier
screenIdScreen where the window appeared
stickyWhether the window is on all desktops
kindStructural kind of the opening window. Accepted for D-Bus wire-compatibility but no longer gates restore — the matched WindowPlacement record carries its own kind.
Returns
PhosphorEngine::SnapResult with geometry and zone info, or PhosphorEngine::SnapResult::noSnap()

◆ restoreFocusedWindow()

void PhosphorSnapEngine::SnapEngine::restoreFocusedWindow ( const PhosphorEngine::NavigationContext ctx)
overridevirtual

Restore the focused window to its captured pre-snap size and unsnap.

Implements PhosphorEngine::IPlacementEngine.

◆ rotateWindows()

void PhosphorSnapEngine::SnapEngine::rotateWindows ( bool  clockwise,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Rotate snapped windows through the layout's zone order, dispatched via IPlacementEngine.

Forwards to rotateWindowsInLayout().

Implements PhosphorEngine::IPlacementEngine.

◆ rotateWindowsInLayout()

void PhosphorSnapEngine::SnapEngine::rotateWindowsInLayout ( bool  clockwise,
const QString &  screenId 
)

Rotate snapped windows through the layout's zone order on screenId.

◆ saveState()

void PhosphorSnapEngine::SnapEngine::saveState ( )
overridevirtual

◆ screenForTrackedWindow()

QString PhosphorSnapEngine::SnapEngine::screenForTrackedWindow ( const QString &  windowId) const
overridevirtual

Return the screen this engine considers the window to be on, or empty if the window isn't tracked by this engine.

The daemon-side shortcut router consults this across engines to resolve the active window's current screen for routing decisions (float, focus, move). Without it, a cross-engine handoff (e.g. drag-insert from snap into autotile) leaves the daemon's screenAssignments lookup empty because the source engine has released its tracking, and the next shortcut routes to whichever engine the cached focus screen pointed at rather than the engine that now owns the window.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setAutotileEngine()

void PhosphorSnapEngine::SnapEngine::setAutotileEngine ( PhosphorEngine::IPlacementEngine engine)

Set the autotile engine for screen ownership checks.

SnapEngine is active on screens where AutotileEngine is NOT active. This must be called after the AutotileEngine is created.

Parameters
engineAutotileEngine instance (not owned, must outlive SnapEngine)

◆ setCrossSurfaceResolver()

void PhosphorSnapEngine::SnapEngine::setCrossSurfaceResolver ( PhosphorEngine::ICrossSurfaceResolver resolver)
overridevirtual

Inject the cross-surface resolver (neighbour output / desktop lookup), threaded into the navigation target resolver so a no-adjacent-zone boundary crosses into the neighbouring output instead of failing.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setCurrentActivity()

void PhosphorSnapEngine::SnapEngine::setCurrentActivity ( const QString &  activity)
overridevirtual

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setCurrentDesktop()

void PhosphorSnapEngine::SnapEngine::setCurrentDesktop ( int  desktop)
overridevirtual

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setCurrentDesktopForScreen()

void PhosphorSnapEngine::SnapEngine::setCurrentDesktopForScreen ( const QString &  screenId,
int  desktop 
)
overridevirtual

Set a single screen's current virtual desktop (Plasma 6.7 "switch desktops independently for each screen").

A PURE context swap — it selects which per-(screen, desktop) tiling state is current for this screen; it does NOT migrate windows between desktop states (the other desktop's state must stay put so it reappears when that screen returns). Default no-op for engines that are not per-screen-desktop-aware.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setExcludeRuleSet()

void PhosphorSnapEngine::SnapEngine::setExcludeRuleSet ( const PhosphorRules::RuleSet *  ruleSet)

Wire the daemon's filtered placement-exclusion rule set (rules carrying an Exclude or ExcludePlacement action) into the snap engine.

See the comment block on the private members and the impl in navigation_actions.cpp for the lifetime contract — the pointer is borrowed and the cached evaluator drops on a pointer change.

The borrowed rule set MUST outlive every subsequent exclusion resolve (isWindowExcluded / evaluateExcludeRules, and the legacy isAppIdExcluded seam). The Daemon currently guarantees this through member-declaration order (m_excludeRuleSet is declared before m_snapEngine so reverse-order destruction tears the engine down first), AND additionally clears the borrow symmetrically by calling setExcludeRuleSet(nullptr) in Daemon::stop() before m_snapEngine.reset() — that explicit teardown survives a future reordering or ownership move that would otherwise silently introduce a dangling pointer.

Declared OUTSIDE the Q_SIGNALS section below: MOC treats every declaration in Q_SIGNALS: as a signal and generates a stub body for it, so placing this setter inside that section makes the translation unit redefine the function and the link fails.

◆ setExclusionQueryProvider()

void PhosphorSnapEngine::SnapEngine::setExclusionQueryProvider ( ExclusionQueryProvider  provider)
inline

Inject the exclusion query provider.

See ExclusionQueryProvider. Same lifetime contract as setExcludeRuleSet — the caller keeps captured state valid for the engine's lifetime; clear with {} before destroying it.

◆ setFloating()

void PhosphorSnapEngine::SnapEngine::setFloating ( const QString &  windowId,
bool  floating 
)

◆ setFloatPredicate()

void PhosphorSnapEngine::SnapEngine::setFloatPredicate ( FloatPredicate  predicate)
inline

◆ setLiveModeResolver()

void PhosphorSnapEngine::SnapEngine::setLiveModeResolver ( LiveModeResolver  resolver)
inline

◆ setManagedRestorePredicate()

void PhosphorSnapEngine::SnapEngine::setManagedRestorePredicate ( ManagedRestorePredicate  predicate)
inline

Inject the managed (snapped-to-zone) restore gate.

See ManagedRestorePredicate. Same lifetime contract as setRestorePositionPredicate — clear with {} before destroying any captured state.

◆ setNavigationStateProvider()

void PhosphorSnapEngine::SnapEngine::setNavigationStateProvider ( INavigationStateProvider provider)

Wire the typed navigation-state provider.

Replaces the opaque QObject* setWindowTrackingAdaptor() that dispatched lastActiveWindowId / lastActiveScreenName / lastCursorScreenName / frameGeometry via QMetaObject::invokeMethod. The daemon's WindowTrackingAdaptor must implement (or wrap) INavigationStateProvider.

Must be set after construction and before any navigation method is called. Not owned; must outlive SnapEngine.

◆ setPersistenceDelegate()

void PhosphorSnapEngine::SnapEngine::setPersistenceDelegate ( std::function< void()>  saveFn,
std::function< void()>  loadFn 
)
inline

Set persistence callbacks for save/load.

KConfig persistence is owned by WindowTrackingAdaptor (WTS is KConfig-free). These callbacks allow SnapEngine to fulfill the IPlacementEngine persistence contract without introducing KConfig as a dependency.

Parameters
saveFnCalled by saveState() to persist WTS state
loadFnCalled by loadState() to restore WTS state

◆ setPlacementZonesResolver()

void PhosphorSnapEngine::SnapEngine::setPlacementZonesResolver ( PlacementZonesResolver  resolver)
inline

◆ setRestorePositionPredicate()

void PhosphorSnapEngine::SnapEngine::setRestorePositionPredicate ( RestorePositionPredicate  predicate)
inline

Inject the unsnapped-position-restore gate.

See RestorePositionPredicate. Same lifetime contract as setShouldRestorePredicate — clear with {} before destroying any captured state.

◆ setShouldRestorePredicate()

void PhosphorSnapEngine::SnapEngine::setShouldRestorePredicate ( ShouldRestorePredicate  predicate)
inline

Inject the auto-snap-restore gate.

See ShouldRestorePredicate.

Ownership: the caller keeps any captured state valid for the engine's lifetime. To detach safely, clear via setShouldRestorePredicate({}) before destroying the captured object.

◆ setTilingEngineLiveResolver()

void PhosphorSnapEngine::SnapEngine::setTilingEngineLiveResolver ( TilingEngineLiveResolver  resolver)
inline

◆ setUnfloatFallbackPredicate()

void PhosphorSnapEngine::SnapEngine::setUnfloatFallbackPredicate ( UnfloatFallbackPredicate  predicate)
inline

◆ setWindowFloat()

void PhosphorSnapEngine::SnapEngine::setWindowFloat ( const QString &  windowId,
bool  shouldFloat,
const QString &  screenId = QString() 
)
overridevirtual

Set floating state explicitly (directional, not toggle).

Parameters
screenIdThe window's authoritative current screen, when the caller knows it (the D-Bus setWindowFloatingForScreen threads the effect's live output here). An engine WITHOUT live per-window screen tracking MUST prefer this over its own tracked association, which can be stale after a floating window drifts across monitors — using the stale screen makes the unfloat's cross-monitor guard non-deterministic (snap and scroll honour it for exactly that reason). AutotileEngine deliberately resolves from its own tracking instead: its focus-driven migration keeps the association current, and the parameter can lag it mid-handoff. Empty (the default) means "resolve it yourself" for internal callers.

Implements PhosphorEngine::IPlacementEngine.

◆ setWindowRegistry()

void PhosphorSnapEngine::SnapEngine::setWindowRegistry ( QObject *  registry)
overridevirtual

Attach the daemon's shared window registry.

Threaded into every SnapState (the per-screen stores, the global-scalar holder, and any created later) plus the engine's own canonicalization so the reverse map keys on the same stable first-seen composite the stores do (issue #628). Not owned.

Overrides IPlacementEngine::setWindowRegistry(QObject*): the interface hands engines a QObject carrying the registry and each casts to its concrete type.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ setZoneAdjacencyResolver()

void PhosphorSnapEngine::SnapEngine::setZoneAdjacencyResolver ( IZoneAdjacencyResolver resolver)

Set typed zone-adjacency resolver for directional navigation.

Replaces the opaque QObject* setZoneDetectionAdaptor() that dispatched via QMetaObject::invokeMethod. The daemon's ZoneDetectionAdaptor must implement (or wrap) IZoneAdjacencyResolver.

Parameters
resolverNon-owning pointer; must outlive SnapEngine.

◆ snapAllWindows() [1/2]

void PhosphorSnapEngine::SnapEngine::snapAllWindows ( const PhosphorEngine::NavigationContext ctx)
overridevirtual

Snap every unmanaged window on the screen.

The IPlacementEngine override takes PhosphorEngine::NavigationContext; coexists with the existing snapAllWindows(const QString&) method which it delegates to.

Implements PhosphorEngine::IPlacementEngine.

◆ snapAllWindows() [2/2]

void PhosphorSnapEngine::SnapEngine::snapAllWindows ( const QString &  screenId)

Request the KWin effect to collect and snap all unsnapped windows.

Parameters
screenIdScreen to operate on

◆ snapAllWindowsRequested

void PhosphorSnapEngine::SnapEngine::snapAllWindowsRequested ( const QString &  screenId)
signal

Request KWin effect to collect unsnapped windows and snap them all.

◆ snapState()

SnapState * PhosphorSnapEngine::SnapEngine::snapState ( ) const
inline

The global-scalar holder (alias of globalState).

Callers/tests that only need the still-global last-used-zone / user-snapped scalars use this; per-window data now lives in the per-screen stores, reached via stateForWindow.

◆ spanFocusedInDirection()

void PhosphorSnapEngine::SnapEngine::spanFocusedInDirection ( const QString &  direction,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Grow the focused window's zone span into the adjacent zone(s) in direction, or retract the opposite edge when nothing lies that way (pressing back toward the span undoes the last grow).

Never crosses outputs or desktops. Empty direction is a no-op with feedback.

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ stateForScreen() [1/2]

const PhosphorEngine::IPlacementState * PhosphorSnapEngine::SnapEngine::stateForScreen ( const QString &  screenId) const
overridevirtual

◆ stateForScreen() [2/2]

PhosphorEngine::IPlacementState * PhosphorSnapEngine::SnapEngine::stateForScreen ( const QString &  screenId)
overridevirtual

Per-screen state object for the given screen.

May return nullptr if the engine does not manage the screen OR if per-screen state ownership has not yet been wired for that engine. Callers must not use a non-null return as a proxy for "engine manages this screen" — use isActiveOnScreen() for that check.

Implements PhosphorEngine::IPlacementEngine.

◆ stateForWindow() [1/2]

SnapState * PhosphorSnapEngine::SnapEngine::stateForWindow ( const QString &  windowId)

The SnapState that owns windowId (via the reverse map), or the global holder when the window is untracked — NEVER null (the holder is constructed in the ctor; see the fallback rationale on the definition).

An untracked window then reads empty per-window data out of the holder, which is observably identical to the nullptr this once returned. Never creates. Callers must not null-check the result as a tracked/untracked test; use isWindowTracked() for that.

◆ stateForWindow() [2/2]

const SnapState * PhosphorSnapEngine::SnapEngine::stateForWindow ( const QString &  windowId) const

◆ stateForWindowOnScreen()

SnapState * PhosphorSnapEngine::SnapEngine::stateForWindowOnScreen ( const QString &  windowId,
const QString &  screenId 
)

Resolve-or-register the owning state for windowId placed/acting on screenId, and return it.

On first placement it derives the key from the screen, lazily creates the state, and records the reverse-map entry; an already-tracked window keeps its existing owning state (its screen value is updated in place by the store call the caller makes). A screenless call resolves to the global holder. Public so the WTS facade routes its screen-carrying writes here.

◆ swapFocusedInDirection()

void PhosphorSnapEngine::SnapEngine::swapFocusedInDirection ( const QString &  direction,
const PhosphorEngine::NavigationContext ctx 
)
overridevirtual

Swap the focused window with whatever's in the adjacent zone in direction.

Empty direction is a no-op.

Implements PhosphorEngine::IPlacementEngine.

◆ switchFocusBetweenFloatingAndTiling()

void PhosphorSnapEngine::SnapEngine::switchFocusBetweenFloatingAndTiling ( const QString &  screenId)
overridevirtual

Jump focus between the float layer and the snapped layout (niri's switch-focus-between-floating-and-tiling).

Activates the last focused window on the OTHER layer, falling back to a scan when the memory is stale; windows the compositor has reported minimized are skipped (an unreported state is treated as visible — a focus verb must not refuse a window merely because its state is unknown). Whether the float layer holds focus is derived live from the navigation state provider's active window, not stored. Success reports reason "snapped"/"floating"; refusals report "no_target".

Reimplemented from PhosphorEngine::IPlacementEngine.

◆ toggleFocusedFloat()

void PhosphorSnapEngine::SnapEngine::toggleFocusedFloat ( const PhosphorEngine::NavigationContext ctx)
overridevirtual

Toggle the focused window between snapped and floating.

Implements PhosphorEngine::IPlacementEngine.

◆ toggleWindowFloat()

void PhosphorSnapEngine::SnapEngine::toggleWindowFloat ( const QString &  windowId,
const QString &  screenId 
)
overridevirtual

Toggle between managed and floating.

Implements PhosphorEngine::IPlacementEngine.

◆ uncommitSnap()

void PhosphorSnapEngine::SnapEngine::uncommitSnap ( const QString &  windowId)

◆ windowClosed()

void PhosphorSnapEngine::SnapEngine::windowClosed ( const QString &  windowId)
overridevirtual

A window was closed.

Implements PhosphorEngine::IPlacementEngine.

◆ windowFloatingClearedForSnap

void PhosphorSnapEngine::SnapEngine::windowFloatingClearedForSnap ( const QString &  windowId,
const QString &  screenId 
)
signal

Floating state cleared as part of a commit. WTA relays as windowFloatingChanged(id, false, screen).

◆ windowFocused()

void PhosphorSnapEngine::SnapEngine::windowFocused ( const QString &  windowId,
const QString &  screenId 
)
overridevirtual

A window gained focus (called when the compositor reports activation).

Named "focused" here because it's the engine's perspective; the D-Bus protocol and DaemonClient use "windowActivated" — same event.

Implements PhosphorEngine::IPlacementEngine.

◆ windowInZoneOnScreen()

QString PhosphorSnapEngine::SnapEngine::windowInZoneOnScreen ( const QString &  zoneId,
const QString &  screenId 
) const

The window snapped to zoneId on screenId (the daemon's stored assignment pins it to that output), or empty if the zone is unoccupied there.

Used by the cross-mode swap to find the snap partner when THIS engine is the swap target.

◆ windowOpened()

void PhosphorSnapEngine::SnapEngine::windowOpened ( const QString &  windowId,
const QString &  screenId,
int  minWidth,
int  minHeight 
)
overridevirtual

A new window appeared on this engine's screen.

Implements PhosphorEngine::IPlacementEngine.

◆ windowSnapStateChanged

void PhosphorSnapEngine::SnapEngine::windowSnapStateChanged ( const QString &  windowId,
const PhosphorProtocol::WindowStateEntry entry 
)
signal

Snap state changed (commit / uncommit). WTA relays to D-Bus windowStateChanged.

◆ zoneForWindow()

QString PhosphorSnapEngine::SnapEngine::zoneForWindow ( const QString &  windowId) const

Primary zone of windowId across the per-screen stores (empty if none).

Used by the cross-mode handoff to read a snap partner's slot.


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