Skip to content

improve volume/mute handling and fix OSD/slider#1

Open
priceofcode wants to merge 1 commit intobase-revamp-volume-mute-osd-steps-r-11722390from
priceofcode/revamp-volume-mute-osd-step-r-11722390
Open

improve volume/mute handling and fix OSD/slider#1
priceofcode wants to merge 1 commit intobase-revamp-volume-mute-osd-steps-r-11722390from
priceofcode/revamp-volume-mute-osd-step-r-11722390

Conversation

@priceofcode
Copy link
Copy Markdown

@priceofcode priceofcode commented Feb 16, 2026

Note

Medium Risk
Changes core brightness/volume/mute control logic and DDC command sequencing, which may behave differently across monitor models and could regress OSD/slider synchronization.

Overview
Improves external display volume/mute handling by basing mute state on the DDC audioMuteScreenBlank value (with detection for monitors that don’t support the mute command) and by synchronizing mute/volume updates between media keys, sliders, saved prefs, and the on-screen display.

Refactors brightness/volume step calculations to better match macOS OSD “chiclet” behavior (including small-increment steps) and updates OSD rendering to use raw values/max values rather than derived step counts. DDC polling logic is centralized into Display.readDDCValues, and volume slider initialization now also polls mute state to show 0 when muted.

Written by Cursor Bugbot for commit 7a9264d. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

slider.integerValue = Int(currentValue)
slider.maxValue = Double(maxValue)
display.saveValue(Int(muteValues!.current), for: command)
display.saveMaxValue(Int(muteValues!.max), for: command)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Mute polling overwrites volume metadata

High Severity

When handling .audioSpeakerVolume, the mute polling result is saved using for: command instead of for: .audioMuteScreenBlank. This writes mute current/max into the volume keys, corrupting stored volume state and max range. Subsequent volume logic that reads getMaxValue(.audioSpeakerVolume) can behave incorrectly.

Fix in Cursor Fix in Web

if self.cmd == .audioSpeakerVolume, (self.display.isMuted() && value > 0) || (!self.display.isMuted() && value == 0) {
self.display.toggleMute(fromVolumeSlider: true)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unmute slider can restore wrong volume

Medium Severity

When the volume slider moves from muted to a non-zero value, toggleMute(fromVolumeSlider: true) restores the previously saved volume asynchronously, then the slider writes the new value separately. These two writes can race, so the final monitor volume may end up at the old restored value instead of the selected slider value.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

1 participant