Skip to content

Fix DwmIsCompositionEnabled crash on Mono/wine-mono#11567

Open
williamzujkowski wants to merge 1 commit intodotnet:mainfrom
williamzujkowski:fix/dwm-composition-preservesig
Open

Fix DwmIsCompositionEnabled crash on Mono/wine-mono#11567
williamzujkowski wants to merge 1 commit intodotnet:mainfrom
williamzujkowski:fix/dwm-composition-preservesig

Conversation

@williamzujkowski
Copy link
Copy Markdown

@williamzujkowski williamzujkowski commented Apr 5, 2026

Description

Fixes WPF applications crashing on minimize/restore when running under Wine on Linux.

History

This is a revival of #4155 (2021), which was closed because it depended on two mono PRs:

The original issue #4166 was closed as completed in 2021, but the WPF-side fix was never actually merged. The bug still exists in the current codebase.

Root cause

The P/Invoke for DwmIsCompositionEnabled in NativeMethods.cs uses PreserveSig = false:

[DllImport("dwmapi.dll", EntryPoint = "DwmIsCompositionEnabled", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool _DwmIsCompositionEnabled();

This transforms the native signature from HRESULT DwmIsCompositionEnabled(BOOL *pfEnabled) to bool DwmIsCompositionEnabled(void). On .NET Framework/CoreCLR this works via automatic HRESULT-to-exception conversion, but Mono and wine-mono do not support PreserveSig = false for DllImports. The marshalling is skipped, so dwmapi.dll receives a garbage pointer in rcx (x64) instead of a valid BOOL*, causing an access violation.

Fix

Change to PreserveSig = true with an explicit out parameter, matching the pattern already used by DwmGetColorizationColor on line 2513 of the same file:

[DllImport("dwmapi.dll", EntryPoint = "DwmIsCompositionEnabled", PreserveSig = true)]
private static extern HRESULT _DwmIsCompositionEnabled(
    [Out, MarshalAs(UnmanagedType.Bool)] out bool pfEnabled);

The WindowsBase/Utilities.cs version already uses the correct pattern via PInvoke.DwmIsCompositionEnabled(out BOOL).

Impact

  • Windows: No behavior change — HRESULT.S_OK is always returned, enabled reflects actual DWM state
  • Wine/Mono: Fixes crash on minimize/restore for all WPF applications
  • Affected apps: Any WPF app triggering SystemParameters.IsGlassEnabled or WindowChromeWorker

Note on mono dependency

This WPF-side fix is correct regardless of mono/mono#20831's status — it changes the P/Invoke to use the proper Windows API signature. The mono PR is a separate prerequisite for wine-mono to fully support the PreserveSig attribute, but this change is independently valid since it switches FROM PreserveSig = false (the problematic path) TO PreserveSig = true (the working path).

Fixes #4166
Supersedes #4155

The P/Invoke for DwmIsCompositionEnabled used PreserveSig = false,
which transforms the native signature from:
  HRESULT DwmIsCompositionEnabled(BOOL *pfEnabled)
to:
  bool DwmIsCompositionEnabled(void)

This works on .NET Framework/CoreCLR but crashes on Mono and
wine-mono, which don't support PreserveSig = false for DllImports.
The marshalling is skipped, so dwmapi receives a garbage pointer
instead of a valid BOOL*, causing an access violation.

Fix: change to PreserveSig = true with an explicit out parameter,
matching the pattern already used by DwmGetColorizationColor in
the same file. The public wrapper now checks the HRESULT before
returning the value.

This fixes WPF applications crashing on minimize/restore when
running under Wine on Linux, which affects tools like EQLogParser.

Fixes: dotnet#4166
@williamzujkowski williamzujkowski requested a review from a team April 5, 2026 17:22
@dotnet-policy-service dotnet-policy-service bot added PR metadata: Label to tag PRs, to facilitate with triage Community Contribution A label for all community Contributions labels Apr 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Community Contribution A label for all community Contributions PR metadata: Label to tag PRs, to facilitate with triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A WPF application running on Wine (on Linux) via wine-mono will crash when calling DwmIsCompositionEnabled due to PreserveSig = false.

1 participant