Problem
Monitors connected via USB-C dock (Lenovo ThinkPad USB-C Dock Gen 2) intermittently fail to activate on boot or dock reconnection. One or both external monitors stay dark permanently until the dock is re-plugged.
Root Cause
The failure is caused by a timing race between the kernel DRM subsystem and EDID firmware negotiation:
- USB-C dock DP alt-mode + MST link negotiation takes hundreds of milliseconds
- Kernel reports connector as
State::Connected before EDID is read → connector.modes() returns empty
pick_mode() returns None → connector_connected() skips activation with "no mode"
- Smithay's
ConnectorScanner treats (Connected, Connected) as a no-op — subsequent scans do not re-emit events for already-connected connectors even when modes become available
- The connector is stuck in a permanent dead state
Whether activation succeeds depends entirely on whether EDID is ready before the first scan completes, making the bug intermittent.
Upstream Root Cause
The underlying issue is in smithay's ConnectorScanner (smithay-drm-extras), which does not detect mode-list changes on already-connected connectors:
Workaround (implemented)
PR #3409 adds a bounded rescan timer in backend/tty.rs:
- After
device_changed() processes connectors, schedule_rescan_if_needed() checks for connected-but-unactivated connectors
- If found, schedules a 2-second delayed rescan (up to 3 retries)
- This gives the kernel time to complete EDID reads
This workaround is valuable even after the smithay fix lands, because it handles the case where no subsequent udev event fires at all.
Hardware
- Laptop: ThinkPad P16 Gen 3
- GPU: NVIDIA RTX PRO 4000 (nvidia-drm 590.48.01, kernel-open), Intel iGPU (i915)
- Dock: Lenovo ThinkPad USB-C Dock Gen 2
- Monitors: Two LEN S27q-10 (2560x1440@60Hz) — one HDMI, one DP MST
- Kernel: 6.19.0-rc8
Cross-Compositor Analysis
| Compositor |
EDID Race Handling |
| Mutter |
3-second debounce timer per connector + mode-change detection → full reload |
| wlroots |
No retry — accepts connected+empty-modes, relies on udev events |
| KWin |
isConnected() requires non-empty modes — connected+no-modes treated as disconnected; no retry |
| niri (with PR #3409) |
Bounded rescan timer: 3 retries × 2s delay |
Related
Problem
Monitors connected via USB-C dock (Lenovo ThinkPad USB-C Dock Gen 2) intermittently fail to activate on boot or dock reconnection. One or both external monitors stay dark permanently until the dock is re-plugged.
Root Cause
The failure is caused by a timing race between the kernel DRM subsystem and EDID firmware negotiation:
State::Connectedbefore EDID is read →connector.modes()returns emptypick_mode()returnsNone→connector_connected()skips activation with "no mode"ConnectorScannertreats(Connected, Connected)as a no-op — subsequent scans do not re-emit events for already-connected connectors even when modes become availableWhether activation succeeds depends entirely on whether EDID is ready before the first scan completes, making the bug intermittent.
Upstream Root Cause
The underlying issue is in smithay's
ConnectorScanner(smithay-drm-extras), which does not detect mode-list changes on already-connected connectors:Workaround (implemented)
PR #3409 adds a bounded rescan timer in
backend/tty.rs:device_changed()processes connectors,schedule_rescan_if_needed()checks for connected-but-unactivated connectorsThis workaround is valuable even after the smithay fix lands, because it handles the case where no subsequent udev event fires at all.
Hardware
Cross-Compositor Analysis
isConnected()requires non-empty modes — connected+no-modes treated as disconnected; no retryRelated