Skip to content

[0.84] fix: correct CompositionHwndHost initialization order for DPI-aware second windows#16148

Open
gmacmaster wants to merge 2 commits into
microsoft:0.84-stablefrom
Virtual-Fulfillment-Technologies-Inc:vendora/second-screen-touch-fix
Open

[0.84] fix: correct CompositionHwndHost initialization order for DPI-aware second windows#16148
gmacmaster wants to merge 2 commits into
microsoft:0.84-stablefrom
Virtual-Fulfillment-Technologies-Inc:vendora/second-screen-touch-fix

Conversation

@gmacmaster
Copy link
Copy Markdown
Contributor

@gmacmaster gmacmaster commented May 18, 2026

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Why

CompositionHwndHost::Initialize() connected the ContentIsland to the DesktopChildSiteBridge before setting the ResizePolicy, causing the island's coordinate space to be configured without proper DPI awareness. This led to InputPointerSource delivering touch coordinates that did not account for the display's scale factor on secondary windows at non-100% zoom.

What

Initialization reorder (CompositionHwndHost.cpp / .h):

  • Promoted DesktopChildSiteBridge from a local variable to a member (m_bridge) so it survives past Initialize().
  • Reordered Initialize() so that ResizePolicy is set before Connect, and ScaleFactor is set before the island is connected — matching the ReactNativeWindow::ContentSiteBridge reference pattern.

Runtime DPI changes (e.g., moving the window between monitors with different scales) are already handled by ReactNativeIsland's ContentIsland::StateChanged subscription, which responds to DidRasterizationScaleChange() and calls ScaleFactor()Arrange() directly.

Screenshots

N/A — this is a behavioral/layout correctness fix; the visual result is that touch input on secondary windows at non-100% DPI now aligns correctly with their visual positions.

Testing

Verified locally by:

  1. Launching a React Native Windows app with a second CompositionHwndHost window on a 150% DPI display — touch targets now align correctly with their visual positions.
  2. Moving the window between monitors with different DPI settings — layout remains correct (handled by ReactNativeIsland's RasterizationScaleChanged subscription).

Changelog

Should this change be included in the release notes: yes

Fix CompositionHwndHost initialization order so that ResizePolicy is set before Connect and ScaleFactor before the island is connected, ensuring secondary windows render with correct DPI-aware touch coordinates.

…econd windows (#7)

* fix: correct CompositionHwndHost initialization order for DPI-aware second windows

CompositionHwndHost::Initialize() connected the ContentIsland to the
DesktopChildSiteBridge before setting the ResizePolicy, causing the
island's coordinate space to be configured without proper DPI awareness.
This led to InputPointerSource delivering touch coordinates that did not
account for the display's scale factor on secondary windows at non-100%
zoom.
Reorders initialization to match ReactNativeWindow::ContentSiteBridge():
ResizePolicy is now set before Connect, and ScaleFactor is set before
the island is connected.
Also adds WM_DPICHANGED handling to TranslateMessage so the island's
scale factor and layout are updated if the display DPI changes at runtime.

* Update CompositionHwndHost.cpp

* Update CompositionHwndHost.cpp

* host lost on function return

* Update CompositionHwndHost.cpp

* Create react-native-windows-c628c673-e01f-4887-9fcf-b1e5c468d311.json
@gmacmaster gmacmaster requested a review from a team as a code owner May 18, 2026 19:23
@gmacmaster gmacmaster changed the title fix: correct CompositionHwndHost initialization order for DPI-aware second windows [0.84] fix: correct CompositionHwndHost initialization order for DPI-aware second windows May 18, 2026
@gmacmaster
Copy link
Copy Markdown
Contributor Author

Will create port to main if this looks good

@acoates-ms
Copy link
Copy Markdown
Contributor

Do we need the WM_DPICHANGED handler? Don't we get a RasterizationScaleChange from the ContentIsland?

pThis->ScaleFactor(island.RasterizationScale());


HWND m_hwnd;
winrt::Microsoft::ReactNative::ReactNativeIsland m_compRootView{nullptr};
winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr};
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.

And now we dont need to store the DesktopChildSiteBridge...

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.

2 participants