Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
Phosphor::Screens::ScreenIdentity Namespace Reference

Stable cross-process screen identifier helpers. More...

Functions

PHOSPHORSCREENSCORE_EXPORT void reset ()
 Unconditionally drop every cache this namespace holds (local identifier caches AND the cross-process EDID serial cache).
 
PHOSPHORSCREENSCORE_EXPORT void invalidateEdidCache (const QString &connectorName=QString())
 Drop the QScreen-keyed identifier caches AND the underlying EDID-serial cache (cascades to PhosphorIdentity::ScreenId::invalidateEdidCache).
 
PHOSPHORSCREENSCORE_EXPORT void invalidateComputedIdentifiers ()
 Drop the computed-identifier and reverse-lookup caches without touching the EDID-serial cache.
 
PHOSPHORSCREENSCORE_EXPORT QString baseIdentifierFor (const QScreen *screen)
 Compute the EDID-based base ID for a QScreen*.
 
PHOSPHORSCREENSCORE_EXPORT QString identifierFor (const QScreen *screen)
 Compute the canonical identifier for a QScreen*.
 
PHOSPHORSCREENSCORE_EXPORT QScreen * findByIdOrName (const QString &identifier)
 Resolve an identifier (connector name OR EDID-style ID, with or without "/vs:N" virtual-screen suffix) to a QScreen*.
 
bool isConnectorName (const QString &identifier)
 True if the identifier looks like a connector name (no ':').
 
PHOSPHORSCREENSCORE_EXPORT QString idForName (const QString &connectorName)
 Convert a connector name to its current screen identifier.
 
PHOSPHORSCREENSCORE_EXPORT QString nameForId (const QString &screenId)
 Convert a screen identifier back to its current connector name.
 
QStringList variantsFor (const QString &screenIdOrName)
 Return every equivalent form of screenIdOrName.
 
PHOSPHORSCREENSCORE_EXPORT bool screensMatch (const QString &a, const QString &b)
 Tolerance-aware equality between two screen identifiers.
 
PHOSPHORSCREENSCORE_EXPORT bool belongsToPhysicalScreen (const QString &storedScreenId, const QString &physicalScreenId)
 Whether storedScreenId belongs to the physical screen physicalScreenId.
 

Detailed Description

Stable cross-process screen identifier helpers.

Owns the canonical "manufacturer:model:serial" wire format that PhosphorScreens uses to refer to a physical screen across processes (daemon, KCM, compositor plugin). Hidden behind the same opaque-ID convention as WindowId / VirtualScreenId in PhosphorIdentity: callers pass strings around; only this module knows the format.

Identifier shape:

  • "Manufacturer:Model:Serial" (preferred — full EDID identity)
  • "Manufacturer:Model" (fallback when serial is unavailable)
  • "Manufacturer:Model:Serial/CONNECTOR" (duplicate disambiguation)
  • connector name (e.g. "DP-2") (final fallback when EDID is empty)

Threading: process-local caches use unsynchronised statics; every function MUST be called from the GUI thread.

Process-global state: these helpers intentionally keep their identifier and reverse-lookup caches in function-local statics rather than on a per-ScreenManager object. EDID-to-identifier mapping is determined entirely by the set of connected QScreens (shared QGuiApplication state), so moving the caches onto individual managers would not decouple them — every instance would end up computing the same answers from the same inputs. The trade-off: hosts that run multiple ScreenManager instances (tests, future multi-session shells) share one cache, so invalidateEdidCache() on hotplug is a global side-effect. Document rather than isolate because isolation here buys nothing.

Function Documentation

◆ baseIdentifierFor()

PHOSPHORSCREENSCORE_EXPORT QString Phosphor::Screens::ScreenIdentity::baseIdentifierFor ( const QScreen *  screen)

Compute the EDID-based base ID for a QScreen*.

Identical-monitor disambiguation is NOT applied here (use identifierFor for that). Not cached at this level — the underlying EDID-serial sysfs read IS cached inside PhosphorIdentity::ScreenId::readEdidHeaderSerial, which is what dominates the cost; assembling the "manuf:model:serial" string from already-fetched QScreen fields is cheap enough that a second cache layer would trade memory for negligible speedup.

◆ belongsToPhysicalScreen()

PHOSPHORSCREENSCORE_EXPORT bool Phosphor::Screens::ScreenIdentity::belongsToPhysicalScreen ( const QString &  storedScreenId,
const QString &  physicalScreenId 
)

Whether storedScreenId belongs to the physical screen physicalScreenId.

Handles virtual screen IDs: if stored is virtual, extracts its physical parent and compares via screensMatch() so connector-name / EDID-ID equivalence is honored (e.g. "DP-2" vs "Dell:U2722D:115107"). If physicalScreenId is itself virtual, returns false (misuse — the function is "stored belongs to PHYSICAL X").

◆ findByIdOrName()

PHOSPHORSCREENSCORE_EXPORT QScreen * Phosphor::Screens::ScreenIdentity::findByIdOrName ( const QString &  identifier)

Resolve an identifier (connector name OR EDID-style ID, with or without "/vs:N" virtual-screen suffix) to a QScreen*.

Priority:

  1. Empty input → primary screen.
  2. Strip "/vs:N" suffix and resolve the physical parent.
  3. Connector name match (fast path).
  4. Reverse cache hit.
  5. Exact base-ID match against every connected screen.
  6. Disambiguated form ("Manuf:Model:Serial/CONNECTOR") match, verifying both the connector and the EDID base.
  7. Legacy: stored config has bare base ID but currently-connected monitors are duplicates — match the first by base ID.

Returns nullptr when no match is found (note: empty input still returns the primary screen).

◆ identifierFor()

PHOSPHORSCREENSCORE_EXPORT QString Phosphor::Screens::ScreenIdentity::identifierFor ( const QScreen *  screen)

Compute the canonical identifier for a QScreen*.

If another currently-connected screen produces the same base ID (identical monitors on different connectors), appends "/CONNECTOR" to disambiguate. Mirrors KWin's OutputConfigurationStore strategy: EDID primary, connector fallback.

◆ idForName()

PHOSPHORSCREENSCORE_EXPORT QString Phosphor::Screens::ScreenIdentity::idForName ( const QString &  connectorName)

Convert a connector name to its current screen identifier.

◆ invalidateComputedIdentifiers()

PHOSPHORSCREENSCORE_EXPORT void Phosphor::Screens::ScreenIdentity::invalidateComputedIdentifiers ( )

Drop the computed-identifier and reverse-lookup caches without touching the EDID-serial cache.

Call on QScreen add/remove: identifier disambiguation depends on the full set of connected screens (a "/CONNECTOR" suffix appears only when another screen produces the same base ID), so any topology change can promote a previously-bare ID to a disambiguated form or vice versa. Pruning by connector name (as invalidateEdidCache does) misses this: screen A's cache entry is keyed on its own connector, but the disambiguation of A's identifier depends on whether screen B exists — a delta to B alone leaves A's entry stale.

Distinct from invalidateEdidCache because the EDID serial is a hardware property of a specific connector (only changes on physical monitor swap), while disambiguation is a function of the screen set (changes on every add/remove regardless of hardware reuse).

◆ invalidateEdidCache()

PHOSPHORSCREENSCORE_EXPORT void Phosphor::Screens::ScreenIdentity::invalidateEdidCache ( const QString &  connectorName = QString())

Drop the QScreen-keyed identifier caches AND the underlying EDID-serial cache (cascades to PhosphorIdentity::ScreenId::invalidateEdidCache).

Call on monitor hotplug — the EDID changing means a different monitor is on this connector and every cached identifier referencing it must be rebuilt. Pass an empty string to drop everything.

◆ isConnectorName()

bool Phosphor::Screens::ScreenIdentity::isConnectorName ( const QString &  identifier)
inline

True if the identifier looks like a connector name (no ':').

◆ nameForId()

PHOSPHORSCREENSCORE_EXPORT QString Phosphor::Screens::ScreenIdentity::nameForId ( const QString &  screenId)

Convert a screen identifier back to its current connector name.

◆ reset()

PHOSPHORSCREENSCORE_EXPORT void Phosphor::Screens::ScreenIdentity::reset ( )

Unconditionally drop every cache this namespace holds (local identifier caches AND the cross-process EDID serial cache).

Test-isolation hook. Production callers almost always want invalidateEdidCache — this function exists so a test harness that recreates QGuiApplication within one process can wipe stale pointer- keyed entries before the next run populates them with addresses that happen to match a freed QScreen from a previous iteration.

◆ screensMatch()

PHOSPHORSCREENSCORE_EXPORT bool Phosphor::Screens::ScreenIdentity::screensMatch ( const QString &  a,
const QString &  b 
)

Tolerance-aware equality between two screen identifiers.

Returns true when both inputs resolve to the same QScreen*. Handles connector-name ↔ EDID-ID equivalence transparently. Virtual screen IDs are compared exactly; mixed virtual/physical inputs always compare false.

◆ variantsFor()

QStringList Phosphor::Screens::ScreenIdentity::variantsFor ( const QString &  screenIdOrName)
inline

Return every equivalent form of screenIdOrName.

Given a screen identifier in either connector-name (e.g. "DP-2") or resolved-id (e.g. "Dell:U2722D:115107") form, returns a list containing the input plus the alternate form when it resolves to a different string. The input is always the first element so callers can rely on its position when picking a canonical key form on write.

Returns an empty list when screenIdOrName is empty — callers iterating the result then run their loop body zero times, which is the correct "nothing to match" behavior for disable-list and lookup paths.

Used by callers that need to match a stored screen-keyed entry regardless of which form was originally written (settings disable-lists, persisted snap-state, etc.). Consolidates the connector ↔ id variant-build logic that would otherwise be duplicated across every such caller.