Repository navigation
Lid: a timer, heat or battery end with the lid closed puts the Mac to sleep - #61
shikhar1729 wants to merge 6 commits into
Conversation
macOS asks for a closed lid's sleep once, at the close, and disablesleep 1 refuses it. disablesleep 0 does not make it ask again, so a Mac ended for heat or a dying battery kept running in the bag until the lid opened. Claude-Session: https://claude.ai/code/session_01Jco1ESE6NxipTXFsZE31rZ
After a failed disablesleep 0, macOS refuses the request, and the recovery agent that later restores sleep does not ask. A refused request now asks again every 30 s while the lid stays closed and no session starts. Also tests an end that cannot remove session.json and a quit during an end. Claude-Session: https://claude.ai/code/session_01Jco1ESE6NxipTXFsZE31rZ
main's README is now short (krishhgg#65) and its lid-close detail lives in docs/lid-close.md, so this PR's sentence about a battery or heat end with the lid closed moves there. The README's battery and heat paragraph gets one short line saying the Mac goes to sleep. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Fixes the three review findings on the retry. The sleep is now owed from the floor end, not tied to one end's reason, so a quit that replaces the pending end no longer drops it. It is asked only with no session, no lifecycle operation queued or running, and no live sudo pmset, so it never lands inside a queued start. A start clears it only once it holds the lock, so a start refused for a busy lock keeps it. Claude-Session: https://claude.ai/code/session_01Jco1ESE6NxipTXFsZE31rZ
…losed lid Apple silicon throttles before it reaches critical, so a Mac that cannot shed its heat, in a bag say, can stay serious for hours with Low Power Mode on, and the session never ends. A serious stretch that lasts seriousThermalLimit now ends it with the new reason thermalSustained, which is one of the floor-rule ends that put a closed Mac to sleep (krishhgg#61): without that sleep the end would switch Low Power Mode off and unfreeze the apps of a Mac still running in the bag. The limit is 15 minutes by default, also for a config.json without the key, and Settings has "End after serious heat for" in 5-minute steps from Off to 60; a hand-edited value outside that range is clamped at load. The stretch is timed from the first floor run that reads it, and any reading below serious breaks it. The thermal state sends no event while it stays serious, so the driver reports after each run when the stretch reaches the limit and AppServices runs the floors once more then. Once it has, no new wait is owed: a refused end is retried by the manager, not every second.
…losed lid Apple silicon throttles before it reaches critical, so a Mac that cannot shed its heat, in a bag say, can stay serious for hours with Low Power Mode on, and the session never ends. A serious stretch that lasts seriousThermalLimit now ends it with the new reason thermalSustained, which is one of the floor-rule ends that put a closed Mac to sleep (krishhgg#61): without that sleep the end would switch Low Power Mode off and unfreeze the apps of a Mac still running in the bag. The limit is 15 minutes by default, also for a config.json without the key, and Settings has "End after serious heat for" in 5-minute steps from Off to 60; a hand-edited value outside that range is clamped at load. The stretch is timed from the first floor run that reads it, and any reading below serious breaks it. The thermal state sends no event while it stays serious, so the driver reports after each run when the stretch reaches the limit and AppServices runs the floors once more then. Once it has, no new wait is owed: a refused end is retried by the manager, not every second.
|
#94 reports the same thing after a timer end: the session ended on its timer with the lid closed, For context, #81 (a draft on top of this one) adds |
…uit waits for it A timer end with the lid closed left the Mac awake for hours when another app held off idle sleep (krishhgg#94). A quit whose disablesleep 0 failed again exited and dropped the owed sleep, which only the app asks for. Claude-Session: https://claude.ai/code/session_01Jco1ESE6NxipTXFsZE31rZ
|
@aldikosh23 Agreed, thanks. d0b7a1c adds This covers #94 while the app runs. A session that the recovery agent ends after a crash still has the gap. That needs a change to |
… the lid closed puts the Mac to sleep
|
Thanks for this. Three things before it can merge: merge main, fix three cases where the owed sleep goes wrong, and then a test report from your MacBook. 1. Merge mainThe branch now conflicts with 2. Three fixesA sleep that is never granted blocks quitting forever. Say the sudoers rule goes away during a session. The end can't restore sleep, so every sleep request fails, even with the recovery agent loaded. With the lid closed, Cleanup retries ask for sleep again. Launch recovery skips the sleep for an expired timer. 3. A test report from your MacBookCI covers the logic. This report covers a real lid close, which needs a MacBook. Run it after the fixes, with no external display connected.
For each check, post the Build and what to post
Post the results as a comment on this PR. Put long logs in a gist and link it. If you push another commit, the report needs to be redone at the new head. |
|
@shikhar1729 thanks for this fix. #94 is what's stopping me from using Insomnia, so I'd like to see this merged. Are you planning to make the three changes from the 18 Oct review? If you're short on time, I'm happy to take them on in a branch built on your commits, with credit to you, and run the real-Mac checks on my MacBook. |
|
Go ahead, take it over. Thanks! |
|
@shikhar1729 thanks again for this. I've opened #138 from your branch: your commits are as they were, with main merged and the three fixes from the review on top. I'll post the MacBook report there. |
Problem
macOS asks for a closed lid's sleep once, when the lid closes. During a session,
disablesleep 1refuses it.disablesleep 0does not make macOS ask again (xnuIOPMrootDomain.cpp,kPowerEventUserDisabledSleep). So a Mac whose session ends with the lid closed keeps running until the lid opens, or until idle sleep, which another app's assertion can hold off for hours (#94).Fix
After a timer or floor-rule end (
timer,thermalCritical,batteryFloor,batteryUnreadable), if the lid is closed andAppleClamshellCausesSleepis true, Insomnia callsIOPMSleepSystem.sudo pmset.Tests
ClosedLidSleepTests, including a failed restore, a quit that fails again, a session.json that cannot be removed, a quit during an end, and a start queued behind or refused during one.swift build -c release -Xswiftc -warnings-as-errorspasses.docs/releasing.md.https://claude.ai/code/session_01Jco1ESE6NxipTXFsZE31rZ


Confidence Score: 5/5
The PR appears safe to merge; the previous quit issue is fixed and no new actionable issue was found.Summary
Insomnia requests sleep when a timer, battery rule, or heat rule ends a session with the lid closed, unless macOS keeps the closed Mac awake.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Timer or floor rule ends session] --> B[Restore saved changes] B --> C{Sleep still owed?} C -->|No| D[Done] C -->|Yes| E{Session or other work active?} E -->|Yes| F[Check again in 30 seconds] E -->|No| G{Closed lid should sleep?} G -->|No| H[Drop owed sleep] G -->|Yes| I[Ask macOS to sleep] I -->|Refused| F I -->|Accepted| H F --> CReviews (7) · Last reviewed commit: "Lid: a timer end with the lid closed put..." · Reviewed by Greptile