GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — Preserve the brightness offset between displays while syncing by anandghegde · Pull Request #1906 · MonitorControl/MonitorControl Conversation
Contributor
Closes #1781. The problem
let newValue = max(0, min(1, targetDisplay.getBrightness() + delta)) Whatever part of the change did not fit was dropped. A display parked near the top of its range loses ground on every ambient light swing up, but gets the whole change back on the way down — so the displays creep together until the sliders are aligned, which is what the issue describes ("especially when the external monitor reaches its maximum brightness and then scales back — the brightness sliders often end up aligned"). The change
The anchor re-anchors itself whenever the display is no longer where the last sync left it — so a brightness the user sets by hand simply becomes the new relationship to keep, and no other code path has to know the anchor exists. The anchors are also dropped when the sync checkbox is toggled, since the user was free to move the displays apart while it was off. Two small side effects, both intentional:
Verification
Before, the offset decays to zero the first time the built-in reaches the top and never comes back. After, the external is still compressed while it sits at its own maximum (+0.10, +0.25 above) — nothing can be done about that, it has nowhere higher to go — but the full +0.40 is restored as soon as the built-in is back in range. The harness, if you want to re-run it// swiftc MonitorControl/Support/BrightnessSync.swift main.swift -o mc-sim && ./mc-sim import Foundation // The easing AppleDisplay.refreshBrightness() applies: each tick it moves a third of // the remaining way towards the real brightness and reports that much as the delta. func deltas(from: Float, to: Float) -> [Float] { var value = from var deltas: [Float] = [] while value != to { let next: Float if abs(to - value) < 0.01 { next = to } else if to > value { next = value + max((to - value) / 3, 0.005) } else { next = value + min((to - value) / 3, -0.005) } deltas.append(next - value) value = next } return deltas } // What AppDelegate.job() did before: add the delta and clamp to the usable range. func oldSync(current: Float, delta: Float) -> Float { max(0, min(1, current + delta)) } func f(_ value: Float) -> String { String(format: "%.2f", value) } func s(_ value: Float) -> String { String(format: "%+.2f", value) } let ambient: [Float] = [0.80, 0.50, 1.00, 0.35, 0.90, 0.45, 0.75, 0.50] var source: Float = 0.50 var old: Float = 0.90 var new: Float = 0.90 var anchor: Float? print("built-in \(f(source)), external \(f(new)), offset \(s(new - source))") print("") print("built-in external before external after offset before offset after") for level in ambient { for delta in deltas(from: source, to: level) { old = oldSync(current: old, delta: delta) let step = BrightnessSync.step(current: new, anchor: anchor, delta: delta) anchor = step.anchor new = step.value } source = level print(" \(f(source)) \(f(old)) \(f(new)) \(s(old - source)) \(s(new - source))") } print("") print("Then the user moves the external display to 0.60 by hand and the ambient light swings once more:") old = 0.60 new = 0.60 for level in [Float(0.90), Float(0.50)] { for delta in deltas(from: source, to: level) { old = oldSync(current: old, delta: delta) let step = BrightnessSync.step(current: new, anchor: anchor, delta: delta) anchor = step.anchor new = step.value } source = level } print("built-in \(f(source)), external \(f(new)), offset \(s(new - source)) - the new relationship is the one that is kept") What I could not verifyNo run on real hardware. This machine has no external display and no Apple Developer signing identity, so the build above needed
Worth a run on your setup before merging. Happy to adjust the tolerance, or to put the old behaviour back behind the checkbox if you would rather have it opt-in.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions…rControl#1781) Brightness sync added the reported delta to each display and clamped the result to 0...1, so whatever part of the change did not fit was dropped. A display parked near the top of its range therefore lost ground on every ambient light swing up but got the whole change back on the way down, and the displays crept together until the sliders were aligned. BrightnessSync keeps an unclamped anchor per display: the position the display would be at if it had no ends. The change is applied to the anchor and the display is driven to the clamped value, so the part that did not fit is given back on the way down instead of being lost. The anchor re-anchors itself whenever the display is no longer where the last sync left it, which is how a brightness the user set by hand becomes the new relationship to keep. Nothing else has to know about it. This branch has not been deployedNo deployments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ReviewersNo reviewsUh oh!
There was an error while loading. Please reload this page. AssigneesNo one assignedLabels
AI contribution / fork recommendation
ProjectsMilestoneNo milestoneDevelopmentSuccessfully merging this pull request may close these issues. Preserve the relative offsets so the actual perceived brightness remains consistent within different displayUh oh!
There was an error while loading. Please reload this page. 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. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |