Skip to content

[Awake] Detect locked screen and allow screen off - #49388

Merged
Yu Leng (moooyo) merged 4 commits into
microsoft:mainfrom
Meister1977:detect-screen-lock-in-awake
Sep 7, 2026
Merged

Yu Leng (moooyo) merged 4 commits into
microsoft:mainfrom
Meister1977:detect-screen-lock-in-awake

Conversation

@Meister1977

@Meister1977 AmbrÃģzy Lőrinc (Meister1977) commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

PR Checklist

  • Communication: I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected
  • [N/A] Tests: Added/updated and all pass
  • [N/A] Localization: All end-user-facing strings can be localized
  • [N/A] Dev docs: Added/updated
  • [N/A] New binaries: Added on the required places
  • [N/A] Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

This change updates Awake’s handling of the workstation lock state so that it behaves more closely to the documented behavior. Previously, Awake would continue to request the display to remain on even when the session was locked, which prevented Windows from turning the display off and entering normal power-saving behavior. The change introduces logic to detect whether the workstation is currently locked and to reapply the awake state accordingly when the session state changes.
In practice, the implementation:
1. Detect the current lock state on startup
Awake now checks whether the workstation is already locked when it starts. This ensures that the initial state is correct even if the session was already locked before Awake was launched.
2. React to lock and unlock transitions
The implementation listens for session switch events and updates the internal lock state whenever the user locks or unlocks the workstation. This allows Awake to respond to changes in session state in real time.
3. Re-apply the awake state when the lock state changes
When the lock state changes, Awake re-applies the active awake mode so that the display is not forced on while the screen is locked. The update is coordinated through the existing shared state logic to avoid race conditions between mode changes and session events.
4. Preserve existing behavior when unlocked
When the session is unlocked, Awake continues to behave as before, so the normal keep-awake experience remains unchanged.

Design rationale:
The Win32 WTSQuerySessionInformationW was chosen because it directly query the specified session state without polling or external dependencies. Alternatives like WMI or registry monitoring were considered but rejected due to latency and reliability concerns in lock state detection.

Thread safety:
The StateLock serializes all state mutations and queue writes to prevent interleaving. For example:

  • SessionSwitch event fires on SystemEvents thread
  • Set*KeepAwake methods execute on caller's thread
    Without the lock, a lock transition could occur between reading IsDisplayOn and enqueueing the state, leaving the system in an inconsistent state.

Validation Steps Performed

â€Ē Tested on multiple machines.
â€Ē Confirmed that when the screen is locked, Windows can now switch off the display and use power-saving mode.
â€Ē Verified that without this change, Awake prevented Windows from entering power-saving mode.
â€Ē Confirmed that the unlocked behavior remains unchanged.
â€Ē The native API call is tested in a small console app with a cycle, and it works

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@Meister1977

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@Meister1977
AmbrÃģzy Lőrinc (Meister1977) marked this pull request as draft July 17, 2026 18:31
@Meister1977
AmbrÃģzy Lőrinc (Meister1977) marked this pull request as ready for review July 22, 2026 08:08
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@moooyo Yu Leng (moooyo) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. Letting the display power down while the session is locked makes sense. I found two correctness issues that can leave Awake's execution state out of sync, so I'm requesting changes. Details are inline.

Comment thread src/modules/awake/Awake/Core/Manager.cs Resolved
Comment thread src/modules/awake/Awake/Core/Manager.cs Resolved
Comment thread src/modules/awake/Awake/Core/Manager.cs Resolved
Comment thread src/modules/awake/Awake/Core/Manager.cs Resolved
@daverayment

Copy link
Copy Markdown
Collaborator

Switching to Draft as this is incomplete, lacking testing information and a description of the code.

Please fill in the Validation Steps Performed section and provide further details of what the code is doing in the Detailed Description section. Thanks.

@Meister1977

Copy link
Copy Markdown
Contributor Author

Switching to Draft as this is incomplete, lacking testing information and a description of the code.

Please fill in the Validation Steps Performed section and provide further details of what the code is doing in the Detailed Description section. Thanks.

Added more detailed description and how I validated that it works.

@Meister1977
AmbrÃģzy Lőrinc (Meister1977) marked this pull request as ready for review August 11, 2026 15:47
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@Meister1977

Copy link
Copy Markdown
Contributor Author

Guys, should I add unittests? I can write, but it needs some refactor in the class. Like moving the SessionStateDetector.IsWorkstationLocked(); to a separate class, etc...
Currently I cannot see any tests for this project.

@Meister1977

Copy link
Copy Markdown
Contributor Author

Any news? How will it be approved? Or never? Should I fork the Awake, and use my own vewrsion?

@moooyo

Yu Leng (moooyo) commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

ambrÃģzy Lőrinc (Meister1977) sorry for my late reply. We are working for next version release recently. Will review it again later.

@moooyo

Copy link
Copy Markdown
Contributor

AmbrÃģzy Lőrinc (@Meister1977) see comments. Thanks~

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🧭 PR intake

Visual evidence: Not needed — The changed files do not indicate a visible UI change. No visual evidence is expected.

Recommendation

Link the issue this PR fixes using a closing keyword such as Closes #123.

✅ Ready for review

This PR passed the automated intake checks and is ready for maintainer review.

Automated PR intake; PowerToys maintainers make final decisions.

@moooyo Yu Leng (moooyo) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moooyo

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@moooyo
Yu Leng (moooyo) enabled auto-merge (squash) September 7, 2026 03:58
@moooyo
Yu Leng (moooyo) merged commit 0825b72 into microsoft:main Sep 7, 2026
11 checks passed
@Meister1977
AmbrÃģzy Lőrinc (Meister1977) deleted the detect-screen-lock-in-awake branch September 9, 2026 12:07
Yu Leng (moooyo) pushed a commit that referenced this pull request Nov 11, 2026
â€Ķed (#51880)

#51529

<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: #51529 
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here:
[6192](MicrosoftDocs/windows-dev-docs#6192)

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

**What it does:** Adds an "Allow screen to turn off while locked" toggle
for Awake (`allowDisplayOffWhileLocked`, default `true`). The default
keeps the behavior from #49388. Turning it off keeps
`ES_DISPLAY_REQUIRED` set while Windows is locked.

**Known behavior, intentionally not changed:** Changing the toggle while
a timed or expirable session is running restarts that session. The
settings save triggers `Program.ProcessSettings()`, which calls
`SetTimedKeepAwake()` or `SetExpirableKeepAwake()` again, and these
cancel the existing timer and restart it with the full configured
duration. This is the same path every other Awake setting already takes,
including "Keep screen on". Avoiding it would need extra change-tracking
code in `ProcessSettings()` for a rarely used edge case, so it is out of
scope here.

**Example without a reset:** In Indefinite mode there is no timer, so
changing the toggle only re-queues the execution state
(`SetIndefiniteKeepAwake()` in `Manager.cs`). Passive mode is also
unaffected.

</details>

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

<img width="797" height="562" alt="image"
src="https://github.com/user-attachments/assets/f7c4c5bf-9e7e-4a86-962b-7e7ac578af1c"
/>
<img width="295" height="157" alt="image"
src="https://github.com/user-attachments/assets/fb8abdea-4f8e-4e9c-8863-483963d953c1"
/>

And checked both cases. In case of enabled, then the locked screen can
be switched off, in case of disabled, the locked screen stays on.

Co-authored-by: Lorinc Ambrozy <lorinc.ambrozy@goto.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-Awake Issues regarding the PowerToys Awake utility Ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants