Files
PowerToys/doc/planning/awake.md
Den Delimarsky 27dcd1e5bc Awake and DevEx improvements (#44795)
This PR contains a set of bug fixes and general improvements to
[Awake](https://awake.den.dev/) and developer experience tooling for
building the module.

### Awake Fixes

- **#32544** - Fixed an issue where Awake settings became non-functional
after the PC wakes from sleep. Added `WM_POWERBROADCAST` handling to
detect system resume events (`PBT_APMRESUMEAUTOMATIC`,
`PBT_APMRESUMESUSPEND`) and re-apply `SetThreadExecutionState` to
restore the awake state.

- **#36150** - Fixed an issue where Awake would not prevent sleep when
AC power is connected. Added `PBT_APMPOWERSTATUSCHANGE` handling to
re-apply `SetThreadExecutionState` when the power source changes
(AC/battery transitions).

- **#41674** - Fixed silent failure when `SetThreadExecutionState`
fails. The monitor thread now handles the return value, logs an error,
and reverts to passive mode with updated tray icon.

- **#41738** - Fixed `--display-on` CLI flag default from `true` to
`false` to align with documentation and PowerToys settings behavior.
This is a breaking change for scripts relying on the undocumented
default.

- **#41918** - Fixed `WM_COMMAND` message processing flaw in
`TrayHelper.WndProc` that incorrectly compared enum values against enum
count. Added proper bounds checking for custom tray time entries.

- **#44134** - Documented that `ES_DISPLAY_REQUIRED` (used when "Keep
display on" is enabled) blocks Task Scheduler idle detection, preventing
scheduled maintenance tasks like SSD TRIM. Workaround: disable "Keep
display on" or manually run `Optimize-Volume -DriveLetter C -ReTrim`.

- **#38770** - Fixed tray icon failing to appear after Windows updates.
Increased retry attempts and delays for icon Add operations (10
attempts, up to ~15.5 seconds total) while keeping existing fast retry
behavior for Update/Delete operations.

- **#40501** - Fixed tray icon not disappearing when Awake is disabled.
The `SetShellIcon` function was incorrectly requiring an icon for Delete
operations, causing the `NIM_DELETE` message to never be sent.

- Fixed an issue where toggling "Keep screen on" during an active timed
session would disrupt the countdown timer. The display setting now
updates directly without restarting the timer, preserving the exact
remaining time.

### Performance Optimizations

- Fixed O(n²) loop in `TrayHelper.CreateAwakeTimeSubMenu` by replacing
`ElementAt(i)` with `foreach` iteration.

- Fixed Observable subscription leak in `Manager.cs` by storing
`IDisposable` and disposing in `CancelExistingThread()`. Also removed
dead `_tokenSource` code that was no longer used.

- Reduced allocations in `SingleThreadSynchronizationContext` by
changing `Tuple<>` to `ValueTuple`.

- Replaced dedicated exit event thread with
`ThreadPool.RegisterWaitForSingleObject()` to reduce resource usage.

### Code Quality

- Replaced `Console.WriteLine` with `Logger.LogError` in `TrayHelper.cs`
for consistent logging.

- Added proper error logging to silent exception catches in
`AwakeService.cs`.

- Removed dead `Math.Min(minutes, int.MaxValue)` code where `minutes` is
already an `int`.

- Extracted hardcoded tray icon ID to named constant `TrayIconId`.

- Standardized null coalescing for `GetSettings<AwakeSettings>()` calls
across all files.

### Debugging Experience Fixes

- Fixed first-chance exceptions in `settings_window.cpp` during
debugging. Added `HasKey()` check before accessing `hotkey_changed`
property to prevent `hresult_error` exceptions when the property doesn't
exist in module settings.

- Fixed first-chance exceptions in FindMyMouse `parse_settings` during
debugging. Refactored to extract the properties object once and added
`HasKey()` checks before all `GetNamedObject()` calls. This prevents
`winrt::hresult_error` exceptions when optional settings keys (like
legacy `overlay_opacity`) don't exist, improving the debugging
experience by eliminating spurious exception breaks.

- Fixed LightSwitch.UITests build failures when building from a clean
state. Added missing project references (`ManagedCommon`,
`LightSwitchModuleInterface`) with `ReferenceOutputAssembly=false` to
ensure proper build ordering, and added existence check for the native
DLL copy operation.

### Developer Experience

- Added `setup-dev-environment.ps1` script to automate development
environment setup.
- Added `clean-artifacts.ps1` script to resolve build errors from
corrupted build state or missing image files.
- Added build script that allows standalone command line build of the
Awake module.
- Added troubleshooting section to
`doc/devdocs/development/debugging.md` with guidance on resolving common
build errors.
2026-01-20 21:27:45 -08:00

9.2 KiB

last-update
last-update
1-18-2026

PowerToys Awake Changelog

Builds

The build ID can be found in Core\Constants.cs in the BuildId variable - it is a unique identifier for the current builds that allows better diagnostics (we can look up the build ID from the logs) and offers a way to triage Awake-specific issues faster independent of the PowerToys version. The build ID does not carry any significance beyond that within the PowerToys code base.

The build ID moniker is made up of two components - a reference to a Halo character, and the date when the work on the specific build started in the format of MMDDYYYY.

Build ID Build Date
DIDACT_01182026 January 18, 2026
TILLSON_11272024 November 27, 2024
PROMETHEAN_09082024 September 8, 2024
VISEGRADRELAY_08152024 August 15, 2024
DAISY023_04102024 April 10, 2024
ATRIOX_04132023 April 13, 2023
LIBRARIAN_03202022 March 20, 2022
ARBITER_01312022 January 31, 2022

DIDACT_01182026 (January 18, 2026)

Note

See pull request: Awake - DIDACT_01182026

  • #32544 Fixed an issue where Awake settings became non-functional after the PC wakes from sleep. Added WM_POWERBROADCAST handling to detect system resume events (PBT_APMRESUMEAUTOMATIC, PBT_APMRESUMESUSPEND) and re-apply SetThreadExecutionState to restore the awake state.
  • #36150 Fixed an issue where Awake would not prevent sleep when AC power is connected. Added PBT_APMPOWERSTATUSCHANGE handling to re-apply SetThreadExecutionState when the power source changes (AC/battery transitions).
  • Fixed an issue where toggling "Keep screen on" during an active timed session would disrupt the countdown timer. The display setting now updates directly without restarting the timer, preserving the exact remaining time.
  • #41918 Fixed WM_COMMAND message processing flaw in TrayHelper.WndProc that incorrectly compared enum values against enum count. Added proper bounds checking for custom tray time entries.
  • Investigated #44134 - documented that ES_DISPLAY_REQUIRED (used when "Keep display on" is enabled) blocks Task Scheduler idle detection, preventing scheduled maintenance tasks like SSD TRIM. Workaround: disable "Keep display on" or manually run Optimize-Volume -DriveLetter C -ReTrim. Additional investigation needed for potential "idle window" feature.
  • #41738 Fixed --display-on CLI flag default from true to false to align with documentation and PowerToys settings behavior. This is a breaking change for scripts relying on the undocumented default.
  • #41674 Fixed silent failure when SetThreadExecutionState fails. The monitor thread now handles the return value, logs an error, and reverts to passive mode with updated tray icon.
  • #38770 Fixed tray icon failing to appear after Windows updates. Increased retry attempts and delays for icon Add operations (10 attempts, up to ~15.5 seconds total) while keeping existing fast retry behavior for Update/Delete operations.
  • #40501 Fixed tray icon not disappearing when Awake is disabled. The SetShellIcon function was incorrectly requiring an icon for Delete operations, causing the NIM_DELETE message to never be sent.
  • #40659 Fixed potential stack overflow crash in EXPIRABLE mode. Added early return after SaveSettings when correcting past expiration times, matching the pattern used by other mode handlers to prevent reentrant execution.

TILLSON_11272024 (November 27, 2024)

Note

See pull request: Awake - TILLSON_11272024

  • #35250 Updates the icon retry policy, making sure that the icon consistently and correctly renders in the tray.
  • #35848 Fixed a bug where custom tray time shortcuts for longer than 24 hours would be parsed as zero hours/zero minutes.
  • #34716 Properly recover the state icon in the tray after an explorer.exe crash.
  • Added configuration safeguards to make sure that invalid values for timed keep-awake times do not result in exceptions.
  • Updated the tray initialization logic, making sure we wait for it to be properly created before setting icons.
  • Expanded logging capabilities to track invoking functions.
  • Added command validation logic to make sure that incorrect command line arguments display an error.
  • Display state now shown in the tray tooltip.
  • When timed mode is used, changing the display setting will no longer reset the timer.

PROMETHEAN_09082024 (September 8, 2024)

Note

See pull request: Awake - PROMETHEAN_09082024

  • Updating the initialization logic to make sure that settings are respected for proper group policy and single-instance detection.
  • #34148 Fixed a bug from the previous release that incorrectly synchronized threads for shell icon creation and initialized parent PID when it was not parented.

VISEGRADRELAY_08152024 (August 15, 2024)

Note

See pull request: Awake - VISEGRADRELAY_08152024

  • #34148 Fixes the issue where the Awake icon is not displayed.
  • #17969 Add the ability to bind the process target to the parent of the Awake launcher.
  • PID binding now correctly ignores irrelevant parameters (e.g., expiration, interval) and only works for indefinite periods.
  • Amending the native API surface to make sure that the Win32 error is set correctly.

DAISY023_04102024 (April 10, 2024)

Note

See pull request: Awake Update - DAISY023_04102024

  • #33630 When in the UI and you select 0 as hours and 0 as minutes in TIMED awake mode, the UI becomes non-responsive whenever you try to get back to timed after it rolls back to PASSIVE.
  • #12714 Adds the option to keep track of Awake state through tray tooltip.
  • #11996 Adds custom icons support for mode changes in Awake.
  • Removes the dependency on System.Windows.Forms and instead uses native Windows APIs to create the tray icon.
  • Removes redundant/unused code that impacted application performance.
  • Updates dependent packages to their latest versions (Microsoft.Windows.CsWinRT and System.Reactive).

ATRIOX_04132023 (April 13, 2023)

  • Moves from using Task.Run to spin up threads to actually using a blocking queue that properly sets thread parameters on the same thread.
  • Moves back to using native Windows APIs through P/Invoke instead of using a package.
  • Move away from custom logging and to built-in logging that is consistent with the rest of PowerToys.
  • Updates System.CommandLine and System.Reactive to the latest preview versions of the package.

LIBRARIAN_03202022 (March 20, 2022)

  • Changed the tray context menu to be following OS conventions instead of the style offered by Windows Forms. This introduces better support for DPI scaling and theming in the future.
  • Custom times in the tray can now be configured in the settings.json file for awake, through the tray_times property. The property values are representative of a Dictionary<string, int> and can be in the form of "YOUR_NAME": LENGTH_IN_SECONDS:
{
    "properties": {
        "awake_keep_display_on": true,
        "awake_mode": 2,
        "awake_hours": 0,
        "awake_minutes": 3,
        "tray_times": {
            "Custom length": 1800,
            "Another custom length": 3600
        }
    },
    "name": "Awake",
    "version": "1.0"
}
  • Proper Awake background window closure was implemented to ensure that the process collects the correct handle instead of the empty one that was previously done through System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow(). This likely can help with the Awake process that is left hanging after PowerToys itself closes.