Skip to content

[windows] Strip HMONITOR sign extension from display ids#189570

Open
sero583 wants to merge 1 commit into
flutter:masterfrom
sero583:fix-hmonitor-sign-extension
Open

[windows] Strip HMONITOR sign extension from display ids#189570
sero583 wants to merge 1 commit into
flutter:masterfrom
sero583:fix-hmonitor-sign-extension

Conversation

@sero583

@sero583 sero583 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

On 64-bit Windows, USER and GDI handles are 32-bit values that the OS sign-extends to pointer size (documented in "Interprocess Communication Between 32-bit and 64-bit Applications"). When an HMONITOR with the high bit set (e.g. 0xE02E16A5) is cast directly to the 64-bit FlutterEngineDisplayId, the result is a sign-extended value like 0xFFFFFFFFE02E16A5. That value exceeds the signed 64-bit range once the display id is converted for Dart and trips the converter's range assertion, crashing debug builds on affected machines.

Whether a machine is affected depends purely on the handle values the session hands out, which is why this only reproduces on some systems.

This change routes every HMONITOR to display id conversion through a single helper, DisplayManagerWin32::ToDisplayId, which truncates the handle to its lower 32 bits. Both conversion sites (DisplayManagerWin32::FromMonitor for the display list and FlutterWindow::GetDisplayId for per-window lookups) use the helper, so FindById keeps matching.

Truncation is safe because the significant bits of these handles are the lower 32 bits; two distinct monitors cannot collide after truncation.

Tests:

  • DisplayManagerWin32Test.DisplayIdStripsSignExtension: a sign-extended handle produces the 32-bit id.

Fixes #189564

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

HMONITOR handles are 32-bit values that Windows sign-extends to pointer
size in 64-bit processes. Casting one directly to the 64-bit display id
produces values like 0xFFFFFFFFE02E16A5, which no longer fit in the
signed 64-bit integer the id is converted to once it reaches Dart and
trip the converter's range assertion.

Convert HMONITOR to display id in one place,
DisplayManagerWin32::ToDisplayId, which masks the handle to its lower
32 bits, and use it from both FromMonitor and
FlutterWindow::GetDisplayId so the two sides keep producing matching
ids.
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically a: desktop Running on desktop team-windows Owned by the Windows platform team labels Jul 16, 2026
@sero583
sero583 marked this pull request as ready for review July 17, 2026 05:22
@sero583
sero583 requested a review from a team as a code owner July 17, 2026 05:22

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a helper method ToDisplayId in DisplayManagerWin32 to convert HMONITOR handles to FlutterEngineDisplayId by truncating them to 32-bit values, which strips sign extension and prevents representation issues in Dart. The display manager, window implementation, and unit tests have been updated to use this method. There are no review comments, and I have no feedback to provide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically team-windows Owned by the Windows platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[windows] Debug assertion when Windows returns an HMONITOR with the high bit set (sign-extended display id)

1 participant