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

One layer-shell surface with a managed lifecycle. More...

#include <phosphor-layer/include/PhosphorLayer/Surface.h>

Inheritance diagram for PhosphorLayer::Surface:
[legend]

Classes

class  CtorToken
 Opaque construction token — only SurfaceFactory can create instances of it. More...
 

Public Types

enum class  State {
  Constructed , Warming , Shown , Hidden ,
  Failed
}
 

Public Slots

Lifecycle

Idempotent and safe to call in any state.

Invalid transitions warn and no-op.

Declared as Q_SLOTS so consumers can wire QML-side signals (e.g. a dismissTimer's dismissRequested()) directly via the string-based QObject::connect(window, SIGNAL(foo()), surface, SLOT(hide())) syntax. QML-defined signals can't be addressed via Qt5 &Class::signal pointers, so the string form is the only path — without Q_SLOT registration the connect would silently fail at runtime.

void show ()
 
void hide ()
 
void warmUp ()
 Create engine + window + content, leave hidden.
 

Signals

void stateChanged (State newState)
 NOTIFY signal for the state Q_PROPERTY.
 
void failed (const QString &reason)
 Emitted once when transitioning to State::Failed.
 
void screenLost ()
 Emitted when the QScreen the Surface was attached to is removed from the IScreenProvider's list.
 

Public Member Functions

 ~Surface () override
 Q_ENUM so QMetaEnum can stringify State values in log messages (State::Failed → "Failed") and so Q_PROPERTY / QSignalSpy introspection works.
 
State state () const noexcept
 
const SurfaceConfigconfig () const noexcept
 
bool isLogicallyShown () const noexcept
 Convenience: is the Surface in the logical "shown" state?
 
Escape hatches

Prefer the declarative API.

These are for consumers that need to reach into Qt machinery (installing event filters, connecting to window-specific signals, etc.).

QQuickWindow * window () const noexcept
 
ITransportHandletransport () const noexcept
 

Protected Member Functions

 Surface (CtorToken, SurfaceConfig cfg, SurfaceDeps deps, QObject *parent)
 Protected so subclasses can forward a CtorToken through their own constructor.
 

Detailed Description

One layer-shell surface with a managed lifecycle.

Owns its QQuickWindow and (by default) its QQmlEngine. Constructed only via SurfaceFactory so injected dependencies can travel with it.

Lifecycle (state machine)

From Event To
Constructed warmUp() Warming
Constructed show() Warming
Warming (content ready, intent=warm) Hidden
Warming (content ready, intent=show) Shown
Warming (content error) Failed
Hidden show() Shown
Shown hide() Hidden
any (transport rejected) Failed

Invalid transitions (e.g. show() from Failed) log qCWarning with the debugName and no-op. They never throw.

Topology-driven respawn (screen removal / compositor restart) is the consumer's responsibility, not the library's: subscribe to TopologyCoordinator callbacks or use ScreenSurfaceRegistry::syncToScreens to decide when to destroy and rebuild surfaces. The library deliberately keeps Surface oblivious to the screen lifecycle so consumers retain full control over the save-state-before-destroy sequencing.

hide() is synchronous from the caller's perspective — the window is unmapped immediately. We do not expose a transient "Hiding" state because the compositor's acknowledgement is invisible to application code and the surface is unusable until it's either Shown again or recreated.

Member Enumeration Documentation

◆ State

enum class PhosphorLayer::Surface::State
strong
Enumerator
Constructed 

Config accepted; no window yet.

Warming 

Engine / window / content initialising.

Shown 

Layer surface attached; window visible.

Hidden 

Attached but window hidden — show() is cheap.

Failed 

Unrecoverable (content error, transport rejected, …)

Constructor & Destructor Documentation

◆ ~Surface()

PhosphorLayer::Surface::~Surface ( )
override

Q_ENUM so QMetaEnum can stringify State values in log messages (State::Failed → "Failed") and so Q_PROPERTY / QSignalSpy introspection works.

Not currently registered with QML — consumers that want to bind surface state from QML should register the type themselves via qmlRegisterUncreatableType<Surface>.

◆ Surface()

PhosphorLayer::Surface::Surface ( CtorToken  ,
SurfaceConfig  cfg,
SurfaceDeps  deps,
QObject *  parent 
)
protected

Protected so subclasses can forward a CtorToken through their own constructor.

Still unreachable to consumers — CtorToken is SurfaceFactory-only-constructible.

Member Function Documentation

◆ config()

const SurfaceConfig & PhosphorLayer::Surface::config ( ) const
noexcept

◆ failed

void PhosphorLayer::Surface::failed ( const QString &  reason)
signal

Emitted once when transitioning to State::Failed.

reason is a human-readable diagnostic (QML compile error, transport rejection, etc.). Surface remains in Failed thereafter.

Safe to delete the Surface from this slot

The library defers this signal via Qt::QueuedConnection so consumer slots that call delete surface do not re-enter library code on a dead this. For non-failure stateChanged emissions the consumer must prefer deleteLater() over delete.

◆ hide

void PhosphorLayer::Surface::hide ( )
slot

◆ isLogicallyShown()

bool PhosphorLayer::Surface::isLogicallyShown ( ) const
noexcept

Convenience: is the Surface in the logical "shown" state?

Equivalent to state() == State::Shown and exists to give consumers a single canonical answer to "is this overlay currently the user's view of itself" regardless of the underlying lifecycle.

Under SurfaceConfig::keepMappedOnHide=true, the QQuickWindow stays Qt-visible across logical hide/show cycles — window()->isVisible() is therefore NOT a reliable signal for "currently shown" because it stays true while the surface is logically Hidden under Qt::WindowTransparentForInput. This helper is the right answer for both lifecycles: keep-mapped surfaces consult Surface state (false during the transparent-for-input span); destroy-on-hide surfaces are simply gone from the consumer's tracking when hidden, so the call site never reaches isLogicallyShown() on a destroyed Surface.

◆ screenLost

void PhosphorLayer::Surface::screenLost ( )
signal

Emitted when the QScreen the Surface was attached to is removed from the IScreenProvider's list.

The Surface stays in its current state (Shown/Hidden); consumers decide whether to destroy+rebuild or wait for the screen to come back. m_config.screen is nulled inside the library so the next attach falls back to the provider's primary.

Safe to delete the Surface from this slot

The library defers this signal via Qt::QueuedConnection so consumer slots that call delete surface do not re-enter library code on a dead this. Deleting the Surface from a stateChanged slot for non-Failed transitions remains UB — prefer deleteLater() there.

◆ show

void PhosphorLayer::Surface::show ( )
slot

◆ state()

State PhosphorLayer::Surface::state ( ) const
noexcept

◆ stateChanged

void PhosphorLayer::Surface::stateChanged ( State  newState)
signal

NOTIFY signal for the state Q_PROPERTY.

Carries the new state so slots don't need a round-trip getter call. The previous state is not exposed — track it in your slot if you need it.

◆ transport()

ITransportHandle * PhosphorLayer::Surface::transport ( ) const
noexcept

◆ warmUp

void PhosphorLayer::Surface::warmUp ( )
slot

Create engine + window + content, leave hidden.

Pre-compiles QML so the first show() is latency-free.

◆ window()

QQuickWindow * PhosphorLayer::Surface::window ( ) const
noexcept

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