Skip to content

VCP and display topology fixes (from #513), plus opt-in live read - #517

Merged
mgth merged 2 commits into
masterfrom
vcp-topology-fixes
Jul 25, 2026
Merged

VCP and display topology fixes (from #513), plus opt-in live read#517
mgth merged 2 commits into
masterfrom
vcp-topology-fixes

Conversation

@mgth

@mgth mgth commented Jul 25, 2026

Copy link
Copy Markdown
Owner

First extraction from #513: the VCP/topology commit (2764856), reviewed fix by fix, cherry-picked with two adaptations, plus a follow-up commit restoring OSD monitoring as an explicit bounded mode.

From #513 (adapted)

  • dxva2 handle leak: VcpControl now disposes its IVcpTransport; the probe task is awaited before the transport goes away, and disposed controls are evicted from the cache.
  • Registry key name over-read: GetHKeyName copied 2× the buffer size (Marshal.Copy counts chars, the buffer counts bytes); replaced by a bounded decode in MonitorDeviceHelper, with a unit test. (The buggy original still lives in HLab.Core — tracked separately.)
  • Clone mode targeted the wrong panel: DxVa2VcpTransport picked _physicalMonitors[0] for every device sharing an HMONITOR; it now matches the physical monitor by description. When two identical descriptions make the choice ambiguous, VCP is disabled for that device rather than guessed — behavioral change to be aware of.
  • DDC polling loop: CommandWorker/MonitorLevel no longer re-enqueue forever; levels go quiet once converged. The hand-tuned slow-monitor behavior is preserved verbatim: read-before-write, convergence-based Moving, 10 retries / 100 ms backoff / auto-disable, latest-value coalescing. Closing one monitor's panel no longer kills the shared worker.
  • Topology application is transactional: WindowsDisplayController stages, commits, and rolls back via ResaveCurrentConfiguration instead of leaving the registry half-written when an AttachToDesktop fails mid-batch.
  • ActiveConnection replaces order-dependent Connections[0] lookups (also removes potential IndexOutOfRange).
  • Topology failures are no longer silent: SetPrimary/Attach/Detach/SetLocations failures show a dialog. Adapted from the PR version: OS-agnostic wording (the controller also targets Linux/kscreen) and Escape kept working (IsCancel moved to the visible OK button).

New: opt-in live read

The perpetual polling removed above was also what kept sliders in sync with changes made on the monitor's own OSD during white-balance sessions. That comes back as an explicit mode: a Live read toggle on the Image card re-reads every level once per second and auto-expires after two minutes, so an abandoned panel never polls the DDC bus forever. The _queued CAS guard coalesces ticks, so a slow bus cannot pile up requests. Interval/duration are constants on VcpControl (LiveReadInterval, LiveReadDuration).

Tested

  • DisplayLayout.Tests: 72/72 (includes new WindowsMonitorSafetyTests)
  • Plugin.Vcp.Avalonia.Tests: 60/60 (includes new VcpSafetyTests + 2 live-read tests, stable over 5 runs)
  • Full UI build on Linux

Needs testing on Windows

  • VCP sliders on a slow monitor: drag feel should be identical or slightly better (immediate wake instead of waiting for the polling pass)
  • Live read toggle: OSD changes appear within ~1 s, button unchecks itself after 2 min
  • Clone mode: right panel is driven; ambiguous twin monitors now show no VCP instead of driving panel 0
  • A failing attach/detach/make-primary shows the failure dialog and rolls back

🤖 Generated with Claude Code

MathieuARS and others added 2 commits July 25, 2026 10:01
Cherry-picked from #513 (2764856), with two adaptations to ShowFailureAsync:
OS-agnostic wording (the controller also targets Linux/kscreen), and Escape
kept working by moving IsCancel to the visible OK button since CancelButton
is hidden.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The event-driven CommandWorker (previous commit) removed the perpetual
polling that, as a side effect, kept the sliders in sync with changes made
on the monitor's own menu during white-balance sessions. Bring that back
as an explicit mode: a Live read toggle on the Image card re-reads every
level once per second, and expires after two minutes so an abandoned panel
never polls the DDC bus forever. The _queued guard in MonitorLevel
coalesces ticks, so a slow bus cannot pile up requests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mgth
mgth merged commit 44942e4 into master Jul 25, 2026
1 check passed
@mgth
mgth deleted the vcp-topology-fixes branch July 25, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants