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

Pure snap-mode navigation target resolver. More...

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

Public Types

using FeedbackFn = std::function< void(bool success, const QString &action, const QString &reason, const QString &sourceZoneId, const QString &targetZoneId, const QString &screenId)>
 Callback shape matching SnapEngine::navigationFeedback (and the WindowTrackingAdaptor signal it is ultimately relayed to).
 
using NeighbourTilingFn = std::function< bool(const QString &screenId)>
 Reports whether a neighbour OUTPUT is owned by a TILING engine — autotile or scrolling, i.e.
 

Public Member Functions

 SnapNavigationTargetResolver (PhosphorEngine::IWindowTrackingService *service, PhosphorZones::LayoutRegistry *layoutManager, IZoneAdjacencyResolver *zoneAdjacency, FeedbackFn feedback)
 Construct the resolver with its pure dependencies.
 
void setZoneAdjacencyResolver (IZoneAdjacencyResolver *resolver)
 Late setter for the zone adjacency resolver — it may not be available at construction time, so we allow nullptr and bind the pointer when it becomes available.
 
void setCrossSurfaceResolver (PhosphorEngine::ICrossSurfaceResolver *resolver)
 Late setter for the cross-surface resolver (neighbour output / desktop lookup).
 
void setNeighbourTilingProvider (NeighbourTilingFn fn)
 
PhosphorProtocol::MoveTargetResult getMoveTargetForWindow (const QString &windowId, const QString &direction, const QString &screenId)
 
SpanTargetResult getSpanTargetForWindow (const QString &windowId, const QString &direction, const QString &screenId)
 Compute the new zone span when the user grows/shrinks toward direction.
 
PhosphorProtocol::FocusTargetResult getFocusTargetForWindow (const QString &windowId, const QString &direction, const QString &screenId)
 
PhosphorProtocol::RestoreTargetResult getRestoreForWindow (const QString &windowId, const QString &screenId)
 
PhosphorProtocol::CycleTargetResult getCycleTargetForWindow (const QString &windowId, bool forward, const QString &screenId)
 
PhosphorProtocol::SwapTargetResult getSwapTargetForWindow (const QString &windowId, const QString &direction, const QString &screenId)
 
PhosphorProtocol::MoveTargetResult getPushTargetForWindow (const QString &windowId, const QString &screenId)
 
PhosphorProtocol::MoveTargetResult getSnapToZoneByNumberTarget (const QString &windowId, int zoneNumber, const QString &screenId)
 

Detailed Description

Pure snap-mode navigation target resolver.

Computes geometry targets for snap-mode keyboard navigation (move, focus, swap, push, snap-by-number, cycle, restore). Extracted from WindowTrackingAdaptor so that the adaptor's D-Bus surface no longer carries ~400 lines of snap-internal computation as member methods.

Separation of concerns:

  • This class is pure compute. It holds const* references to WindowTrackingService / PhosphorZones::LayoutRegistry / IZoneAdjacencyResolver and reads from them. It does not mutate their state.
  • It never touches D-Bus or Qt signals directly — navigation feedback (OSD data) is emitted through a std::function callback wired at construction time. In production the sole construction site is SnapEngine::ensureTargetResolver, which forwards the callback to SnapEngine::navigationFeedback (relayed onward via SnapAdaptor to WindowTrackingAdaptor::navigationFeedback).
  • Validation failures (empty windowId, empty direction) are considered pre-call contract violations and return an early noSnap-equivalent result; the adaptor's dispatcher is expected to catch these before they reach the resolver.

This class is deliberately not a QObject — it needs no signals of its own, and the absence of QObject machinery makes it trivially constructable for unit tests. The single dependency on Qt is the shared result-struct types (PhosphorProtocol::MoveTargetResult etc. from PhosphorProtocol/NavigationTypes.h).

All methods are intended to be called only for screens that the router (ScreenModeRouter) has confirmed are in Snapping mode. The resolver does not re-check mode — that's the dispatcher's job.

Member Typedef Documentation

◆ FeedbackFn

using PhosphorSnapEngine::SnapNavigationTargetResolver::FeedbackFn = std::function<void(bool success, const QString& action, const QString& reason, const QString& sourceZoneId, const QString& targetZoneId, const QString& screenId)>

Callback shape matching SnapEngine::navigationFeedback (and the WindowTrackingAdaptor signal it is ultimately relayed to).

Invoked by the resolver whenever a target computation succeeds or fails in a user-visible way. SnapEngine::ensureTargetResolver wires this to SnapEngine::navigationFeedback at construction time.

◆ NeighbourTilingFn

using PhosphorSnapEngine::SnapNavigationTargetResolver::NeighbourTilingFn = std::function<bool(const QString& screenId)>

Reports whether a neighbour OUTPUT is owned by a TILING engine — autotile or scrolling, i.e.

anything that is not Snapping — evaluated in the engine's current (desktop, activity) context, which the resolver itself lacks. When set, the MOVE and SWAP cross-output paths skip a tiling neighbour (deferring to the engine's cross-mode handoff) instead of snapping the window onto a tiled screen. May be empty, in which case no gating happens and every neighbour is treated as snap-mode (the pre-provider behaviour). The FOCUS cross-output path is never gated here, but landing still requires a snap-tracked occupant in the neighbour's entry zone (tiled windows are not in windowsInZone), so focus toward a tiling output collapses to no_adjacent_zone instead of crossing.

Constructor & Destructor Documentation

◆ SnapNavigationTargetResolver()

PhosphorSnapEngine::SnapNavigationTargetResolver::SnapNavigationTargetResolver ( PhosphorEngine::IWindowTrackingService service,
PhosphorZones::LayoutRegistry layoutManager,
IZoneAdjacencyResolver zoneAdjacency,
FeedbackFn  feedback 
)

Construct the resolver with its pure dependencies.

Parameters
servicewindow tracking state store (non-owning)
layoutManagerlayout / zone owner (non-owning)
zoneAdjacencytyped adjacency resolver (non-owning; may be nullptr)
feedbackOSD feedback callback; may be empty (suppresses feedback)

Member Function Documentation

◆ getCycleTargetForWindow()

PhosphorProtocol::CycleTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getCycleTargetForWindow ( const QString &  windowId,
bool  forward,
const QString &  screenId 
)

◆ getFocusTargetForWindow()

PhosphorProtocol::FocusTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getFocusTargetForWindow ( const QString &  windowId,
const QString &  direction,
const QString &  screenId 
)

◆ getMoveTargetForWindow()

PhosphorProtocol::MoveTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getMoveTargetForWindow ( const QString &  windowId,
const QString &  direction,
const QString &  screenId 
)

◆ getPushTargetForWindow()

PhosphorProtocol::MoveTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getPushTargetForWindow ( const QString &  windowId,
const QString &  screenId 
)

◆ getRestoreForWindow()

PhosphorProtocol::RestoreTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getRestoreForWindow ( const QString &  windowId,
const QString &  screenId 
)

◆ getSnapToZoneByNumberTarget()

PhosphorProtocol::MoveTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getSnapToZoneByNumberTarget ( const QString &  windowId,
int  zoneNumber,
const QString &  screenId 
)

◆ getSpanTargetForWindow()

SpanTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getSpanTargetForWindow ( const QString &  windowId,
const QString &  direction,
const QString &  screenId 
)

Compute the new zone span when the user grows/shrinks toward direction.

One shortcut quad drives both operations: when zone(s) exist beyond the span's direction edge, the span GROWS into them (the extension band sweeps up every zone between the old edge and the picked neighbour's far edge, so growing a full-height span into a column of stacked zones takes the whole column). When nothing lies that way, the span SHRINKS instead by dropping the member band on the opposite edge (pressing left after growing right undoes the grow). An unsnapped window snaps into the edge zone in direction, mirroring getMoveTargetForWindow. A single-zone span with nothing to grow into fails with "no_adjacent_zone".

Span never crosses outputs or desktops — a span is a set of zones on one screen's layout, so the boundary is a hard stop, not a handoff.

◆ getSwapTargetForWindow()

PhosphorProtocol::SwapTargetResult PhosphorSnapEngine::SnapNavigationTargetResolver::getSwapTargetForWindow ( const QString &  windowId,
const QString &  direction,
const QString &  screenId 
)

◆ setCrossSurfaceResolver()

void PhosphorSnapEngine::SnapNavigationTargetResolver::setCrossSurfaceResolver ( PhosphorEngine::ICrossSurfaceResolver resolver)

Late setter for the cross-surface resolver (neighbour output / desktop lookup).

When set, a navigation that finds no adjacent zone on the current output crosses to the entry zone of the adjacent output instead of failing. May be nullptr.

◆ setNeighbourTilingProvider()

void PhosphorSnapEngine::SnapNavigationTargetResolver::setNeighbourTilingProvider ( NeighbourTilingFn  fn)

◆ setZoneAdjacencyResolver()

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

Late setter for the zone adjacency resolver — it may not be available at construction time, so we allow nullptr and bind the pointer when it becomes available.


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