Skip to content

Commit

Permalink
Syncing content from committish release/1.4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
reunion-maestro-bot committed Nov 20, 2023
1 parent 7198c4e commit 685d2bf
Show file tree
Hide file tree
Showing 38 changed files with 776 additions and 167 deletions.
21 changes: 0 additions & 21 deletions controls/LICENSE

This file was deleted.

23 changes: 23 additions & 0 deletions controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include "ResourceAccessor.h"
#include "TypeLogging.h"
#include "Vector.h"
#include "velocity.h"
#include <FrameworkUdk/Containment.h>

// Bug 47050253: [1.4 servicing] Insiders report that even with the latest bug fixes in the dev channel they can still see the context menu with a transparent background sometimes
#define WINAPPSDK_CHANGEID_47050253 47050253

CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
{
Expand Down Expand Up @@ -159,6 +164,19 @@ CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
});
}

CommandBarFlyoutCommandBar::~CommandBarFlyoutCommandBar()
{
if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_47050253>())
{
// The SystemBackdrop DP has already been cleared out. Use our cached field.
if (auto systemBackdrop = m_systemBackdrop.get())
{
systemBackdrop.OnTargetDisconnected(m_backdropLink);
systemBackdrop.OnTargetDisconnected(m_overflowPopupBackdropLink);
}
}
}

void CommandBarFlyoutCommandBar::OnApplyTemplate()
{
COMMANDBARFLYOUT_TRACE_INFO(*this, TRACE_MSG_METH, METH_NAME, this);
Expand Down Expand Up @@ -1419,6 +1437,11 @@ void CommandBarFlyoutCommandBar::OnPropertyChanged(const winrt::DependencyProper
oldSystemBackdrop.OnTargetDisconnected(m_overflowPopupBackdropLink);
}

if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_47050253>())
{
m_systemBackdrop = newSystemBackdrop;
}

