Skip to content

Fix uneven fine scale brightness steps - #1898

Merged
waydabber merged 1 commit into
MonitorControl:mainfrom
anandghegde:fix-fine-scale-brightness-steps
Sep 15, 2026
Merged

waydabber merged 1 commit into
MonitorControl:mainfrom
anandghegde:fix-fine-scale-brightness-steps

Conversation

@anandghegde

Copy link
Copy Markdown
Contributor

Fixes #1759

Two small bugs that together cause the uneven steps described in the issue.

Built-in / software-dimmed displays (Display.calcNewBrightness)

The fine scale step is 1/64, but the snapping tolerance (delta) was taken from the coarse step (1/16 / 4 = 1/64). So with fine scale on, tolerance and step were the same size and there was no slack at all. Brightness read back from DisplayServices is often a tiny bit off the 1/64 grid (on my Mac, setting 2/64 reads back as 0.031250004), and whenever it lands just above a boundary the next press jumps two steps. The coarse scale already uses a quarter-step tolerance; this makes the fine scale do the same.

Simulating 64 presses with the read-back noise I measured:

  • before, fine up: 62 presses, 1,2,4,5,7,8,9,...; fine down: 55 presses, ...57,55,54,...
  • after: 64 presses both ways, every step 1/64

Coarse stepping is unchanged (16 steps either way).

DDC displays (OtherDisplay.convValueToDDC)

The value was converted to an integer by truncating. Fine scale adds 0.01 each press, and in Float 0.29 + 0.01 is 0.29999998, which becomes DDC 29 again. Stepping up from 0 with a max of 100, truncation gives: 4 sent twice, 15 skipped, 29 sent twice, and it tops out at 99. That's exactly the "repeated 4%, skipped 15, repeated 29" from the issue. Rounding gives 1..100 with no repeats or skips. It also means a value read from the display and written back now maps to the same DDC value.

This doesn't address the one-off "59 sets the monitor to 100%" from the issue; I couldn't reproduce that from the code path.

Testing

  • Builds with xcodebuild -scheme MonitorControl -configuration Debug (signing disabled).
  • SwiftFormat --lint and SwiftLint: no issues in the changed files.
  • There's no test target, so I checked both changes with small standalone Swift scripts that copy the old and new functions (results above). I don't have a DDC monitor here, so I haven't tested on real DDC hardware.

Implemented with Claude Code; I reviewed and tested the change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MA8JGs7pCoXFL2W6jEJ8sD

Built-in and software-dimmed displays: the fine scale step reused the
coarse step's snapping tolerance (1/64), which equals the fine step
itself, so a brightness read back as a hair above a 1/64 boundary made
the next key press jump two steps. Use a quarter of the actual step,
matching the coarse scale.

DDC displays: convValueToDDC truncated the float to an integer, so
values like 0.29999998 (0.29 + 0.01) were sent as 29 and the following
step skipped a value. Round instead.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01MA8JGs7pCoXFL2W6jEJ8sD
@waydabber

Copy link
Copy Markdown
Member

Thank you!

@waydabber
waydabber self-requested a review September 15, 2026 13:38

@waydabber waydabber left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is legitimate, the fix seems fine.

@waydabber
waydabber merged commit 5ce1a25 into MonitorControl:main Sep 15, 2026
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.

Inconsistent number of brightness steps for built-in display with fine scale enabled

2 participants