Repository navigation
Conversation
A taskbar-hosted surface is a child of Shell_TrayWnd, and DefWindowProc forwards several mouse messages from a child to its parent with a synchronous SendMessage. Every button press on the widget therefore sent WM_MOUSEACTIVATE into Explorer's taskbar thread, and every mouse move over a non-clickable area sent WM_SETCURSOR. A hang dump of explorer.exe taken after a right-click on the widget showed the Taskbar thread stuck inside UI Automation while handling WM_MOUSEACTIVATE (hit test HTCLIENT, mouse message WM_RBUTTONDOWN) sent to Shell_TrayWnd. The monitor's UI thread waited on that call until the hang watchdog relaunched it; on other occasions Windows restarted Explorer. The surfaces now answer these messages themselves: - WM_MOUSEACTIVATE returns MA_NOACTIVATE (the surface is WS_EX_NOACTIVATE and never activates; the click is still delivered). - WM_SETCURSOR always sets the hand or arrow cursor and returns TRUE. - WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_APPCOMMAND and WM_CONTEXTMENU are consumed, since the surface has no handler for them. The widget tooltip is also owned by the controller instead of the surface: a popup owned by a child is owned by its top-level ancestor, which put the tooltip in Explorer's Shell_TrayWnd owner chain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
Fixes #198.
A taskbar-hosted surface is a child of
Shell_TrayWnd.DefWindowProcforwards several mouse messages from a child window to its parent with a synchronousSendMessage, so the widget was making blocking calls into Explorer's taskbar thread:WM_MOUSEACTIVATEon every button press. A hang dump ofexplorer.exeshowed the Taskbar thread stuck in UI Automation while handling exactly this message (sent toShell_TrayWndfrom a right-button press). The monitor's UI thread waited on it until the hang watchdog relaunched the widget, or Windows restarted Explorer.WM_SETCURSORon every mouse move over a non-clickable area, through theset_surface_cursor(...) == falsefallback.WM_APPCOMMANDmessages.Changes:
MA_NOACTIVATEforWM_MOUSEACTIVATE. The surfaces areWS_EX_NOACTIVATEand never activate, and the click itself is still delivered.set_surface_cursoralways sets a cursor (hand over clickable layers, arrow elsewhere), andWM_SETCURSORreturnsTRUEwithoutDefWindowProc.WM_MOUSEWHEEL,WM_MOUSEHWHEEL,WM_APPCOMMANDandWM_CONTEXTMENUare consumed by the surfaces, which have no handlers for them.Shell_TrayWndowner chain.Testing
cargo fmt --all -- --check: passescargo test --locked: 603 passed, 6 ignored. The run includes a new regression test,hosted_surface_never_forwards_mouse_messages_to_its_parent. It first confirms thatDefWindowProcforwardsWM_MOUSEACTIVATEto a recording parent, then checks that the surfacewnd_procforwards none of these messages.cargo build --locked --release: succeedsGetWindow(GW_OWNER)), notShell_TrayWnd. The hang is intermittent and appeared roughly once per handful of right-clicks over an evening on the affected machine. I am running this build there now and will report back on the issue.Checklist
🤖 Generated with Claude Code