if (newSystemBackdrop)
{
if (!m_backdropLink)
Expand Down
7 changes: 7 additions & 0 deletions controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class CommandBarFlyoutCommandBar :
{
public:
CommandBarFlyoutCommandBar();
~CommandBarFlyoutCommandBar();

// IFrameworkElementOverrides
void OnApplyTemplate();
Expand Down Expand Up @@ -131,6 +132,12 @@ class CommandBarFlyoutCommandBar :
winrt::ContentExternalBackdropLink m_backdropLink{ nullptr };
winrt::ContentExternalBackdropLink m_overflowPopupBackdropLink{ nullptr };

// A copy of the value in the DependencyProperty. We need to unregister with this SystemBackdrop when this
// CommandBarFlyoutCommandBar is deleted, but the DP value is already cleared by the time we get to Unloaded or the
// dtor, so we cache a copy for ourselves to use during cleanup. Another possibility is to do cleanup during Closed,
// but the app can release and delete this CommandBarFlyoutCommandBar without ever closing it.
weak_ref<winrt::SystemBackdrop> m_systemBackdrop{ nullptr };

// Localized string caches. Looking these up from MRTCore is expensive, so we don't want to put the lookups in a
// loop. Instead, look them up once, cache them, use the cached values, then clear the cache. The values in these
// caches are only valid after CacheLocalizedStringResources and before ClearLocalizedStringResourceCache.
Expand Down
2 changes: 1 addition & 1 deletion dxaml/xcp/components/AccessKeys/inc/ScopeTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ namespace AccessKeys {
// We successfully found an element to be invoked, but it failed to find a valid pattern. As a result, we will give focus to the element
if (!invokeResult.invokeFoundValidPattern)
{
if (FocusProperties::IsFocusable(invokedElement.get()))
if (FocusProperties::IsFocusable(invokedElement.get(), false /*ignoreOffScreenPosition*/))
{
const Focus::FocusMovementResult result = m_pFocusManager->SetFocusedElement(
Focus::FocusMovement(
Expand Down
3 changes: 2 additions & 1 deletion dxaml/xcp/components/elements/UIElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ CUIElement::CUIElement(_In_ CCoreServices* core)
, m_childBoundsDirty(TRUE)
, m_combinedInnerBoundsDirty(TRUE)
, m_outerBoundsDirty(TRUE)
, m_skipFocusSubtree()
, m_skipFocusSubtree_OffScreenPosition()
, m_skipFocusSubtree_Other()
, m_contentInnerBounds()
, m_childBounds()
, m_combinedInnerBounds()
Expand Down
12 changes: 6 additions & 6 deletions dxaml/xcp/components/focus/FocusProperties/FocusProperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ bool IsEnabled<CDependencyObject>(_In_ CDependencyObject* const object)

//Determine if a particular DependencyObject cares to take focus.
template<>
bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object)
bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object, bool ignoreOffScreenPosition)
{
bool isFocusable = false;

xref_ptr<CUIElement> objectAsUI;

if (SUCCEEDED(DoPointerCast(objectAsUI, object)) && objectAsUI->SkipFocusSubtree())
if (SUCCEEDED(DoPointerCast(objectAsUI, object)) && objectAsUI->SkipFocusSubtree(ignoreOffScreenPosition))
{
return false;
}
Expand All @@ -125,7 +125,7 @@ bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object)
CControl* control = static_cast<CControl*>(object);

ASSERT(control);
isFocusable = IsFocusable(control);
isFocusable = IsFocusable(control, ignoreOffScreenPosition);
}
else if (IFocusable* ifocusable = CFocusableHelper::GetIFocusableForDO(object))
{
Expand All @@ -135,7 +135,7 @@ bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object)
{
if (objectAsUI)
{
isFocusable = IsFocusable(objectAsUI.get());
isFocusable = IsFocusable(objectAsUI.get(), ignoreOffScreenPosition);
}
}

Expand Down Expand Up @@ -207,7 +207,7 @@ bool CanHaveFocusableChildren<CDependencyObject>(_In_ CDependencyObject* const p
child->OfTypeByIndex<KnownTypeIndex::RichTextBlock>() ||
child->OfTypeByIndex<KnownTypeIndex::RichTextBlockOverflow>())
{
if (IsFocusable(child.get()) && IsPotentialTabStop(child.get()))
if (IsFocusable(child.get(), false /*ignoreOffScreenPosition*/) && IsPotentialTabStop(child.get()))
{
isFocusable = true;
}
Expand All @@ -221,7 +221,7 @@ bool CanHaveFocusableChildren<CDependencyObject>(_In_ CDependencyObject* const p
}
else
{
if (IsFocusable(child.get()))
if (IsFocusable(child.get(), false /*ignoreOffScreenPosition*/))
{
isFocusable = true;
}
Expand Down
2 changes: 1 addition & 1 deletion dxaml/xcp/components/focus/XYFocus/inc/Focusability.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Focus { namespace XYFocusPrivate {
template<class Element>
bool IsValidCandidate(_In_ Element* const element)
{
const bool isFocusable = FocusProperties::IsFocusable(element);
const bool isFocusable = FocusProperties::IsFocusable(element, false /*ignoreOffScreenPosition*/);
const bool isGamepadFocusCandidate = FocusProperties::IsGamepadFocusCandidate(element);
const bool isRootScrollViewer = element->template OfTypeByIndex<KnownTypeIndex::RootScrollViewer>();
const bool isValidTabStop = FocusProperties::IsPotentialTabStop(element);
Expand Down
4 changes: 2 additions & 2 deletions dxaml/xcp/components/focus/inc/FocusProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace FocusProperties
}

template<class DependencyObject>
bool IsFocusable(_In_ DependencyObject* const object)
bool IsFocusable(_In_ DependencyObject* const object, bool ignoreOffScreenPosition)
{
return object->IsFocusable() == TRUE;
}
Expand Down Expand Up @@ -92,7 +92,7 @@ namespace FocusProperties
template<> bool IsVisible<CDependencyObject>(_In_ CDependencyObject* const object);
template<> bool AreAllAncestorsVisible<CDependencyObject>(_In_ CDependencyObject* const object);
template<> bool IsEnabled<CDependencyObject>(_In_ CDependencyObject* const object);
template<> bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object);
template<> bool IsFocusable<CDependencyObject>(_In_ CDependencyObject* const object, bool ignoreOffScreenPosition);
template<> bool IsPotentialTabStop<CDependencyObject>(_In_ CDependencyObject* const object);
template<> bool CanHaveFocusableChildren<CDependencyObject>(_In_ CDependencyObject* const parent);
template<> bool IsFocusEngagementEnabled<CDependencyObject>(_In_ CDependencyObject* const object);
Expand Down
40 changes: 37 additions & 3 deletions dxaml/xcp/components/mrt/ModernResourceProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,43 @@ HRESULT ModernResourceProvider::UpdateLanguageAndLayoutDirectionQualifiers()
// Windows components use the Windows display language, can lead to an
// inconsistent language experience if WinUI 3 always uses
// ApplicationLanguages.Languages.
wchar_t lpLocaleName[LOCALE_NAME_MAX_LENGTH];
IFC_RETURN(GetUserDefaultLocaleName(lpLocaleName, LOCALE_NAME_MAX_LENGTH));
primaryLanguageName.Attach(wrl_wrappers::HStringReference(lpLocaleName).Get());
// We need to use GetUserDefaultUILanguage() to get the Windows display language,
// GetUserDefaultLocaleName() will return the "Regional format"/sort order instead
// if it has been set which could also be inconsistent with other OS UI.
// Example of setting the sort order:
// Win+R -> intl.cpl -> "Change sorting method" -> "Format": "German (Germany)" ->
// "Change sorting method" -> "Select the sorting method:" "Phone book (DIN)"
boolean isLocaleValid = false;
boolean isWellFormedLanguage = false;

wrl::ComPtr<wg::ILanguageStatics> languageStatics;
IFC_RETURN(wf::GetActivationFactory(
wrl_wrappers::HStringReference(RuntimeClass_Windows_Globalization_Language).Get(),
&languageStatics));

wchar_t lpLocaleName[LOCALE_NAME_MAX_LENGTH] = { 0 };
isLocaleValid = GetLocaleInfo(MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT), LOCALE_SNAME, lpLocaleName, LOCALE_NAME_MAX_LENGTH) != FALSE;

if (isLocaleValid)
{
IFC_RETURN(languageStatics->IsWellFormed(wrl_wrappers::HStringReference(lpLocaleName).Get(), &isWellFormedLanguage));
}

if (isLocaleValid && isWellFormedLanguage)
{
// CopyTo() calls WindowsDuplicateString() which will make a deep copy of the
// underlying fast-pass lpLocaleName buffer,
// making primaryLanguageName safe to use outside of lpLocaleName's scope
wrl_wrappers::HStringReference(lpLocaleName).CopyTo(primaryLanguageName.GetAddressOf());
}
else
{
// If the Windows display language isn't bcp47 compliant for some reason, fall back to the user's preferred language list.
// This could still be an inconsistent localization experience, but is the next best option.
wrl::ComPtr<wfc::IVectorView<HSTRING>> languages;
IFC_RETURN(applicationLanguagesStatics->get_Languages(languages.ReleaseAndGetAddressOf()));
IFC_RETURN(languages->GetAt(0, primaryLanguageName.GetAddressOf()));
}
}
else
{
Expand Down
26 changes: 23 additions & 3 deletions dxaml/xcp/core/core/elements/Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "DXamlServices.h"
#include "CVisualStateManager2.h"
#include <Theme.h>
#include <FrameworkUdk/Containment.h>

// Bug 47229546: [1.4 servicing] The File Explorer's Details pane steals focus unexpectedly
#define WINAPPSDK_CHANGEID_47229546 47229546

// Class: CControl
//
Expand Down Expand Up @@ -1483,9 +1487,25 @@ CControl::Enabled(
if (pControl == pFocusable)
{
bool focusUpdated = false;
// If we are trying to set focus in a changing focus event handler, we will end up leaving focus on the disabled control.
// As a result, we fail fast here. This is being tracked by Bug 9840123
IFCFAILFAST(pControl->Focus(DirectUI::FocusState::Programmatic, false /*animateIfBringIntoView*/, &focusUpdated));

if (WinAppSdk::Containment::IsChangeEnabled<WINAPPSDK_CHANGEID_47229546>())
{
// In 1.4 servicing we started specifying NoActivate here. In this function, we're setting focus just to avoid the state where no
// focus is set, not because the user is interacting with it. We don't want to activate the window for this kind of situation.
IFCFAILFAST(pControl->Focus(
DirectUI::FocusState::Programmatic,
false /*animateIfBringIntoView*/,
&focusUpdated,
DirectUI::FocusNavigationDirection::None,
InputActivationBehavior::NoActivate));
}
else
{
// If we are trying to set focus in a changing focus event handler, we will end up leaving focus on the disabled control.
// As a result, we fail fast here. This is being tracked by Bug 9840123
IFCFAILFAST(pControl->Focus(DirectUI::FocusState::Programmatic, false /*animateIfBringIntoView*/, &focusUpdated));
}

}
}
}
Expand Down
2 changes: 1 addition & 1 deletion dxaml/xcp/core/core/elements/Popup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ _Check_return_ HRESULT CPopup::Close(bool forceCloseforTreeReset)
if (m_pPreviousFocusWeakRef)
{
CDependencyObject* pPreviousFocus = m_pPreviousFocusWeakRef.lock();
if (pPreviousFocus && FocusProperties::IsFocusable(pPreviousFocus))
if (pPreviousFocus && FocusProperties::IsFocusable(pPreviousFocus, false /*ignoreOffScreenPosition*/))
{
if (pPreviousFocus->OfTypeByIndex<KnownTypeIndex::UIElement>())
{
Expand Down
7 changes: 5 additions & 2 deletions dxaml/xcp/core/core/elements/uielement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1578,8 +1578,11 @@ _Check_return_ HRESULT CUIElement::LeaveImpl(_In_ CDependencyObject *pNamescopeO
params.fCoercedIsEnabled = FALSE;
}

// Clear the skip focus subtree flag.
m_skipFocusSubtree = FALSE;
ASSERT(IsTabNavigationWithVirtualizedItemsSupported() || !m_skipFocusSubtree_OffScreenPosition);

// Clear the skip focus subtree flags.
m_skipFocusSubtree_OffScreenPosition = false;
m_skipFocusSubtree_Other = false;

// When visual tree is being reset, (CCoreServices::ResetVisualTree) no need to coerce values/raise events.
if (params.fIsLive && !params.fVisualTreeBeingReset)
Expand Down
Loading

0 comments on commit 685d2bf

Please sign in to comment.