A tiny macOS background service that restarts the Touch Bar whenever you open your MacBook lid or wake it from sleep — fixing the common bug where the Touch Bar goes blank after the laptop has been closed (especially when undocking from an external display).
Tested on a MacBook Pro (M1, 2020) running macOS 15 (Sequoia).
A small launchd daemon runs a shell watcher that polls the lid state
(AppleClamshellState from the IORegistry) every few seconds. It triggers a
Touch Bar restart on two events:
- Lid opened while awake — e.g. clamshell mode with an external display,
detected as a
closed → opentransition. - Wake from sleep — closing the lid usually sleeps the Mac, which freezes the watcher process. A poll cycle that takes far longer than its interval is a reliable "just woke up" signal, with no extra dependencies.
On either trigger it runs killall TouchBarServer and killall ControlStrip,
and launchd immediately respawns them, so the Touch Bar reinitialises.
Because TouchBarServer runs as root, the watcher must run as a root
LaunchDaemon — hence the one-time sudo at install. After that it runs
automatically at every boot with no further prompts.
sudo bash install.shsudo bash uninstall.shThe watcher logs lid changes and resets to /var/log/touchbar-reset.log
(auto-trimmed to the newest 500 lines):
cat /var/log/touchbar-reset.logThe installer creates a touchbar-reset command (a symlink in
/usr/local/bin), so you can control the daemon from anywhere:
touchbar-reset --status
sudo touchbar-reset --onceWith no argument the script runs the watcher loop (how launchd starts it).
It also accepts:
| Flag | Action | Root? |
|---|---|---|
--once |
Reset the Touch Bar now and exit (manual "fix it now") | sudo |
--pause |
Stop resetting until --resume; the daemon stays loaded but idle (persists across reboot) |
sudo |
--resume |
Resume after a --pause |
sudo |
--status |
Show daemon state, pause state, current lid state, and the last log lines | no |
--uninstall |
Remove the daemon, script, logs, and pause marker | sudo |
--version, -v |
Print the version | no |
--help, -h |
Show usage | no |
Examples:
touchbar-reset --status
sudo touchbar-reset --pause
sudo touchbar-reset --resume
sudo touchbar-reset --once--pause works by creating a marker file (/usr/local/var/touchbar-reset.paused)
that the running daemon checks each cycle, so it takes effect within INTERVAL
seconds without unloading the service.
touchbar-reset --version # the version actually installed
./touchbar-reset.sh --version # the version in this repoThe installed version is also recorded in the startup line of
/var/log/touchbar-reset.log.
Edit the values at the top of touchbar-reset.sh, then re-run
sudo bash install.sh:
| Variable | Default | Meaning |
|---|---|---|
INTERVAL |
5 |
Seconds between lid-state checks |
WAKE_GAP |
12 |
A poll cycle longer than this means the Mac was asleep |
| File | Role |
|---|---|
touchbar-reset.sh |
The watcher loop (installed to /usr/local/bin) |
design.westerlund.touchbar-reset.plist |
LaunchDaemon definition (installed to /Library/LaunchDaemons) |
install.sh / uninstall.sh |
Install / remove the daemon |
MIT — see LICENSE.