Files
Codeman/docs
Codeman maintainer be8b96fa5d feat(desktop): keep a closed MacBook awake without the administrator password
Keep This Mac Awake > With the Lid Closed is a plain switch now. 1.50.1
installed a root LaunchDaemon behind the administrator prompt, which set
`pmset disablesleep` while the app asked for it. The app now turns off lid
sleep in the kernel's power management root itself
(`kPMSetClamshellSleepState`, a call any process may make), the method
LogoLight ships as Lit with Lid Closed.

That switch has no owner (read from Apple's sources of the kernel and of
powerd): the kernel keeps it after the process that set it has gone and
honours it on battery, macOS's power daemon and LogoLight write the same
bit, and clearing it under a closed lid puts the Mac to sleep at once. On an
Apple silicon Mac it is also what keeps a docked MacBook awake with its lid
closed, set by the power daemon once, when a display comes. So a child
process holds it (`src/lid_awake.rs`, this binary with `--keep-awake-lid`):

- it sets the switch again every second and holds two assertions with it
  (system sleep and idle sleep), the three LogoLight measured together;
- it reads the power source itself and holds nothing on battery;
- it writes nothing at all while an external display is connected: a zero
  from here would put a docked Mac to sleep, or leave it without its
  closed-lid mode until the display is plugged in again. What the child set
  before the display came is cleared once the display has been gone for
  five seconds, and the child outlives the app for that if it has to;
- it lets go when the pipe from the app closes (quit, crash, Force Quit) and
  when the app has not written for a minute (a hang), the assertions first,
  then the switch;
- it ignores SIGHUP, SIGINT and SIGTERM, so the pipe is its one way out;
- it leaves the switch alone at its end while LogoLight holds it for itself
  (LogoLight sets it once and would not notice it gone).

One child at a time holds a lock on `lid-awake` next to `desktop.json`, and
the file is non-empty while the switch may be set. A child that was killed
leaves it marked and unlocked: the app turns lid sleep back on when it sees a
child end and at its next launch, and the next child takes the mark over.

The status line says what came of it: the kernel took the call, the lid is
left to macOS at a display, on battery, refused, or that the Mac slept under
the lid all the same and until when. A display has its own wording so a Mac
that sleeps there never reads as covered.

The helper of 1.50.1 is no longer installed or used. Its request file is
never written and is deleted at launch, so a helper that is still there does
nothing. While it is installed the menu has Remove the Old Lid Helper…, the
one item left behind the administrator prompt. `macos/keep-awake-lid.sh` and
its vitest suite go with the install path.

Checked on a Mac mini (macOS 27.2, no lid, no display): 276 tests, clippy and
fmt; the kernel takes the call from an unprivileged process; the real child
holds its assertions, lets go on a closed pipe and after a minute of silence,
ignores SIGTERM, waits for a child before it, writes nothing when told a
display is connected, and a SIGKILLed child is replaced by the app and its
mark undone. 34 deliberate breaks of these rules each fail a test. Not run
yet: the app itself with this change (the mini has no session to open it
in), a real closed lid, the menu items, and the removal of the old helper.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 10:36:23 +01:00
..
2026-08-22 14:13:58 +02:00
2026-08-04 15:02:46 +02:00