fix(native): eliminate explorer hang deadlock and improve taskbar crash recovery - #98
Merged
CodeZeno merged 4 commits intoSep 13, 2026
Conversation
- Replace synchronous SHAppBarMessage in get_taskbar_rect with non-blocking get_window_rect_safe to prevent thread deadlock when explorer.exe hangs (Application Hang 1002) - In spawn_taskbar_watchdog, verify parent window validity via GetParent() when shell_hosted to detect orphaned child windows across explorer restarts - Re-dock taskbar surfaces and re-render on TaskbarCreated shell broadcast
… dispatch, and fix CI BOM
CodeZeno
added a commit
that referenced
this pull request
Sep 13, 2026
Integrate PR #98: avoid the shell taskbar-position round-trip, check surviving window parents, and repaint after TaskbarCreated. Remove the CI workflow added by the PR. Preserve all four original author commits. Verified release build in target/pr-98-validation, cargo clippy, cargo test (242 passed, 1 ignored), and cargo fmt --check.
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.
Background & Context
While using the app on Windows 11, I ran into the issue discussed in #94 during an
explorer.exeUI hang (Event ID 1002, Application Hang). The app vanished from the taskbar and froze completely. After digging into the root cause, I found that while the recent context-menu fixes in v2.10.24/25 addressed menu deadlocks, a couple of underlying Win32 LPC and watchdog checks were still causing the monitor thread to hang indefinitely or fail to re-dock when Explorer hung or restarted. Here is the detailed breakdown and the fix.Problem
When
explorer.exeexperiences a UI hang or freeze (Event ID 1002, Application Hang),Claude-Code-Usage-Monitorfreezes indefinitely and vanishes from the Windows 11 taskbar without recovering:SHAppBarMessage(ABM_GETTASKBARPOS, ...)insrc/native_interop.rsrelies on synchronous LPC with Explorer's UI thread. When Explorer is unresponsive, this call blocks indefinitely, freezing the monitor thread.IsWindow(child_hwnd)continues to returntrue, causingspawn_taskbar_watchdogto believe the host taskbar is still alive and leave the widget orphaned.Solution
SHAppBarMessagewithget_window_rect_safe(taskbar_hwnd). Non-blockingGetWindowRecttakes ~0.003 ms and never deadlocks during Explorer hangs (verified empirically viaNtSuspendProcesstests whereSHAppBarMessagehung for >1500 ms).spawn_taskbar_watchdog, we now checkGetParent(hwnd). If a surface has a parent assigned and!IsWindow(parent), the watchdog detects the dead host and triggers redocking. Unparented/floating surfaces safely evaluate tofalseto avoid false-positive restart loops. Uses a zero-heap lazy iterator (once(...).chain(...).any(...)).TaskbarCreated: Explicitly triggersrender_layered()when theTaskbarCreatedbroadcast message is received.Testing
NtSuspendProcessonexplorer.exe: monitor remained 100% responsive (Responding = True, ~28 MB RAM) and resumed immediately.WM_CLOSEtoShell_TrayWndand restartingexplorer.exe: widget cleanly and automatically redocked to the new taskbar (Visible = True).taskkill /f /im explorer.exe: watchdog cleanly detected dead parent and recovered with single-instance mutex handoff.test result: ok).Note: This fix was researched, profiled, and refined in collaboration with an AI coding agent (Google Antigravity), and rigorously validated across live Windows 11 shell hang & restart lifecycles.