dotnet / dotnet/wpf

HwndHost temporarily reparents hosted window to SystemResourceNotifyWindow (SystemResources.Hwnd window) for no reason

Open
#10,153 0 comments 1 reaction 0 assignees View on GitHub
Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

In response to certain events, such as toggling high contrast mode or RDPing into a machine, HwndHost will temporarily change the parent of the hosted child window to a special invisible 'SystemResourceNotifyWindow' window created by .NET. This behaviour is supposed to only happen if the child window is taken out of the visual tree (so no longer has a parent window). This causes an unfortunate side effect when using WinUI 3's Xaml Islands (DesktopWindowXamlSource) that the child window is destroyed, causing all sorts of issues. See https://github.com/microsoft/microsoft-ui-xaml/issues/10231. There is obviously also the question of if WinUI 3 should have this behaviour of destroying DesktopWindowXamlSource windows if they have their parent changed, so that is why I raised an issue for that as well. Still, HwndHost shouldn't be reparenting child windows for no reason.

This seems to be in response to the PresentationSource changing in reponse to these events for some reason. You can see exactly where it reparents the child window to the SystemResourceNotifyWindow (SystemResources.Hwnd window) here: https://github.com/dotnet/wpf/blob/c6bff274b42ea186c4a53aab6e6447cf92aeb1e1/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Interop/HwndHost.cs#L984. The method where that happens is called by the method which is added as a SourceChanged handler here: https://github.com/dotnet/wpf/blob/c6bff274b42ea186c4a53aab6e6447cf92aeb1e1/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Interop/HwndHost.cs#L834.

### Reproduction Steps

1. Debug the attached project in Visual Studio
2. Toggle high contrast mode on or off in Windows Settings or RDP into the box
3. The app will crash due to BuildWindowCore running again since the window was destroyed as a result of the parent changing
4. Do not stop debugging
5. Check the immediate window for a message that looks like the following:
`onecoreuap\windows\moderncore\inputv2\inputhost\outside\lifted\windowparentchain.cpp(326)\Microsoft.UI.Input.dll!00007FF8A4985FCC: (caller: 00007FF8A4986AB1) ReturnHr(2) tid(15c88) 8007139F The group or resource is not in the correct state to perform the requested operation. Msg:[HWND 000000000088348A changed parent from 00000000017F11E4 to 000000000042392C. Unsupported scenario.] Exception thrown at 0x00007FFA13D5FA4C (KernelBase.dll) in QPad.exe: WinRT originate error - 0x8007139F : 'WindowParentChain invalid state.'.`
6. Using a tool like Spy++, look up the window handle which the above message says is the new parent
7. You will notice that the new parent of the Xaml Islands child window is 'SystemResourceNotifyWindow'
![Image](https://github.com/user-attachments/assets/cc24db46-90a4-4aed-b5a3-4c40ac2d3a2e)

### Expected behavior

The parent of the hosted child window in the HwndHost should never change unless the HwndHost is moved to a different window, especially not in response to trivial events such as toggling high contrast.

### Actual behavior

Certain events like toggling high contrast and RDPing into the box cause the hosted child window to be reparented to the special invisible 'SystemResourceNotifyWindow' window temporarily.

### Regression?

Not sure, but I tested in .NET 8 and the issue is present there as well.

### Known Workarounds

None at the moment. I have tried adding my own SourceChangedHandler and setting e.handled to true to stop it going through to the HwndHost's internal one, but the internal one always seems to run first.

### Impact

Unable to use WinUI 3 XamlIslands properly using a HwndHost in WPF. Could also cause issue with other types of child windows when hosted in a HwndHost.

### Configuration

- .NET 9
- Windows 11 23H2 (22631.4460
- x64 (OS and app)
- Not sure

### Other information

My guess is that for some reason, certain events cause a new PresentationSource to be created, and when it is first created, it isn't associated with a window handle, which causes the HwndHost to reparent the child window to the special invisible 'SystemResourceNotifyWindow'.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.