Awake: Add "Keep awake when lid closed" option.#46408
Open
andrewleech wants to merge 1 commit intomicrosoft:mainfrom
Open
Awake: Add "Keep awake when lid closed" option.#46408andrewleech wants to merge 1 commit intomicrosoft:mainfrom
andrewleech wants to merge 1 commit intomicrosoft:mainfrom
Conversation
This comment has been minimized.
This comment has been minimized.
9da6c61 to
2728b11
Compare
This comment has been minimized.
This comment has been minimized.
Add a new toggle that prevents system sleep when the laptop lid is closed while Awake is active. Uses Windows PowerWriteACValueIndex/PowerWriteDCValueIndex APIs to temporarily override the lid close action to "Do nothing". - Add LidOverrideManager for thread-safe lid override with crash recovery - Add P/Invoke declarations for power management APIs - Add tray menu item (visible only on devices with lids) - Add Settings UI toggle with proper enable/disable states - Restore original lid settings when Awake is disabled or exits Signed-off-by: Andrew Leech <andrew@alelec.net>
2728b11 to
1e2524b
Compare
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Laptops running Awake in INDEFINITE or TIMED mode still go to sleep when the lid is closed, because Windows applies the power plan's lid close action regardless of
SetThreadExecutionState. This adds a toggle that overrides the lid close action to "Do nothing" in the active power scheme while Awake is in a non-passive mode. The toggle defaults to off, so existing behavior is unchanged for users who want sleep-on-close.The core of the change is
LidOverrideManager, a new static class that wraps the Win32PowerWriteACValueIndex/PowerWriteDCValueIndexAPIs to temporarily set the lid close action to "Do nothing" (for both AC and DC power), then restore the original values when the override is removed. It persists a JSON state file alongside the normal settings so that if Awake crashes or gets killed, the next launch detects the orphaned override and restores the original lid settings before doing anything else.stateDiagram-v2 [*] --> Passive Passive --> Active: Mode set to INDEFINITE/TIMED/EXPIRABLE<br/>+ keepAwakeOnLidClose=true Active --> Passive: Mode set to PASSIVE<br/>or timer expires Active --> Active: Power event (resume)<br/>→ reapply override Active --> CrashRecovery: Process killed CrashRecovery --> Passive: Next launch reads state file<br/>→ restores original values state Active { [*] --> OverrideApplied: WriteLidCloseAction(DoNothing) OverrideApplied --> OverrideRemoved: RestoreLidSettings() OverrideRemoved --> [*] }Key design decisions the diff won't immediately convey:
ApplyLidOverrideIfNeededrather than readingCurrentOperatingMode— the mode setters save settings and return before updating the static property, so the FileSystemWatcher can re-triggerProcessSettingswith a stale value.SetLidOverridemirrors the existingSetDisplaypattern — toggling the lid setting directly without saving first avoids restarting the countdown timer.SettingsUtilsbecause crash-recovery state has a delete-on-restore lifecycle that doesn't fit the settings framework.SystemPowerCapabilitiesP/Invoke since it runs in a separate process from the Awake module.Relates to #34479 (and the issues consolidated there: #16422, #41095, #35051, #13785, #13622, #34903).
Testing
powercfg /qthat the lid close action changes to 0 when enabled and restores to 1 (Sleep) when disabled.LidOverrideManager.Initializereturns early.AwakeSettings.Clone()to guard against future property omissions (reflection-based property list assertion).Trade-offs and Alternatives
The override modifies the system-wide power plan, not just the Awake process. This is unavoidable — there is no per-process lid close action API. The risk is mitigated by crash recovery and by restoring settings on every exit path.
An alternative would be registering for
WM_POWERBROADCAST/PBT_APMSUSPENDand callingSetSuspendState(FALSE)to cancel the suspend, but this is fragile (the cancel can be overridden by the kernel) and doesn't work for hibernate or shutdown lid actions.