[PR #1892] Add brightness presets and a monitorcontrol:// URL scheme #1324

Open
opened 2026-10-02 22:09:48 -06:00 by gitea-mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/MonitorControl/MonitorControl/pull/1892
Author: @Erik5000
Created: 8/12/2026
Status: 🔄 Open

Base: main ← Head: feature/brightness-presets-and-url-scheme


📝 Commits (3)

  • 2c30f1c Add a shared brightness action layer
  • ae9090a Add the monitorcontrol:// URL scheme
  • dc7ee4c Add four brightness preset shortcuts

📊 Changes

28 files changed (+588 additions, -1 deletions)

View changed files

📝 MonitorControl.xcodeproj/project.pbxproj (+8 -0)
📝 MonitorControl/Enums/PrefKey.swift (+15 -0)
📝 MonitorControl/Extensions/KeyboardShortcuts+Extension.swift (+16 -0)
📝 MonitorControl/Info.plist (+13 -0)
📝 MonitorControl/Support/AppDelegate.swift (+4 -0)
➕ MonitorControl/Support/BrightnessActions.swift (+140 -0)
📝 MonitorControl/Support/KeyboardShortcutsManager.swift (+14 -1)
➕ MonitorControl/Support/URLSchemeHandler.swift (+80 -0)
📝 MonitorControl/UI/cs.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/de.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/en.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/es.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/fr.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/hi.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/hu.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/it.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/ja.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/ko.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/nl.lproj/Localizable.strings (+9 -0)
📝 MonitorControl/UI/pl.lproj/Localizable.strings (+9 -0)

...and 8 more files

📄 Description

What this adds

Two related things, in three commits that can be taken separately:

  1. Four brightness presets. Each has a percentage you set and a shortcut
    you record. A preset sets every display to that level.
  2. A monitorcontrol:// URL scheme, so a script or a launcher can do the
    same thing.
monitorcontrol://brightness/set?value=10&display=all
monitorcontrol://brightness/change?delta=-10

Both go through one small shared file, BrightnessActions.swift, so the two
entry points cannot drift apart.

Why

The most common request I could find in this repo is a key that dims every
screen when you leave the desk, and a key that puts them back: #1851, #1674,
#727, #795, #1224. Related asks for outside control: #682, #1515, #1620, #1858.

I understand the answer has been that MonitorControl stays simple, and that
BetterDisplay covers this. I still think this specific shape is small enough to
fit: it adds no new window, no new tab, and nothing changes for a user who
never records a preset shortcut.

Please close this if you disagree. I will keep using my fork and I will not
argue the point.

Design notes

  • Display.setBrightness already existed and already picks DDC, the Apple
    protocol, gamma, or the shade layer. Nothing in that path is touched.
  • The new action repeats the three side effects of stepBrightness: the OSD,
    the menu slider, and brightnessSyncSourceValue. The last one matters,
    because AppDelegate.job() compares against it and a stale value makes the
    sync push the difference to every other display.
  • A relative URL change does its arithmetic per display inside the app. A
    caller therefore never has to read the brightness first. Many monitors accept
    writes but return noise on reads.
  • Presets stay active whichever way the brightness keys are set. Most users
    keep the media keys, and a preset must still work for them.
  • The settings rows are built in code, not in the storyboard, to keep the new
    text in Localizable.strings only instead of 19 Main.strings files.
  • Any app can open a URL, so disableExternalControl switches the scheme off
    and a 1% floor stops a URL from making a screen fully black.
  • No change to the deployment target. App Intents would have needed macOS 13.

Testing

Built and run on macOS 26.5.2, Apple silicon, with 4 external displays
(3x LG UltraFine, 1x N27p) in clamshell mode. Two of those monitors accept DDC
writes but return noise on reads, which made them a useful test.

Checked: absolute set, relative change, all four displays reaching the target,
the OSD, the menu sliders, the brightness sync not fighting the change, the 1%
floor, the off switch, and malformed URLs (value=abc, value=999, unknown
action) being ignored without a crash.

The diff carries no SwiftFormat churn and no CFBundleVersion bumps.

Disclosure

This was written with AI assistance (Claude). You said on 2026-05-09 that you
do not review AI generated PRs, and asked to be told. So: this is one. I am not
asking you to make an exception. If the AI contribution / fork recommendation
label is the right home for it, that is completely fine, and the fork is at
https://github.com/Erik5000/MonitorControl for anyone who wants the feature.

Every line was read, built, and tested on real hardware before opening this.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/MonitorControl/MonitorControl/pull/1892 **Author:** [@Erik5000](https://github.com/Erik5000) **Created:** 8/12/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feature/brightness-presets-and-url-scheme` --- ### 📝 Commits (3) - [`2c30f1c`](https://github.com/MonitorControl/MonitorControl/commit/2c30f1c7b4116485b5043fe2a3a55b014eaa8cb0) Add a shared brightness action layer - [`ae9090a`](https://github.com/MonitorControl/MonitorControl/commit/ae9090abd86637110b444dc484aa3d66690e669c) Add the monitorcontrol:// URL scheme - [`dc7ee4c`](https://github.com/MonitorControl/MonitorControl/commit/dc7ee4c0f4f3d0dc664b456aaa5da7f1ac3cfcdb) Add four brightness preset shortcuts ### 📊 Changes **28 files changed** (+588 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `MonitorControl.xcodeproj/project.pbxproj` (+8 -0) 📝 `MonitorControl/Enums/PrefKey.swift` (+15 -0) 📝 `MonitorControl/Extensions/KeyboardShortcuts+Extension.swift` (+16 -0) 📝 `MonitorControl/Info.plist` (+13 -0) 📝 `MonitorControl/Support/AppDelegate.swift` (+4 -0) ➕ `MonitorControl/Support/BrightnessActions.swift` (+140 -0) 📝 `MonitorControl/Support/KeyboardShortcutsManager.swift` (+14 -1) ➕ `MonitorControl/Support/URLSchemeHandler.swift` (+80 -0) 📝 `MonitorControl/UI/cs.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/de.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/en.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/es.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/fr.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/hi.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/hu.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/it.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/ja.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/ko.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/nl.lproj/Localizable.strings` (+9 -0) 📝 `MonitorControl/UI/pl.lproj/Localizable.strings` (+9 -0) _...and 8 more files_ </details> ### 📄 Description ## What this adds Two related things, in three commits that can be taken separately: 1. **Four brightness presets.** Each has a percentage you set and a shortcut you record. A preset sets every display to that level. 2. **A `monitorcontrol://` URL scheme**, so a script or a launcher can do the same thing. ``` monitorcontrol://brightness/set?value=10&display=all monitorcontrol://brightness/change?delta=-10 ``` Both go through one small shared file, `BrightnessActions.swift`, so the two entry points cannot drift apart. ## Why The most common request I could find in this repo is a key that dims every screen when you leave the desk, and a key that puts them back: #1851, #1674, #727, #795, #1224. Related asks for outside control: #682, #1515, #1620, #1858. I understand the answer has been that MonitorControl stays simple, and that BetterDisplay covers this. I still think this specific shape is small enough to fit: it adds no new window, no new tab, and nothing changes for a user who never records a preset shortcut. **Please close this if you disagree.** I will keep using my fork and I will not argue the point. ## Design notes - `Display.setBrightness` already existed and already picks DDC, the Apple protocol, gamma, or the shade layer. Nothing in that path is touched. - The new action repeats the three side effects of `stepBrightness`: the OSD, the menu slider, and `brightnessSyncSourceValue`. The last one matters, because `AppDelegate.job()` compares against it and a stale value makes the sync push the difference to every other display. - A relative URL change does its arithmetic per display inside the app. A caller therefore never has to read the brightness first. Many monitors accept writes but return noise on reads. - Presets stay active whichever way the brightness keys are set. Most users keep the media keys, and a preset must still work for them. - The settings rows are built in code, not in the storyboard, to keep the new text in `Localizable.strings` only instead of 19 `Main.strings` files. - Any app can open a URL, so `disableExternalControl` switches the scheme off and a 1% floor stops a URL from making a screen fully black. - No change to the deployment target. App Intents would have needed macOS 13. ## Testing Built and run on macOS 26.5.2, Apple silicon, with 4 external displays (3x LG UltraFine, 1x N27p) in clamshell mode. Two of those monitors accept DDC writes but return noise on reads, which made them a useful test. Checked: absolute set, relative change, all four displays reaching the target, the OSD, the menu sliders, the brightness sync not fighting the change, the 1% floor, the off switch, and malformed URLs (`value=abc`, `value=999`, unknown action) being ignored without a crash. The diff carries no SwiftFormat churn and no `CFBundleVersion` bumps. ## Disclosure This was written with AI assistance (Claude). You said on 2026-05-09 that you do not review AI generated PRs, and asked to be told. So: this is one. I am not asking you to make an exception. If the `AI contribution / fork recommendation` label is the right home for it, that is completely fine, and the fork is at https://github.com/Erik5000/MonitorControl for anyone who wants the feature. Every line was read, built, and tested on real hardware before opening this. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
github-starred/MonitorControl#1324
No description provided.