Re-apply dimming as the reconfiguration shades come off, silence Option plus volume, and fix the panel's text sizing - #91
Merged
Conversation
…on plus volume, and fix the panel's text sizing The reconfiguration pass now re-evaluates HDR first and then resets gamma, removes every shade and re-applies the dim in one synchronous turn, so a software-dimmed display no longer flashes to full brightness while the per-display reads run. The volume feedback sound plays only when the key-down for that key was a volume step, so Option plus a volume key opens Sound settings in silence while a plain key at the limits still blips. The percent readout, its column and the hover caption are fixed at the sizes the system text styles resolved to, so the panel scales consistently: not at all, a trade recorded at the readout width until the panel has a bounded height.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #56: three of its four open items. The panel-height item stays open there.
What changed
Reconfiguration flashes. The reconfiguration handler used to reset gamma and remove every shade, then await two HDR reads per display before re-applying the dim, so a software-dimmed display sat at full brightness for the whole loop. The HDR pass now runs first, over a snapshot of the displays, and the gamma reset, the shade removal and the re-apply follow in one synchronous turn. The wholesale removal stays unconditional, because it is what keeps a shade from stranding when mirroring engages; it now runs a little later than before, and the mirroring coordinator's own teardown from the raw notification is what keeps that backstop timely. The engine-side re-apply records that it must stay free of suspension points for this to hold, and the tests pin the order: nothing awaits between the removal and the re-apply, the reads all precede the reset, and both displays are re-applied from one snapshot.
Hardware verification exposed two additional transitions. WindowServer could reset gamma before the topology debounce finished, and AppKit's automatic window animations could overlap the old and new shades. Direct SDR displays now get a bounded recovery window that reasserts only a recognized reset to the cached ColorSync baseline. It checks the full RGB curve, fresh HDR state, the display identity and reconfiguration generation, and stops on an unfamiliar curve or uncertain state. Repeated notifications cannot renew the deadline or write allowance, and a stopped owner cannot restart without a fresh brightness write. Recovery stays active through the HDR preparation, pauses immediately before the final reset and baseline recapture, and starts a fresh five-second settling watch after the final pass. A physical multi-display reconfiguration exposed an additional system reset about 3.6 seconds after that pass; regression tests now cover it. The first topology change after a completed pass starts its own bounded window, so a new reconnect cannot inherit an expired deadline. Later events in that burst retain the deadline and eight-write allowance. A raw CoreGraphics signal now queues recovery through the main run loop’s common modes, outside the callback, before the delayed AppKit notification. Dimming windows also disable AppKit's automatic show/hide animations; OLED care retains its intentional entry fade.
Option plus a volume key. The feedback sound now plays only when the preceding key-down for that key routed to a volume step. Option plus a volume key opens Sound settings and stays silent; a plain volume key at maximum or minimum still plays, because the latch tracks the step, not whether the value changed. This is a deliberate departure from the behaviour inherited from the earlier code base, which played the sound on every volume key release. The key router and its tests are untouched.
Text size in the panel. Three elements scaled with the system text size while the two dozen around them did not: the percent readout, its column width, and the hover caption. All three are now fixed, at the sizes the system text style resolved to on this machine, so the panel is internally consistent and the readout column still fits "100%" with headroom. This makes the panel fully non-scaling, which is an accessibility trade made on purpose rather than by accident: real scaling of the whole panel is a larger job and is gated on the panel-height work. A render test proves the readout still fits its column at the fixed size; the render pipeline ignores the dynamic type setting on macOS, so the large-text behaviour itself is a hardware step.
Not in this change
Hardware verification
Verified locally on signed Release builds with the Dell U2725QE and MSI MAG 341C OLED connected.
Transfer-table sampling does not establish zero physical flash duration. Earlier traces exposed expired recovery budgets and a newer dimming write superseding the recovery snapshot. Those cases, including the first change after startup, now have failing-then-passing regression tests. A handoff obtains fresh HDR observations and retains the existing deadline and write allowance. The last small refinements were checked with automated regressions rather than another round of manual cable swaps.
Validation: 2,591 engine tests and 714 app tests passed on this branch. The final combined build passed 2,632 engine tests and 762 app tests, plus the Release marker gate. Developer ID signing was verified on the installed test builds. Independent reviews found no actionable issues, and all required CI checks passed on a4f284c.