4040#include " XamlRoot_Partial.h"
4141#include < Microsoft.UI.Composition.h>
4242#include < FrameworkUdk/Theming.h>
43+ #include < FrameworkUdk/Containment.h>
44+
45+ #define WINAPPSDK_CHANGEID_61884734 61884734 , WinAppSDK_1_8_8
4346#include " WinRTExpressionConversionContext.h"
4447#include " VisualDebugTags.h"
4548#include " xcpwindow.h"
@@ -1328,6 +1331,27 @@ float CPopup::GetWindowedPopupRasterizationScale() const
13281331 return rasterizationScale;
13291332}
13301333
1334+ float CPopup::GetWindowedPopupRootVisualScaleCompensation () const
1335+ {
1336+ // Windowed popups render in a separate ContentIsland whose RasterizationScale is driven by the system (popup HWND DPI).
1337+ // For XAML Islands, the effective XamlRoot scale may be overridden (e.g. DesktopWindowXamlSource.OverrideScale).
1338+ // The main island cancels/adjusts system scale via RootScale. Windowed popups need the same compensation.
1339+ if (!m_contentIsland)
1340+ {
1341+ return 1 .0f ;
1342+ }
1343+
1344+ const float systemScaleForPopupIsland = GetWindowedPopupRasterizationScale ();
1345+ const float effectiveScaleForPopup = GetEffectiveRootScale ();
1346+
1347+ if (systemScaleForPopupIsland <= 0 .0f || effectiveScaleForPopup <= 0 .0f )
1348+ {
1349+ return 1 .0f ;
1350+ }
1351+
1352+ return effectiveScaleForPopup / systemScaleForPopupIsland;
1353+ }
1354+
13311355wrl::ComPtr<ixp::IPointerPoint> CPopup::GetPreviousPointerPoint ()
13321356{
13331357 return m_inputSiteAdapter->GetPreviousPointerPoint ();
@@ -1627,12 +1651,26 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup()
16271651 undoY += insets.top ;
16281652 }
16291653
1654+ float rootScaleCompensation = 1 .0f ;
1655+ if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_61884734 >())
1656+ {
1657+ rootScaleCompensation = GetWindowedPopupRootVisualScaleCompensation ();
1658+ }
1659+
16301660 if (m_contentIslandRootVisual)
16311661 {
16321662 // Set any scale inherited from the ancestor chain
16331663 CMILMatrix rootTransform (true );
1634- rootTransform.SetM11 (scaleX);
1635- rootTransform.SetM22 (scaleY);
1664+ if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_61884734 >())
1665+ {
1666+ rootTransform.SetM11 (scaleX * rootScaleCompensation);
1667+ rootTransform.SetM22 (scaleY * rootScaleCompensation);
1668+ }
1669+ else
1670+ {
1671+ rootTransform.SetM11 (scaleX);
1672+ rootTransform.SetM22 (scaleY);
1673+ }
16361674
16371675 // Set premultiplied "undo" transform on the window's root visual
16381676 CMILMatrix undo (true );
@@ -1682,11 +1720,26 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup()
16821720 // Tell the windowed popup inputsite adapter the offset of the popup window from the content
16831721 // root. We do this by using the position passed to MoveAndSize (either earlier in this function
16841722 // or updated by AdjustWindowedPopupBoundsForDropShadow), converted to island coords in dips.
1685- wf::Point transformedOffset{
1686- PhysicalPixelsToDips (static_cast <float >(m_windowedPopupMoveAndResizeRect.X - rootOffsetPhysical.x )),
1687- PhysicalPixelsToDips (static_cast <float >(m_windowedPopupMoveAndResizeRect.Y - rootOffsetPhysical.y ))};
1723+ if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_61884734 >())
1724+ {
1725+ const float popupIslandRasterizationScale = m_contentIsland ? GetWindowedPopupRasterizationScale () : 0 .0f ;
1726+ const float offsetXPhysical = static_cast <float >(m_windowedPopupMoveAndResizeRect.X - rootOffsetPhysical.x );
1727+ const float offsetYPhysical = static_cast <float >(m_windowedPopupMoveAndResizeRect.Y - rootOffsetPhysical.y );
1728+
1729+ wf::Point transformedOffset{
1730+ popupIslandRasterizationScale > 0 .0f ? (offsetXPhysical / popupIslandRasterizationScale) : PhysicalPixelsToDips (offsetXPhysical),
1731+ popupIslandRasterizationScale > 0 .0f ? (offsetYPhysical / popupIslandRasterizationScale) : PhysicalPixelsToDips (offsetYPhysical)};
1732+
1733+ IFC_RETURN (UpdateTranslationFromContentRoot (transformedOffset, /* forceUpdate*/ false , rootScaleCompensation));
1734+ }
1735+ else
1736+ {
1737+ wf::Point transformedOffset{
1738+ PhysicalPixelsToDips (static_cast <float >(m_windowedPopupMoveAndResizeRect.X - rootOffsetPhysical.x )),
1739+ PhysicalPixelsToDips (static_cast <float >(m_windowedPopupMoveAndResizeRect.Y - rootOffsetPhysical.y ))};
16881740
1689- IFC_RETURN (UpdateTranslationFromContentRoot (transformedOffset, /* forceUpdate*/ false ));
1741+ IFC_RETURN (UpdateTranslationFromContentRoot (transformedOffset, /* forceUpdate*/ false ));
1742+ }
16901743
16911744 // Play the MenuPopupThemeTransition, if we have one
16921745 if (m_animationRootVisual && m_secretTransitionTarget && m_secretTransitionTarget->IsDirty ())
@@ -2296,9 +2349,9 @@ HWND CPopup::GetPopupPositioningWindow() const
22962349}
22972350
22982351// Converts between logical and physical pixels
2299- float CPopup::GetEffectiveRootScale ()
2352+ float CPopup::GetEffectiveRootScale () const
23002353{
2301- const auto scale = RootScale::GetRasterizationScaleForElement (this );
2354+ const auto scale = RootScale::GetRasterizationScaleForElement (const_cast <CPopup*>( this ) );
23022355 return scale;
23032356}
23042357
@@ -2714,7 +2767,7 @@ CPopup::ClearUCRemoveLogicalParentFlag(
27142767//
27152768// ------------------------------------------------------------------------
27162769_Check_return_ HRESULT
2717- CPopup::UpdateTranslationFromContentRoot (const wf::Point& offset, bool forceUpdate)
2770+ CPopup::UpdateTranslationFromContentRoot (const wf::Point& offset, bool forceUpdate, float rootScaleCompensation )
27182771{
27192772 IFCEXPECT_RETURN (m_inputSiteAdapter);
27202773
@@ -2725,6 +2778,16 @@ CPopup::UpdateTranslationFromContentRoot(const wf::Point& offset, bool forceUpda
27252778 m_offsetFromMainWindow.X = offset.X ;
27262779 m_offsetFromMainWindow.Y = offset.Y ;
27272780
2781+ // Pointer points for windowed popups are delivered in the coordinate space of the popup's content island.
2782+ // When DesktopWindowXamlSource.OverrideScale is used, the popup island's rasterization scale (system DPI)
2783+ // can differ from the XamlRoot effective scale. We compensate the visuals by scaling the island root visual;
2784+ // mirror that compensation for input by scaling pointer coordinates by the inverse ratio.
2785+ float inputScaleCompensation = 1 .0f ;
2786+ if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_61884734 >())
2787+ {
2788+ inputScaleCompensation = (rootScaleCompensation != 0 .0f ) ? (1 .0f / rootScaleCompensation) : 1 .0f ;
2789+ }
2790+
27282791 auto dxamlCore = DXamlCore::GetCurrent ();
27292792 auto coreServices = dxamlCore->GetHandle ();
27302793 CREATEPARAMETERS cp (coreServices);
@@ -2734,6 +2797,12 @@ CPopup::UpdateTranslationFromContentRoot(const wf::Point& offset, bool forceUpda
27342797 xref_ptr<CMatrix> matrix;
27352798 xref_ptr<CMatrixTransform> matrixTransform;
27362799
2800+ if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_61884734 >())
2801+ {
2802+ matTransform.SetM11 (inputScaleCompensation);
2803+ matTransform.SetM22 (inputScaleCompensation);
2804+ }
2805+
27372806 IFC_RETURN (CMatrixTransform::Create (reinterpret_cast <CDependencyObject**>(matrixTransform.ReleaseAndGetAddressOf ()), &cp));
27382807 IFC_RETURN (CMatrix::Create (reinterpret_cast <CDependencyObject**>(matrix.ReleaseAndGetAddressOf ()), &cp));
27392808
0 commit comments