Skip to content

[Modules] Handle WM_ENDSESSION in run_message_loop daemons (GrabAndMove, AlwaysOnTop, FancyZones) - #48404

Merged
Boliang Zhang (LegendaryBlair) merged 2 commits into
microsoft:mainfrom
yeelam-gordon:user/yeelam/fix-modules-quiesce
Aug 9, 2026
Merged

[Modules] Handle WM_ENDSESSION in run_message_loop daemons (GrabAndMove, AlwaysOnTop, FancyZones)#48404
Boliang Zhang (LegendaryBlair) merged 2 commits into
microsoft:mainfrom
yeelam-gordon:user/yeelam/fix-modules-quiesce

Conversation

@yeelam-gordon

@yeelam-gordon Gordon Lam (yeelam-gordon) commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Companion PR to #48378 (runner). Fixes the same APPLICATION_HANG_QUIESCE_*_PowerToys.exe!run_message_loop WER bucket in the other PowerToys daemons whose top-level windows ignored WM_ENDSESSION.

Root cause (same as #48378)

run_message_loop (src/common/utils/window.h) calls GetMessageW which only returns 0 on WM_QUIT. If a daemon's WndProc lets WM_ENDSESSION fall through to DefWindowProc, no WM_QUIT is ever posted on logoff/shutdown, the loop blocks, CSRSS hits the quiesce timeout (~5s), TerminateProcess fires, and Watson logs APPLICATION_HANG_QUIESCE.

run_message_loop callsite audit

8 production callsites. Persistent daemons that own a top-level window and were affected:

Module Status before Fix here
runner hang Fixed in #48378
GrabAndMove hang (tray icon, NIM_DELETE in WM_DESTROY) main.cpp
AlwaysOnTop hang AlwaysOnTop.cpp
FancyZones hang FancyZones.cpp
KeyboardManagerEngine n/a No top-level window → OS skips WM_ENDSESSION and TerminateProcess directly; no hang bucket possible
ZoomIt already handled SysInternals heritage
PowerLauncher already handled Managed SessionEnding event
MeasureTool, Notifications transient/spawned on demand Not a shutdown-time daemon

Fix pattern

For AlwaysOnTop and FancyZones (no tray icon to clean up) — minimal:

case WM_ENDSESSION:
    if (wparam) PostQuitMessage(0);  // wparam==FALSE => shutdown vetoed
    return 0;

For GrabAndMove (has Shell_NotifyIcon cleanup in WM_DESTROY that must not run on shutdown) — use a g_session_ending flag and skip the tray-icon delete in WM_DESTROY, mirroring runner's tray_icon.cpp pattern from #48378.

No shared header: each module's WM_DESTROY cleanup is module-specific; the abstraction would be too thin and would hide the variance in what to skip.

Why no logging on the shutdown path

Same reasoning as #48378 review feedback — spdlog::flush_on(info) synchronously flushes to disk; emitting log lines from WM_ENDSESSION/WM_DESTROY burns the ~5s quiesce budget for no diagnostic value (Watson already records the bucket on failure).

Verification

Related

@yeelam-gordon Gordon Lam (yeelam-gordon) changed the title [GrabAndMove] Handle WM_ENDSESSION to avoid APPLICATION_HANG_QUIESCE on OS shutdown [Modules] Handle WM_ENDSESSION in run_message_loop daemons (GrabAndMove, AlwaysOnTop, FancyZones) Jun 9, 2026
Comment thread src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Fixed
Comment thread src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Fixed
@github-actions

This comment has been minimized.

Copilot AI 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.

Pull request overview

This PR updates several PowerToys module daemons that run a top-level GetMessageW loop so they respond to WM_ENDSESSION and can unwind promptly during OS logoff/shutdown, avoiding the APPLICATION_HANG_QUIESCE_*_PowerToys.exe!run_message_loop WER bucket.

Changes:

  • GrabAndMove: adds a g_session_ending flag, routes WM_ENDSESSION through WM_CLOSE, and skips tray-icon deletion in WM_DESTROY during OS shutdown.
  • FancyZones: handles WM_ENDSESSION and posts WM_QUIT (only when wparam indicates shutdown is proceeding).
  • AlwaysOnTop: handles WM_ENDSESSION and posts WM_QUIT (only when wparam indicates shutdown is proceeding).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/modules/GrabAndMove/GrabAndMove/main.cpp Add WM_ENDSESSION handling + shutdown flag to avoid shutdown-time work in WM_DESTROY.
src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Post WM_QUIT on confirmed session end so the message loop exits.
src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Post WM_QUIT on confirmed session end so the message loop exits.

Comment thread src/modules/GrabAndMove/GrabAndMove/main.cpp
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Outdated
Comment thread src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Outdated
Comment thread src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/modules/GrabAndMove/GrabAndMove/main.cpp

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/modules/GrabAndMove/GrabAndMove/main.cpp

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/modules/GrabAndMove/GrabAndMove/main.cpp Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

/acp run

@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines could not run because the pipeline triggers exclude this branch/path.

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yeelam-gordon
Gordon Lam (yeelam-gordon) force-pushed the user/yeelam/fix-modules-quiesce branch from 9ebd655 to 407ec4f Compare August 6, 2026 14:13
@LegendaryBlair
Boliang Zhang (LegendaryBlair) merged commit 68a2a0d into microsoft:main Aug 9, 2026
8 checks passed
@LegendaryBlair Boliang Zhang (LegendaryBlair) added Product-Grab And Move Product-Always On Top Refers to the idea of a Always on Top Powertoy Product-FancyZones Refers to the FancyZones PowerToy labels Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-Always On Top Refers to the idea of a Always on Top Powertoy Product-FancyZones Refers to the FancyZones PowerToy Product-Grab And Move

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants