fix(drm-extras): re-emit Connected event when modes change on already-connected connector#1923
Conversation
…-connected connector ConnectorScanner previously treated (Connected, Connected) as a no-op, only tracking state transitions between Connected/Disconnected/Unknown. This meant that a connector whose mode list changed while remaining Connected would not emit any event. This is problematic for USB-C docks with DP MST/alt-mode where the kernel may report a connector as Connected before EDID data is available. The initial scan sees an empty mode list and the compositor skips activation. When a later rescan finds modes populated, no Connected event is emitted because the state is still Connected. Now compare the old and new mode lists on (Connected, Connected) transitions and re-emit a Connected event when they differ. This allows compositors to activate outputs that initially had no modes without requiring custom retry logic.
|
Hi!
|
|
Hi! Thanks for the thoughtful review. 1. Verification: The initial investigation was LLM-assisted, but I've verified the mechanism against kernel DRM source and have a hardware reproducer (ThinkPad P16 Gen 3 + USB-C Dock Gen 2, DP alt-mode + MST hub). The relevant kernel codepath is
So what smithay sees via On my hardware, this manifests as intermittent monitor activation failure — niri's 2. Suppressing the first empty-modes Connected: I considered this, but
3. New The current PR overloads
Happy to revise the PR with a |
…ent variant Per maintainer review, introduce ConnectorScanEvent::Changed and DrmScanEvent::Changed to semantically distinguish mode-list updates on already-connected connectors from initial connection events. This gives compositors explicit control over how to handle EDID races and mode changes (e.g. video switchbox input change per Smithay#1859) without overloading Connected semantics. Changes: - Add Changed(connector::Info) to ConnectorScanEvent - Add Changed { connector, crtc } to DrmScanEvent - Add changed field to ConnectorScanResult and DrmScanResult - Simplify IntoIterator impls to Vec-based approach for 3-way chain - Update anvil and simple.rs examples with Changed arm
- Fix comment in connector_scanner.rs: 'Re-emit Connected' -> 'Emit Changed' to match the actual behavior after the Changed variant was introduced. - Add explanatory comment on the Changed arm in anvil/src/udev.rs per reviewer request, since anvil serves as reference for downstream compositors.
f08f79e to
a9e0555
Compare
Fixes #1922
Problem
ConnectorScannertreats(Connected, Connected)as a no-op, only tracking state transitions. When a connector's mode list changes while remainingConnected(e.g., EDID becomes available after initial probe returned empty modes), no event is emitted.This causes USB-C dock monitors with DP MST/alt-mode to get stuck in a permanent "connected but never activated" state when the kernel reports the connector as
Connectedbefore EDID data is ready.Fix
Add a new
Changedevent variant to bothConnectorScanEventandDrmScanEvent. When a connector staysConnectedbut its mode list differs from the previous scan, emitChangedinstead of silently ignoring it:The scanner logic:
This is better than re-emitting
Connected(original approach) because:ConnectedsemanticsContext
Discovered while debugging intermittent monitor activation failures on a ThinkPad P16 Gen 3 with USB-C Dock Gen 2 (DP alt-mode + MST). Verified against kernel DRM source (
drm_probe_helper.clines 598-653) —drm_helper_probe_detect()sets connector status before EDID/mode enumeration, so userspace can observeConnectedwith empty modes.Related: