The Surface Dial can be paired through Bluetooth with macOS, but sends invalid inputs by default, resulting in the dial having no functionality. This app reads the raw data from the dial and translates it to various actions to act as a customizable input device.
Built as a native macOS app as to use as little resource consumption as possible, with easy customization from the menu bar. Every option in the app can additionally be scripted with both Shortcuts as well as AppleScript/JXA.
Supports macOS 10.13 (High Sierra) to macOS 26 (Tahoe)
The app will continuously try to open any Surface Dial connected to the computer and then process inpout controls. You will need to pair and connect the device as any other bluetooth device.
There are three mode types that you can select from:
- Rotation Mode: Allows for rotational feature control with the dial (eg: scrolling, volume/brightness control)
- Button Mode: Allows for pressed feature control with the dial (eg: media control, mouse click)
- Multi Mode: Allows for both rotational & pressed control to work together for a single feature (eg: color picker control)
![]() |
![]() |
![]() |
![]() |
tell application "MacDial"
set rotation mode scrolling
set wheel sensitivity custom
set custom sensitivity 500
set key scroll modifiers with shift and control without command and option
set haptics true
end tell(() => {
const MacDial = Application("MacDial");
MacDial.setRotationMode("scrolling");
MacDial.setWheelSensitivity("custom");
MacDial.setCustomSensitivity(500);
MacDial.setKeyScrollModifiers({
shift: true,
command: false,
option: false,
control: true
});
MacDial.setHaptics(true);
})()- https://github.com/andreasjhkarlsson/mac-dial - The original implementation of the Surface Dial on macOS
- https://github.com/bealex/mac-dial - Rewrite of the original project to make use of native IOKit APIs and an AppKit-based UI





