diff --git a/controls/dev/ItemsView/ItemsView.cpp b/controls/dev/ItemsView/ItemsView.cpp index ddf402ce0f..cb1685e243 100644 --- a/controls/dev/ItemsView/ItemsView.cpp +++ b/controls/dev/ItemsView/ItemsView.cpp @@ -2083,42 +2083,32 @@ void ItemsView::SetItemsViewItemContainerRevokers( itemContainer.SetValue(s_ItemsViewItemContainerRevokersProperty, itemContainerRevokers.as()); - m_itemContainersWithRevokers.insert(tracker_ref{ this, itemContainer }); + m_itemContainersWithRevokers.insert(itemContainer); } void ItemsView::ClearItemsViewItemContainerRevokers( const winrt::ItemContainer& itemContainer) { - const auto& itemContainerRef = tracker_ref{ this, itemContainer }; - const auto& itemContainerSafe = itemContainerRef.safe_get(); - if (itemContainerSafe) - { - RevokeItemsViewItemContainerRevokers(itemContainerSafe); - itemContainerSafe.SetValue(s_ItemsViewItemContainerRevokersProperty, nullptr); - } - const bool removed = static_cast(m_itemContainersWithRevokers.erase(itemContainerRef)); - MUX_ASSERT(removed); + RevokeItemsViewItemContainerRevokers(itemContainer); + itemContainer.SetValue(s_ItemsViewItemContainerRevokersProperty, nullptr); + m_itemContainersWithRevokers.erase(itemContainer); } void ItemsView::ClearAllItemsViewItemContainerRevokers() noexcept { - for (const auto& itemContainerTracker : m_itemContainersWithRevokers) + for (const auto& itemContainer : m_itemContainersWithRevokers) { - const auto& itemContainer = itemContainerTracker.safe_get(); // ClearAllItemsViewItemContainerRevokers is only called in the destructor, where exceptions cannot be thrown. // If the associated ItemsView items have not yet been cleaned up, we must detach these revokers or risk a call into freed // memory being made. However if they have been cleaned up these calls will throw. In this case we can ignore // those exceptions. - if (itemContainer) + try + { + RevokeItemsViewItemContainerRevokers(itemContainer); + itemContainer.SetValue(s_ItemsViewItemContainerRevokersProperty, nullptr); + } + catch (...) { - try - { - RevokeItemsViewItemContainerRevokers(itemContainer); - itemContainer.SetValue(s_ItemsViewItemContainerRevokersProperty, nullptr); - } - catch (...) - { - } } } m_itemContainersWithRevokers.clear(); diff --git a/controls/dev/ItemsView/ItemsView.h b/controls/dev/ItemsView/ItemsView.h index a21a5e31a5..04e0c244e0 100644 --- a/controls/dev/ItemsView/ItemsView.h +++ b/controls/dev/ItemsView/ItemsView.h @@ -399,5 +399,6 @@ class ItemsView : tracker_ref m_bringIntoViewElement{ this }; std::list m_navigationKeysToProcess; - std::set> m_itemContainersWithRevokers; + std::set m_itemContainersWithRevokers; + std::map>> m_itemContainersPointerInfos; }; diff --git a/controls/dev/NavigationView/NavigationView.cpp b/controls/dev/NavigationView/NavigationView.cpp index 8cc71d3284..305bb3c885 100644 --- a/controls/dev/NavigationView/NavigationView.cpp +++ b/controls/dev/NavigationView/NavigationView.cpp @@ -3484,7 +3484,7 @@ void NavigationView::SetNavigationViewItemBaseRevokers(const winrt::NavigationVi auto nvibRevokers = winrt::make_self(); nvibRevokers->visibilityRevoker = RegisterPropertyChanged(nvib, winrt::UIElement::VisibilityProperty(), { this, &NavigationView::OnNavigationViewItemBaseVisibilityPropertyChanged }); nvib.SetValue(s_NavigationViewItemBaseRevokersProperty, nvibRevokers.as()); - m_itemsWithRevokerObjects.insert(tracker_ref{ this, nvib }); + m_itemsWithRevokerObjects.insert(nvib); } void NavigationView::SetNavigationViewItemRevokers(const winrt::NavigationViewItem& nvi) @@ -3503,22 +3503,15 @@ void NavigationView::SetNavigationViewItemRevokers(const winrt::NavigationViewIt void NavigationView::ClearNavigationViewItemBaseRevokers(const winrt::NavigationViewItemBase& nvib) { - const auto& nvibRef = tracker_ref{ this, nvib }; - const auto& nvibSafe = nvibRef.safe_get(); - if (nvibSafe) - { - RevokeNavigationViewItemBaseRevokers(nvibSafe); - nvibSafe.SetValue(s_NavigationViewItemBaseRevokersProperty, nullptr); - } - const bool removed = static_cast(m_itemsWithRevokerObjects.erase(nvibRef)); - MUX_ASSERT(removed); + RevokeNavigationViewItemBaseRevokers(nvib); + nvib.SetValue(s_NavigationViewItemBaseRevokersProperty, nullptr); + m_itemsWithRevokerObjects.erase(nvib); } void NavigationView::ClearAllNavigationViewItemBaseRevokers() noexcept { - for (const auto& nvibTracker : m_itemsWithRevokerObjects) + for (const auto& nvib : m_itemsWithRevokerObjects) { - const auto& nvib = nvibTracker.safe_get(); // ClearAllNavigationViewItemBaseRevokers is only called in the destructor, where exceptions cannot be thrown. // If the associated NV has not yet been cleaned up, we must detach these revokers or risk a call into freed // memory being made. However if they have been cleaned up these calls will throw. In this case we can ignore diff --git a/controls/dev/NavigationView/NavigationView.h b/controls/dev/NavigationView/NavigationView.h index c41e36c14d..d51921a71c 100644 --- a/controls/dev/NavigationView/NavigationView.h +++ b/controls/dev/NavigationView/NavigationView.h @@ -194,7 +194,7 @@ class NavigationView : void ClearNavigationViewItemBaseRevokers(const winrt::NavigationViewItemBase& nvib); void ClearAllNavigationViewItemBaseRevokers() noexcept; void RevokeNavigationViewItemBaseRevokers(const winrt::NavigationViewItemBase& nvib); - std::set> m_itemsWithRevokerObjects; + std::set m_itemsWithRevokerObjects; void InvalidateTopNavPrimaryLayout(); // Measure functions for top navigation diff --git a/dxaml/xcp/core/animation/timer.cpp b/dxaml/xcp/core/animation/timer.cpp index 157f11ea32..aa8c34f2f9 100644 --- a/dxaml/xcp/core/animation/timer.cpp +++ b/dxaml/xcp/core/animation/timer.cpp @@ -6,6 +6,11 @@ #include "Timemgr.h" #include "TimeSpan.h" #include +#include "XamlTelemetry.h" +#include + +// Bug 49537618: [1.5 servicing] DispatcherTimer callbacks are taking much longer on Cadmus +#define WINAPPSDK_CHANGEID_49537618 49537618 _Check_return_ HRESULT CDispatcherTimer::Create( _Outptr_ CDependencyObject **ppObject, @@ -85,6 +90,17 @@ _Check_return_ HRESULT CDispatcherTimer::ComputeStateImpl( // If we've reached the point where the timer should fire, raise the event and start time over. if (timeRemainingInMilliseconds <= 0) { + if (WinAppSdk::Containment::IsChangeEnabled()) + { + TraceLoggingProviderWrite( + XamlTelemetry, "DispatcherTimer_Tick", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingWideString(m_strName.GetBuffer(), "TimerName"), + TraceLoggingUInt64(static_cast(m_pInterval->m_rTimeSpan * 1000.0), "IntervalInMilliseconds"), + TraceLoggingBoolean(!!m_pEventList, "HasListeners"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + } + FireTickEvent(); // Snap the time the DispatcherTimer ticked - the next interval is relative to this point. @@ -167,6 +183,17 @@ _Check_return_ HRESULT CDispatcherTimer::Start() m_rLastTickTime = pTimeManager->GetEstimatedNextTickTime(); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + TraceLoggingProviderWrite( + XamlTelemetry, "DispatcherTimer_Start", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingWideString(m_strName.GetBuffer(), "TimerName"), + TraceLoggingUInt64(static_cast(m_pInterval->m_rTimeSpan * 1000.0), "IntervalInMilliseconds"), + TraceLoggingUInt64(static_cast(m_rLastTickTime * 1000.0), "StartTickTimeInMilliseconds"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + } + // Request a tick to update the timeline. // The browser host and/or frame scheduler can be NULL during shutdown. IXcpBrowserHost *pBH = core->GetBrowserHost(); @@ -198,6 +225,16 @@ _Check_return_ HRESULT CDispatcherTimer::Stop() m_fAddedToManager = FALSE; } + if (WinAppSdk::Containment::IsChangeEnabled()) + { + TraceLoggingProviderWrite( + XamlTelemetry, "DispatcherTimer_Stop", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingWideString(m_strName.GetBuffer(), "TimerName"), + TraceLoggingUInt64(static_cast(m_pInterval->m_rTimeSpan * 1000.0), "IntervalInMilliseconds"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + } + return S_OK; } @@ -216,6 +253,17 @@ _Check_return_ HRESULT CDispatcherTimer::WorkComplete() m_fWorkPending = FALSE; m_rLastTickTime = pTimeManager->GetEstimatedNextTickTime(); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + TraceLoggingProviderWrite( + XamlTelemetry, "DispatcherTimer_TickComplete", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingWideString(m_strName.GetBuffer(), "TimerName"), + TraceLoggingUInt64(static_cast(m_pInterval->m_rTimeSpan * 1000.0), "IntervalInMilliseconds"), + TraceLoggingUInt64(static_cast(m_rLastTickTime * 1000.0), "StartTickTimeInMilliseconds"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + } + // Request a tick to update the timeline. // The browser host and/or frame scheduler can be NULL during shutdown. IXcpBrowserHost *pBH = core->GetBrowserHost(); diff --git a/dxaml/xcp/core/compositor/RefreshAlignedClock.cpp b/dxaml/xcp/core/compositor/RefreshAlignedClock.cpp index 662ec3c376..87dde02fd9 100644 --- a/dxaml/xcp/core/compositor/RefreshAlignedClock.cpp +++ b/dxaml/xcp/core/compositor/RefreshAlignedClock.cpp @@ -3,6 +3,11 @@ #include "precomp.h" #include "RefreshAlignedClock.h" +#include "XamlTelemetry.h" +#include + +// Bug 49537618: [1.5 servicing] DispatcherTimer callbacks are taking much longer on Cadmus +#define WINAPPSDK_CHANGEID_49537618 49537618 //------------------------------------------------------------------------ // @@ -78,6 +83,16 @@ RefreshAlignedClock::Tick() m_lastReportedTime = GetNextTickTimeInSeconds(); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + TraceLoggingProviderWrite( + XamlTelemetry, "RefreshAlignedClock_Tick", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingUInt64(static_cast(m_lastReportedTime * 1000.0), "LastReportedTimeInMilliseconds"), + TraceLoggingUInt64(reinterpret_cast(m_pIClock), "ClockPointer"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + } + return m_lastReportedTime; } @@ -93,31 +108,55 @@ RefreshAlignedClock::GetNextTickTimeInSeconds() const { auto guard = m_Lock.lock(); // can be called from ui thread + compositor thread simultaneously - XDOUBLE refreshIntervalInSeconds; - - if (m_pRefreshRateInfo != NULL) + if (WinAppSdk::Containment::IsChangeEnabled()) { - refreshIntervalInSeconds = static_cast(m_pRefreshRateInfo->GetRefreshIntervalInMilliseconds()) / 1000.0; + double currentTime = m_pIClock->GetAbsoluteTimeInSeconds(); + + // Make sure time never flows backwards. If we calculated something less than the last reported time, just return + // the last reported time. + if (currentTime < m_lastReportedTime) + { + TraceLoggingProviderWrite( + XamlTelemetry, "RefreshAlignedClock_GetNextTickTimeInSeconds_TimeMovedBackwards", + TraceLoggingUInt64(reinterpret_cast(this), "ObjectPointer"), + TraceLoggingUInt64(static_cast(currentTime * 1000.0), "CurrentTimeInMilliseconds"), + TraceLoggingUInt64(static_cast(m_lastReportedTime * 1000.0), "LastReportedTimeInMilliseconds"), + TraceLoggingUInt64(reinterpret_cast(m_pIClock), "ClockPointer"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); + + currentTime = m_lastReportedTime; + } + + return currentTime; } else { - // The refresh rate can't be read from the system yet. - refreshIntervalInSeconds = static_cast(DefaultRefreshIntervalInMilliseconds) / 1000.0; + XDOUBLE refreshIntervalInSeconds; + + if (m_pRefreshRateInfo != NULL) + { + refreshIntervalInSeconds = static_cast(m_pRefreshRateInfo->GetRefreshIntervalInMilliseconds()) / 1000.0; + } + else + { + // The refresh rate can't be read from the system yet. + refreshIntervalInSeconds = static_cast(DefaultRefreshIntervalInMilliseconds) / 1000.0; + } + + // Round time forward to the refresh rate interval. + XDOUBLE unroundedTime = static_cast(m_pIClock->GetAbsoluteTimeInSeconds()); + XDOUBLE roundedTime = static_cast(XcpCeiling(unroundedTime / refreshIntervalInSeconds)) * refreshIntervalInSeconds; + XDOUBLE tolerance = 0.00001; // allow 0.01ms error + + // Make sure we advance time by at least a frame each time the composition thread ticks. + if (roundedTime <= m_lastReportedTime + tolerance) + { + roundedTime = m_lastReportedTime + refreshIntervalInSeconds; + } + + ASSERT(roundedTime > m_lastReportedTime); + return roundedTime; } - - // Round time forward to the refresh rate interval. - XDOUBLE unroundedTime = static_cast(m_pIClock->GetAbsoluteTimeInSeconds()); - XDOUBLE roundedTime = static_cast(XcpCeiling(unroundedTime / refreshIntervalInSeconds)) * refreshIntervalInSeconds; - XDOUBLE tolerance = 0.00001; // allow 0.01ms error - - // Make sure we advance time by at least a frame each time the composition thread ticks. - if (roundedTime <= m_lastReportedTime + tolerance) - { - roundedTime = m_lastReportedTime + refreshIntervalInSeconds; - } - - ASSERT(roundedTime > m_lastReportedTime); - return roundedTime; } //------------------------------------------------------------------------ diff --git a/dxaml/xcp/core/core/elements/DragEventArgs.cpp b/dxaml/xcp/core/core/elements/DragEventArgs.cpp index b934ad05c1..04c9100d95 100644 --- a/dxaml/xcp/core/core/elements/DragEventArgs.cpp +++ b/dxaml/xcp/core/core/elements/DragEventArgs.cpp @@ -6,6 +6,11 @@ #include "Activators.g.h" #include +#include + +// Bug 49668748: [1.5 Servicing] After dragging an FE Home item, all item drops on breadcrumbs don't support Move after first drag +#define LOCAL_WINAPPSDK_CHANGEID_49668748 49668748 + // Initialize the DragEventArgs with any framework specific context. _Check_return_ HRESULT CDragEventArgs::Create(_In_ CCoreServices* pCore, _Outptr_ CDragEventArgs** ppArgs, _In_opt_ IInspectable* pWinRtDragInfo, _In_opt_ IInspectable* pDragDropAsyncOperation) @@ -19,6 +24,16 @@ _Check_return_ HRESULT CDragEventArgs::Create(_In_ CCoreServices* pCore, _Outptr if(pWinRtDragInfo) { IFC_RETURN(spArgs->m_spWinRtDragInfo.reset(pWinRtDragInfo)); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + wrl::ComPtr dragInfo; + if (SUCCEEDED(pWinRtDragInfo->QueryInterface(IID_PPV_ARGS(&dragInfo)))) + { + wadt::DataPackageOperation allowedOperations; + IFC_RETURN(dragInfo->get_AllowedOperations(&allowedOperations)); + IFC_RETURN(spArgs->put_AllowedOperations(static_cast(allowedOperations))); + } + } } if(pDragDropAsyncOperation) diff --git a/dxaml/xcp/core/core/elements/Popup.cpp b/dxaml/xcp/core/core/elements/Popup.cpp index fe4cf6638d..bfe7601989 100644 --- a/dxaml/xcp/core/core/elements/Popup.cpp +++ b/dxaml/xcp/core/core/elements/Popup.cpp @@ -43,6 +43,11 @@ #include "WinRTExpressionConversionContext.h" #include "VisualDebugTags.h" #include "xcpwindow.h" +#include + +// Bug 49613456: [1.5 servicing] [GitHub] AutoSuggestBox, ComboBox, (probably others) no longer transform their popups correctly in WindowsAppSDK 1.4 +#define WINAPPSDK_CHANGEID_49613456 49613456 + using namespace DirectUI; using namespace Focus; @@ -1396,9 +1401,11 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup() IFC_RETURN(EnsureOuterBounds(nullptr)); // Get popup's bounds relative to the CoreWindow or Win32 app bounds - // Note: The returned popupBounds will have the plateau zoom scale applied + // Note: The returned popupBoundsPhysical will have the plateau zoom scale applied XRECTF popupBoundsPhysical = {}; - IFC_RETURN(GetPhysicalBounds(this, &popupBoundsPhysical)); + float scaleX = 1.0f; + float scaleY = 1.0f; + IFC_RETURN(GetPhysicalBounds(this, &popupBoundsPhysical, &scaleX, &scaleY)); // Find the offset to the root in physical pixels. This is either XAML's main CoreWindow, // or the associated XamlIslandRoot. @@ -1480,12 +1487,12 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup() // // // - // Popup p's content c should render with the transform a-b-p-c. This is also the offset that should be applied to the + // Popup p's child c should render with the transform a-b-p-c. This is also the offset that should be applied to the // popup's hwnd. Xaml rendering code will automatically produce a comp node (and a Composition Visual) for the popup // element, with its transform p already set, and a visual for the popup content with its transform c set on it. // If we just put these visuals inside the hwnd, we'll end up with the transform (a-b-p-c)-p-c. This double counts // two transforms and produces the wrong result. So we apply an undo transform under the hwnd to make sure the net - // transform is what we want. We'll have + // offset is what we want. We'll have // // (a-b-p-c)-(c'-p')-(p)-(c) = a-b-p-c // ^ ^ ^ ^ @@ -1497,7 +1504,14 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup() // | // +- applied by the hwnd // - // where c' and p' are inverse transforms of c and p + // where c' and p' are inverse transforms of c and p + // + // Note that this is just the offset. In addition we can potentially inherit a scale from the popup's ancestors as + // well. This scale can't be baked into the hwnd, so we have to apply it in the subtree under the hwnd. It should be + // applied at the m_contentIslandRootVisual, where it covers any potential shadows, backdrops, and animations (see + // the banner comment on EnsureWindowedPopupRootVisualTree for the full visual tree). In terms of the transform + // chain, it should take the place of (a-b-p-c). Under it should be the undo transform, and under that should be the + // transforms in the comp node. // bool isParentedPopup = IsActive(); @@ -1569,9 +1583,23 @@ _Check_return_ HRESULT CPopup::PositionAndSizeWindowForWindowedPopup() if (m_contentIslandRootVisual) { - // Set premultiplied "undo" transform on the window's root visual + // Set any scale inherited from the ancestor chain CMILMatrix rootTransform(true); - rootTransform.AppendTranslation(undoX, undoY); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + rootTransform.SetM11(scaleX); + rootTransform.SetM22(scaleY); + + // Set premultiplied "undo" transform on the window's root visual + CMILMatrix undo(true); + undo.SetDx(undoX); + undo.SetDy(undoY); + rootTransform.Prepend(undo); + } + else + { + rootTransform.AppendTranslation(undoX, undoY); + } if (isParentedPopup && IsRightToLeft()) { @@ -1799,13 +1827,14 @@ void CPopup::ApplyRootRoundedCornerClipToSystemBackdrop() } } -_Check_return_ HRESULT CPopup::GetPhysicalBounds(_In_ CUIElement* element, _Out_ XRECTF* physicalBounds) +_Check_return_ HRESULT CPopup::GetPhysicalBounds(_In_ CUIElement* element, _Out_ XRECTF* physicalBounds, _Out_ float* scaleX, _Out_ float* scaleY) { *physicalBounds = {}; CUIElement* elementForBounds = element; CUIElement* elementForPosition = element; float left = 0; float top = 0; + XRECTF oneByOneTransformed = {0, 0, 1, 1}; bool useActualBounds = RuntimeFeatureBehavior::GetRuntimeEnabledFeatureDetector()->IsFeatureEnabled(RuntimeFeatureBehavior::RuntimeEnabledFeature::WindowedPopupActualBoundsMode); if (auto popup = do_pointer_cast(element)) @@ -1837,6 +1866,11 @@ _Check_return_ HRESULT CPopup::GetPhysicalBounds(_In_ CUIElement* element, _Out_ IFC_RETURN(elementForPosition->TransformToVisual(nullptr, &transform)); IFC_RETURN(transform->TransformRect({ left, top, elementForBounds->GetActualWidth(), elementForBounds->GetActualHeight() }, physicalBounds)); DipsToPhysicalPixelsRect(physicalBounds); + + if (WinAppSdk::Containment::IsChangeEnabled()) + { + IFC_RETURN(transform->TransformRect(oneByOneTransformed, &oneByOneTransformed)); + } } else { @@ -1853,6 +1887,11 @@ _Check_return_ HRESULT CPopup::GetPhysicalBounds(_In_ CUIElement* element, _Out_ IFC_RETURN(elementForPosition->TransformToVisual(nullptr, &transform)); IFC_RETURN(transform->TransformRect({ 0, 0, elementForBounds->UnclippedDesiredSize.width, elementForBounds->UnclippedDesiredSize.height }, physicalBounds)); DipsToPhysicalPixelsRect(physicalBounds); + + if (WinAppSdk::Containment::IsChangeEnabled()) + { + IFC_RETURN(transform->TransformRect(oneByOneTransformed, &oneByOneTransformed)); + } } else { @@ -1863,6 +1902,13 @@ _Check_return_ HRESULT CPopup::GetPhysicalBounds(_In_ CUIElement* element, _Out_ } } + // Note: These assume that the transform was axis-aligned. We don't support windowed popups with rotations above them. + if (WinAppSdk::Containment::IsChangeEnabled()) + { + *scaleX = oneByOneTransformed.Width; + *scaleY = oneByOneTransformed.Height; + } + // In addition to the contents in the windowed popup, also union in all the non-windowed popups that are nested // inside this windowed popup's. They must live in the same island as the windowed popup so that they won't be // covered by the windowed popup, and their bounds weren't included when we bounded the popup. See diff --git a/dxaml/xcp/core/inc/Popup.h b/dxaml/xcp/core/inc/Popup.h index 8b952df750..0955dfdd7d 100644 --- a/dxaml/xcp/core/inc/Popup.h +++ b/dxaml/xcp/core/inc/Popup.h @@ -66,7 +66,7 @@ struct ImplicitCloseGuard // which needs to be transformed from the pointer's target window to the // root window (see DxamlCore::GetTranslationFromTargetWindowToRootWindow), // and initialization of DirectManipulationContainer, which needs to -// use the popup's island input site's window (see +// use the popup's island input site's window (see // CInputServices::InitializeDirectManipulationContainer's usage of // CDependencyObject::GetElementIslandInputSite.) // - Windowed popups must be closed when the Jupiter window is moved, because @@ -443,7 +443,7 @@ class CPopup : public CFrameworkElement _Check_return_ HRESULT HideWindowForWindowedPopup(); _Check_return_ HRESULT PositionAndSizeWindowForWindowedPopup(); bool MeetsRenderingRequirementsForWindowedPopup(); - _Check_return_ HRESULT GetPhysicalBounds(_In_ CUIElement* element, _Out_ XRECTF* physicalBounds); + _Check_return_ HRESULT GetPhysicalBounds(_In_ CUIElement* element, _Out_ XRECTF* physicalBounds, _Out_ float* scaleX, _Out_ float* scaleY); _Check_return_ HRESULT AdjustWindowedPopupBoundsForDropShadow(_In_ const XRECTF* popupWindowBounds); bool ShouldPopupRendersDropShadow() const; XTHICKNESS GetInsetsForDropShadow(); diff --git a/dxaml/xcp/dxaml/lib/ModernCollectionBasePanel_IICG2_Partial.cpp b/dxaml/xcp/dxaml/lib/ModernCollectionBasePanel_IICG2_Partial.cpp index 57d309eab5..2df799bb4a 100644 --- a/dxaml/xcp/dxaml/lib/ModernCollectionBasePanel_IICG2_Partial.cpp +++ b/dxaml/xcp/dxaml/lib/ModernCollectionBasePanel_IICG2_Partial.cpp @@ -7,6 +7,10 @@ #include "ScrollViewer.g.h" #include "VisualTreeHelper.h" #include "DataTemplate.g.h" +#include + +// Bug 49618076: [1.5 servicing] File Explorer crashes when Home directory is selected in address bar and hitting Enter +#define WINAPPSDK_CHANGEID_49618076 49618076 #pragma warning(disable:4267) //'var' : conversion from 'size_t' to 'type', possible loss of data @@ -787,6 +791,16 @@ _Check_return_ HRESULT ModernCollectionBasePanel::RecycleLinkedContainer(_In_ xa // focus to jump when the container gets reused. IFC_RETURN(spContainer.Cast()->put_IsGamepadFocusCandidate(FALSE)); + if (WinAppSdk::Containment::IsChangeEnabled()) + { + // Declare the container not focusable in general so that it cannot be selected as + // a focus candidate. This is to handle the rare case where a focus selection is + // imminently made before the next measure pass (i.e. before the next execution of + // ModernCollectionBasePanel::MeasureElementsInGarbageSection() where recycled items are + // marked unfocusable in the common cases via a SetElementSizeInGarbageSection call). + SetElementEmptySizeInGarbageSection(spContainer); + } + TraceVirtualizedItemRemovedInfo((UINT64)spContainer.Cast()->GetHandle()); // Only containers that are not items are eligible for recycling. diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 98c77fa6db..a9ded409a5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,17 +2,17 @@ - + https://dev.azure.com/microsoft/ProjectReunion/_git/WindowsAppSDK - 6717f9fc2c0da67b14f74e7854ade9d22933ee63 + 9aaec9a42d35cecdefb1418a855d95d741155a9f - + https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP - c2021b41a2c423f3ab83d1de51218b9df521fb8f + 6b9f6f6f4f2977b56b347e943e6804b29886ed19 - + https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP - c2021b41a2c423f3ab83d1de51218b9df521fb8f + 6b9f6f6f4f2977b56b347e943e6804b29886ed19