Skip to content

Fix WinUI tray menu crash with invisible anchor window pattern#4

Closed
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-winui-tray-menu-crash
Closed

Fix WinUI tray menu crash with invisible anchor window pattern#4
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-winui-tray-menu-crash

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 30, 2026

WinUI 3's MenuFlyout.ShowAt() requires a UIElement with visual tree context. TrayIcon doesn't provide this, causing native crashes in Microsoft.UI.Windowing.Core.dll (exception 0xe0464645) after idle periods or window interactions.

Changes

New TrayMenuAnchorWindow

  • Minimal 1x1 invisible window providing required UIElement anchor
  • Positioned at cursor via P/Invoke when menu invoked
  • Created once, reused across invocations to avoid creation/destruction overhead
  • Strong reference in App._trayMenuAnchor prevents premature GC

Modified tray handlers

private void OnTrayIconSelected(TrayIcon sender, TrayIconEventArgs e)
{
    ShowTrayMenuFlyoutWithAnchor();  // Was: e.Flyout = BuildTrayMenuFlyout()
}

private void ShowTrayMenuFlyoutWithAnchor()
{
    if (_trayMenuAnchor == null)
        _trayMenuAnchor = new TrayMenuAnchorWindow();
    
    GetCursorPos(out POINT cursorPos);
    _trayMenuAnchor.PositionAtCursor(cursorPos.X, cursorPos.Y);
    
    var flyout = BuildTrayMenuFlyout();
    _trayMenuAnchor.ShowFlyout(flyout);  // Anchors to window's Grid element
}

Technical Context

This pattern is documented in WinUIEx and Microsoft WinUI repos as the workaround for unpackaged apps showing flyouts from system tray. Direct assignment (e.Flyout = ...) works in simple cases but crashes under timing-sensitive conditions when the flyout lacks valid visual context.

See TRAY_MENU_CRASH_FIX.md for detailed analysis of alternatives considered (custom window popup, window reuse, native Win32 menus) and why this approach was selected.

Original prompt

This section details on the original issue you should resolve

<issue_title>WinUI tray menu crashes in Microsoft.UI.Windowing.Core.dll after idle/interaction</issue_title>
<issue_description>## Problem
The WinUI 3 tray app crashes intermittently when clicking the tray icon to show the menu. The crash occurs in the native WinUI windowing layer and bypasses all .NET exception handlers.

Crash Details

  • Faulting module: Microsoft.UI.Windowing.Core.dll (version 10.0.27108.1025)
  • Exception code: 0xe0464645 (CLR exception marker)
  • Fault offset: 0x000000000000a280 (consistent across all crashes)
  • Platform: Windows 11 ARM64
  • Windows App SDK: 1.8.250906003
  • WinUIEx: 2.9.0
  • .NET: 9.0 (targeting windows10.0.19041.0)

Reproduction Steps

  1. Start the tray app
  2. Click tray icon - menu appears (works)
  3. Click away to dismiss menu
  4. Wait a few seconds OR open Settings window and close it
  5. Click tray icon again - CRASH

The crash doesn't happen immediately but becomes more likely after:

  • The app has been idle for a period
  • Other windows have been opened/closed (like Settings)
  • Multiple menu show/hide cycles

What We've Tried

1. Window Reuse Pattern

Instead of creating/destroying TrayMenuWindow each click, tried reusing a single window:

  • Hide() instead of Close() on deactivation
  • ClearItems() and rebuild menu content
  • Result: Black square appeared instead of menu content

2. UI Thread Dispatching

Added checks to ensure tray icon callbacks dispatch to UI thread

  • Result: Still crashes

3. Crash Logging

Added UnhandledException, DomainUnhandledException, UnobservedTaskException handlers

  • Result: No crash log written - crash is in native code

4. Backdrop Removal

Removed DesktopAcrylicBackdrop from TrayMenuWindow

  • Result: Still crashes

5. Async Data Fetch with Timeout

Added brief wait for gateway data before showing menu

  • Result: Still crashes

Current Architecture

TrayMenuWindow extends WinUIEx.WindowEx, configured as popup-style (no title bar, always on top, closes on deactivation). ShowAtCursor() uses P/Invoke to position near taskbar.

App creates new TrayMenuWindow on each tray click, closes previous one first.

Hypothesis

The crash appears to be related to WinUI window lifecycle management:

  1. GC collecting something the native windowing layer still references after idle
  2. COM apartment threading issue when tray icon callback fires
  3. WindowEx/WinUIEx issue with rapid window creation/destruction
  4. Windows App SDK bug with unpackaged apps and system tray interaction

Potential Solutions to Explore

  1. MenuFlyout approach: Use e.Flyout = BuildMenuFlyout() in tray callbacks instead of custom window
  2. Keep-alive window: Create an invisible window to keep WinUI runtime active
  3. GC.KeepAlive: Pin critical objects to prevent collection

Files of Interest

  • src/OpenClaw.Tray.WinUI/App.xaml.cs - Main app, tray icon handling
  • src/OpenClaw.Tray.WinUI/Windows/TrayMenuWindow.xaml.cs - Popup menu window

Windows Event Log Entry

Faulting application name: OpenClaw.Tray.WinUI.exe
Faulting module name: Microsoft.UI.Windowing.Core.dll
Exception code: 0xe0464645
Fault offset: 0x000000000000a280

</issue_description>

<agent_instructions>Think as deeply as you can here. Yeah, you won't be able to test it locally, but think about why this might happen. Feel free to check documentation or Google around.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits January 30, 2026 23:54
Co-authored-by: shanselman <2892+shanselman@users.noreply.github.com>
Co-authored-by: shanselman <2892+shanselman@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix intermittent crash in WinUI tray menu Fix WinUI tray menu crash with invisible anchor window pattern Jan 30, 2026
Copilot AI requested a review from shanselman January 30, 2026 23:57
@shanselman shanselman closed this Feb 2, 2026
@shanselman shanselman deleted the copilot/fix-winui-tray-menu-crash branch February 8, 2026 02:22
shanselman pushed a commit that referenced this pull request Apr 20, 2026
Propagate CancellationToken through WebSocket TTS call chain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WinUI tray menu crashes in Microsoft.UI.Windowing.Core.dll after idle/interaction

2 participants