Note:
Before bug reporting, please make sure you have tried the latest (alpha) version of BetterTouchTool and that you have already tried to restart your system :-). If you encounter a crash, please attach a crash log from the macOS Console.app's "Crash Reports" section.
Describe the bug
A clear and concise description of what the bug is. Any bug reports that contain insults against me or my software will be deleted without warning and the user will be blocked (unfortunately this has become necessary to mention here).
This took me a few days of experimentation with AI assistance to narrow this down.
Apparently when iCloud Sync is turned on, it prevents the Mac from sleeping due to synthetic HID events being fired periodically.
Affected input device (e.g. MacBook Trackpad, Magic Mouse/Trackpad, Touch Bar, etc.):
N/A. It happens if the 'Enable iCloud Sync' is turned on.
Screenshots
If applicable, add screenshots to help explain your problem. (You can just paste or drag them here)
Device information:
- Type of Mac: M1 Mac Studio Max
- macOS version: 26.6.1
- BetterTouchTool version: (please post the exact version - not just "the latest one"): 6.698, 6.703, 6.710, 6.721, 6.723
Additional information (e.g. crash logs, related issues, etc.):
Attaching a markdown file of the report generated by Claude on what is being caught. There is a synthetic HID event that is being fired at a regular interval when BTT with iCloud Sync is turned on.
iCloud settings sync posts a synthetic HID event on every cycle, preventing macOS idle sleep
Environment: macOS 26.6.1 (25G76), Apple M1 Max.
Reproduced across 6.698, 6.703, 6.710, 6.721 and 6.723 alpha (build 2026081202).
Summary
Every iCloud settings sync coincides with a synthetic HID event attributed to
BetterTouchTool. Each one resets the system idle timer, so the display never
reaches its sleep threshold and the machine never idle-sleeps.
The events
They arrive on the legacy NX event path, not the normal driver path. From the
UserIsActive tickle assertion label:
BetterTouchTool:
com.apple.iohideventsystem.queue.tickle.nxevent
service:IOHIDSystem pid:<btt> process:BetterTouchTool
real keyboard:
com.apple.iohideventsystem.queue.tickle
service:AppleUserHIDEventService product:Voyager eventType:3
real trackpad:
com.apple.iohideventsystem.queue.tickle
service:AppleMultitouchDevice product:<trackpad> eventType:11
The .nxevent suffix and service:IOHIDSystem indicate a userspace process
posting through the legacy IOHIDSystem interface (i.e. IOHIDPostEvent or
equivalent), attributed to BTT's pid. Real devices are attributed to a hardware
product: and carry an eventType:; the BTT variant carries neither, so the
event type itself is not visible from outside.
What is not determinable externally is the call site — whether the sync path
posts an event deliberately, or whether it is incidental to something else on
that path (a cursor query, a menubar refresh) that routes through the legacy
API. That should be quick to identify from the source.
Period tracks the sync interval, and changed between versions
The tickle period is not a fixed keepalive interval — it tracks whatever the
sync scheduler is doing in that build, and has changed twice:
| BTT version | Tickle period |
|---|---|
| 6.698 / 6.703 | ~96–101 s |
| 6.710 / 6.721 | ~178 s |
| 6.723 alpha | ~105 s |
Correlation evidence
A 35-minute idle run on 6.723 alpha, logging sync completions and idle-timer
tickles into one stream: 20 syncs, 20 synthetic tickles, 20/20 paired within
0–3 seconds. No unpaired sync, no unpaired tickle, and zero real input for the
whole window.
21:52:03 SYNC + TICKLE
21:53:51 SYNC + TICKLE
21:55:35 SYNC + TICKLE
… 20 consecutive pairs …
22:25:32 SYNC + TICKLE
During that run HIDIdleTime never exceeded ~105 s despite 35 minutes of no
user input, and the display never reached its 10-minute sleep threshold.
An earlier run on 6.710 gave the same result at the slower period (4/4 within
2 s).
Disabling sync resolves it completely
With BTTiCloudSyncEnabled = 0 and everything else left on:
- 0 synthetic events in a 2 h 20 min run, and again in a 39 min run
HIDIdleTimereached 2282 s uninterrupted (previously never exceeded ~180 s)- display slept 10 m 11 s after last input, exactly on schedule
- machine idle-slept and stayed asleep ~20 hours
Ruled out
Each measured on an idle machine with sync still enabled: all user triggers,
script widgets at every refresh interval including 0, the Now Playing widget,
all plugins, the launcher, the HTTP server, BTT Remote, and three version
upgrades. The behaviour is independent of user configuration.
Impact
Any user with iCloud settings sync enabled — the default — silently loses
display and system sleep. There is no visible indication BTT is the cause:
pmset -g assertions shows no BTT power assertion, because the idle timer is
being reset rather than held. Every normal diagnostic therefore points
elsewhere.
Suggested fix
The sync cycle should not post HID events. If something on that path needs to
signal activity, a power assertion would be visible in pmset -g assertions and
would respect the user's power settings; a synthetic HID event is
indistinguishable from real input and defeats them.
Reproducing
- Enable iCloud settings sync. Leave the machine completely idle — any real
input masks the synthetic events, since the tickle assertion records only the
most recent source. - Watch
pmset -g assertions | grep -i tickleand note the assertion age
resetting on a fixed period withprocess:BetterTouchToolas the source. - Sample
defaults read com.hegenberg.BetterTouchTool BTTLastSyncDate
alongside it — the timestamps advance in lockstep with the tickles. This
measurement does not require an idle machine. - Set
BTTiCloudSyncEnabled = 0. The tickles stop immediately and the display
sleeps on schedule.