Control Integration and Events
Control Integration connects BetterDisplay's display controls to equipment or software that accepts scripts, URLs or macOS distributed notifications. A volume slider can adjust a receiver instead of the display's speakers, while an event action can ask a service to prepare the same receiver after the Mac wakes.
Add integration to a display
Open Settings > Displays > [display] > Device Control > Add or Remove Controllers… and add Control Integration. Use Configure Integration Controls… for ranged, Boolean and command controls, and Configure Events… for connection and sleep/wake actions. The display must be connected to open the configuration.
The Control Integration settings article is the complete illustrated reference. It covers assigning a predefined control, creating custom controls, selecting the action, formatting values, startup restoration and readback. Device Control explains controller precedence when more than one controller offers the same feature.
Choose how an action reaches the device
- Run shell script calls a local tool. This is useful when a device already has a command-line client, or when you need to transform data or send an HTTP request with options beyond a simple GET. The editor says Shell script (zsh), but the current execution path invokes Bash; use syntax supported by that execution environment and explicit paths for external tools.
- Invoke URL sends an HTTP/HTTPS GET or opens another registered URL scheme. Use it for a service with a suitable GET endpoint or an app that accepts URL commands.
- Notification dispatch posts a named macOS distributed notification with a string payload. A cooperating app must listen for that name and interpret the payload; this is not a user-facing notification banner.
For example, an AV receiver with a documented network volume endpoint can supply the display's Volume control. Choose its appropriate numeric range and map the outgoing value to the receiver's expected units. Configure Mute separately as a Boolean control with different on/off actions. Brightness, volume and additional controls then use their normal BetterDisplay entry points, subject to controller assignment and keyboard targeting.
Some devices also have built-in Network Controllers. Check those before writing a custom integration: they can provide device discovery, authentication and device-specific behavior without a script.
Reuse connection details and insert values
Shared parameters let you store a hostname or other repeated text once for a display. Add a parameter with a distinct, nonempty Identifier and Content, then refer to it using [*:Identifier:*]. Identifiers are case-sensitive. Reserve VALUE for the ranged-control value supplied by BetterDisplay.
For a service of your own that accepts /volume?level=…, an outgoing URL might look like this:
http://[*:Host:*]/volume?level=[*:VALUE:*]
This illustrates the substitution syntax, not a universal receiver API. Replace the path and query with the endpoint your device actually documents. The Value multiplier, value format and rounding choices determine the text inserted for VALUE. For example, a multiplier of 100 can translate a normalized 0–1 value to a device's 0–100 scale.
Substitution is literal. BetterDisplay does not automatically shell-quote or URL-encode the inserted text. The notification name is literal too; expansion belongs in its payload. Refer to Reusable parameters for the full rules.
Keep sliders and toggles synchronized
Writing a value and reading it back are separate actions. For a script or URL control, enable Define action to get/pull data, enter the readback action and, if needed, enable Periodically read and update current value from device. This lets the BetterDisplay slider follow changes made with a receiver's own remote.
A ranged readback extracts a number from the returned text and divides it by the Value multiplier. A Return value regex can select the intended field when the response includes other numbers. Boolean controls compare the response with configured ON/OFF content, optionally using regular expressions. Account for whitespace and trailing newlines when using exact matches.
Periodic reading defaults to off. Its default interval is 5 seconds, adjustable from 0.5 to 3600 seconds. Turn periodic reading off before hiding the readback fields; hiding them does not clear the saved actions or stop an already enabled polling preference. Startup policies can also read or write values. The readback reference explains these interactions and safe-mode behavior.
An external tool that already knows a value can use CLI feed to update a control's stored value without sending the control's set action back to the device. See Custom controls for examples.
Respond to connection and power events
Event Integration offers seven hooks:
| Event | When to use it |
|---|---|
| Soft disconnect | After BetterDisplay's disconnect attempt. |
| Soft reconnect | Before BetterDisplay attempts reconnection, after early safety checks. |
| Hard disconnect | When an active display becomes a remembered display. |
| Hard reconnect | When a remembered display is rediscovered and its controllers are set up. |
| System sleep | When the app handles system sleep for connected displays. |
| System wake (immediate) | During the first wake pass, before the configured wake delay. |
| System wake | During the later pass after the app's wake delay. |
A new event starts at Do nothing. Keep that selection while preparing its payload, then choose its script, URL or notification action. Edits save immediately. Set an existing event back to Do nothing to pause it, or remove it to delete its definition.
Event payloads can insert [*:EVENT_HOOK:*], [*:DEVICE_NAME:*], [*:DEVICE_DESCRIPTION:*] and [*:DISPLAY_ID:*], alongside shared parameters. For a logging endpoint of your own, a URL such as http://localhost:8080/event?hook=[*:EVENT_HOOK:*]&display=[*:DISPLAY_ID:*] distinguishes the event and current display ID. Event actions have no ranged VALUE substitution and do not return a control value.
A soft operation can also cause a later hard-state event. Wake actions are asynchronous and do not guarantee that the display, network or earlier action is ready. The default redundancy interval is 1 second and can suppress identical payloads across controls and events of the same action type. Including the event hook in the payload helps distinguish requests. A timeout does not undo work already performed.
Follow the desk reconnect tutorial to prepare one paused event, test its explicitly targeted script and restore the trial setup afterward.
Additional information
This section explains licensing and platform requirements.
Features requiring Pro license
Custom-control integration definitions and the additional integration controls in the app menu require Pro. Predefined display controls can be configured without Pro, and the event editor has no separate Pro requirement. See the linked settings articles for the distinction between configuration and app-menu availability.
Platform compatibility
These integration methods are available on both Apple silicon and Intel Macs. The associated display must be connected for configuration, and the receiving device, script or app must support the requested action.