diff --git a/controls/MidlShared.targets b/controls/MidlShared.targets
index 9811538e54..aa62a852d1 100644
--- a/controls/MidlShared.targets
+++ b/controls/MidlShared.targets
@@ -16,6 +16,7 @@
$(ProjectUnmergedWinmd)
+ %(AdditionalOptions) /nomidl
diff --git a/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp b/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp
index b717f75c3b..5f0a9c05aa 100644
--- a/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp
+++ b/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp
@@ -15,6 +15,9 @@
// 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
+// Bug 48006563: [1.4 servicing] File Explorer crash due to bad reentrancy from CommandBarFlyoutCommandBar calling FocusCommand (STOWED_EXCEPTION_8000ffff_Microsoft.UI.Xaml.dll!CXcpDispatcher::OnReentrancyProtectedWindowMessage)
+#define WINAPPSDK_CHANGEID_48006563 48006563
+
CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
{
SetDefaultStyleKey(this);
@@ -49,12 +52,24 @@ CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
{
if (firstCommandAsFrameworkElement.IsLoaded())
{
- FocusCommand(
- commands,
- usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
- winrt::FocusState::Programmatic /*focusState*/,
- true /*firstCommand*/,
- ensureTabStopUniqueness);
+ if (WinAppSdk::Containment::IsChangeEnabled())
+ {
+ FocusCommandAsync(
+ commands,
+ usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
+ winrt::FocusState::Programmatic /*focusState*/,
+ true /*firstCommand*/,
+ ensureTabStopUniqueness);
+ }
+ else
+ {
+ FocusCommandSync(
+ commands,
+ usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
+ winrt::FocusState::Programmatic /*focusState*/,
+ true /*firstCommand*/,
+ ensureTabStopUniqueness);
+ }
}
else
{
@@ -62,12 +77,25 @@ CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
{
[this, commands, usingPrimaryCommands, ensureTabStopUniqueness](winrt::IInspectable const& sender, auto const&)
{
- FocusCommand(
- commands,
- usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
- winrt::FocusState::Programmatic /*focusState*/,
- true /*firstCommand*/,
- ensureTabStopUniqueness);
+ if (WinAppSdk::Containment::IsChangeEnabled())
+ {
+ FocusCommandAsync(
+ commands,
+ usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
+ winrt::FocusState::Programmatic /*focusState*/,
+ true /*firstCommand*/,
+ ensureTabStopUniqueness);
+ }
+ else
+ {
+ FocusCommandSync(
+ commands,
+ usingPrimaryCommands ? m_moreButton.get() : nullptr /*moreButton*/,
+ winrt::FocusState::Programmatic /*focusState*/,
+ true /*firstCommand*/,
+ ensureTabStopUniqueness);
+ }
+
m_firstItemLoadedRevoker.revoke();
}
});
@@ -1029,12 +1057,24 @@ void CommandBarFlyoutCommandBar::OnKeyDown(
IsOpen(true);
// ... and focus the first focusable command
- FocusCommand(
- SecondaryCommands() /*commands*/,
- nullptr /*moreButton*/,
- winrt::FocusState::Keyboard /*focusState*/,
- true /*firstCommand*/,
- true /*ensureTabStopUniqueness*/);
+ if (WinAppSdk::Containment::IsChangeEnabled())
+ {
+ FocusCommandAsync(
+ SecondaryCommands() /*commands*/,
+ nullptr /*moreButton*/,
+ winrt::FocusState::Keyboard /*focusState*/,
+ true /*firstCommand*/,
+ true /*ensureTabStopUniqueness*/);
+ }
+ else
+ {
+ FocusCommandSync(
+ SecondaryCommands() /*commands*/,
+ nullptr /*moreButton*/,
+ winrt::FocusState::Keyboard /*focusState*/,
+ true /*firstCommand*/,
+ true /*ensureTabStopUniqueness*/);
+ }
}
break;
}
@@ -1124,15 +1164,29 @@ void CommandBarFlyoutCommandBar::OnKeyDown(
}
}
- if (FocusControl(
- accessibleControls.GetAt(i) /*newFocus*/,
- focusedControl /*oldFocus*/,
- winrt::FocusState::Keyboard /*focusState*/,
- true /*updateTabStop*/))
+ if (WinAppSdk::Containment::IsChangeEnabled())
{
+ FocusControlAsync(
+ accessibleControls.GetAt(i) /*newFocus*/,
+ focusedControl /*oldFocus*/,
+ winrt::FocusState::Keyboard /*focusState*/,
+ true /*updateTabStop*/);
+
args.Handled(true);
break;
}
+ else
+ {
+ if (FocusControlSync(
+ accessibleControls.GetAt(i) /*newFocus*/,
+ focusedControl /*oldFocus*/,
+ winrt::FocusState::Keyboard /*focusState*/,
+ true /*updateTabStop*/))
+ {
+ args.Handled(true);
+ break;
+ }
+ }
}
}
@@ -1174,7 +1228,103 @@ winrt::Control CommandBarFlyoutCommandBar::GetFirstTabStopControl(
return nullptr;
}
-bool CommandBarFlyoutCommandBar::FocusControl(
+winrt::IAsyncOperation CommandBarFlyoutCommandBar::FocusControlAsync(
+ winrt::Control newFocus,
+ winrt::Control oldFocus,
+ winrt::FocusState focusState,
+ bool updateTabStop)
+{
+ MUX_ASSERT(newFocus);
+
+ if (updateTabStop)
+ {
+ newFocus.IsTabStop(true);
+ }
+
+ // Setting focus can cause us to enter the window message handler loop, which is bad if
+ // CXcpDispatcher::OnReentrancyProtectedWindowMessage is on the callstack, since that can lead to reentry.
+ // Switching to a background thread and then back to the UI thread ensures that this call to Control.Focus()
+ // occurs outside that callstack.
+ winrt::apartment_context uiThread;
+ co_await winrt::resume_background();
+ co_await uiThread;
+
+ if (newFocus.Focus(focusState))
+ {
+ if (oldFocus && updateTabStop)
+ {
+ oldFocus.IsTabStop(false);
+ }
+ co_return true;
+ }
+ co_return false;
+}
+
+winrt::IAsyncOperation CommandBarFlyoutCommandBar::FocusCommandAsync(
+ winrt::IObservableVector commands,
+ winrt::Control moreButton,
+ winrt::FocusState focusState,
+ bool firstCommand,
+ bool ensureTabStopUniqueness)
+{
+ COMMANDBARFLYOUT_TRACE_VERBOSE(nullptr, TRACE_MSG_METH, METH_NAME, nullptr);
+
+ MUX_ASSERT(commands);
+
+ // Give focus to the first or last focusable command
+ winrt::Control focusedControl = nullptr;
+ int startIndex = 0;
+ int endIndex = static_cast(commands.Size());
+ int deltaIndex = 1;
+
+ if (!firstCommand)
+ {
+ deltaIndex = -1;
+ startIndex = endIndex - 1;
+ endIndex = -1;
+ }
+
+ for (int index = startIndex; index != endIndex; index += deltaIndex)
+ {
+ auto command = commands.GetAt(index);
+
+ if (auto commandAsControl = command.try_as())
+ {
+ if (IsControlFocusable(commandAsControl, !ensureTabStopUniqueness /*checkTabStop*/))
+ {
+ if (!focusedControl)
+ {
+ if (co_await FocusControlAsync(
+ commandAsControl /*newFocus*/,
+ nullptr /*oldFocus*/,
+ focusState /*focusState*/,
+ ensureTabStopUniqueness /*updateTabStop*/))
+ {
+ if (ensureTabStopUniqueness && moreButton && moreButton.IsTabStop())
+ {
+ moreButton.IsTabStop(false);
+ }
+
+ focusedControl = commandAsControl;
+
+ if (!ensureTabStopUniqueness)
+ {
+ break;
+ }
+ }
+ }
+ else if (focusedControl && commandAsControl.IsTabStop())
+ {
+ commandAsControl.IsTabStop(false);
+ }
+ }
+ }
+ }
+
+ co_return focusedControl != nullptr;
+}
+
+bool CommandBarFlyoutCommandBar::FocusControlSync(
winrt::Control const& newFocus,
winrt::Control const& oldFocus,
winrt::FocusState const& focusState,
@@ -1198,7 +1348,7 @@ bool CommandBarFlyoutCommandBar::FocusControl(
return false;
}
-bool CommandBarFlyoutCommandBar::FocusCommand(
+bool CommandBarFlyoutCommandBar::FocusCommandSync(
winrt::IObservableVector const& commands,
winrt::Control const& moreButton,
winrt::FocusState const& focusState,
@@ -1232,7 +1382,7 @@ bool CommandBarFlyoutCommandBar::FocusCommand(
{
if (!focusedControl)
{
- if (FocusControl(
+ if (FocusControlSync(
commandAsControl /*newFocus*/,
nullptr /*oldFocus*/,
focusState /*focusState*/,
diff --git a/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h b/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h
index dd2085a19d..597fa208db 100644
--- a/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h
+++ b/controls/dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h
@@ -70,12 +70,23 @@ class CommandBarFlyoutCommandBar :
bool checkTabStop);
static winrt::Control GetFirstTabStopControl(
winrt::IObservableVector const& commands);
- static bool FocusControl(
+ static winrt::IAsyncOperation FocusControlAsync(
+ winrt::Control newFocus,
+ winrt::Control oldFocus,
+ winrt::FocusState focusState,
+ bool updateTabStop);
+ static winrt::IAsyncOperation FocusCommandAsync(
+ winrt::IObservableVector commands,
+ winrt::Control moreButton,
+ winrt::FocusState focusState,
+ bool firstCommand,
+ bool ensureTabStopUniqueness);
+ static bool FocusControlSync(
winrt::Control const& newFocus,
winrt::Control const& oldFocus,
winrt::FocusState const& focusState,
bool updateTabStop);
- static bool FocusCommand(
+ static bool FocusCommandSync(
winrt::IObservableVector const& commands,
winrt::Control const& moreButton,
winrt::FocusState const& focusState,
diff --git a/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml b/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml
index 4a5f9d07cb..d065de33ec 100644
--- a/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml
+++ b/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml
@@ -230,6 +230,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -247,6 +263,7 @@
+
diff --git a/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml.cs b/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml.cs
index 5ba4cca682..df33b11bcf 100644
--- a/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml.cs
+++ b/controls/dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml.cs
@@ -65,6 +65,7 @@ public CommandBarFlyoutPage()
UndoButton6.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Z, Modifiers = VirtualKeyModifiers.Control });
UndoButton7.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Z, Modifiers = VirtualKeyModifiers.Control });
UndoButton11.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Z, Modifiers = VirtualKeyModifiers.Control });
+ UndoButton12.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Z, Modifiers = VirtualKeyModifiers.Control });
RedoButton1.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
RedoButton2.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
@@ -74,6 +75,7 @@ public CommandBarFlyoutPage()
RedoButton6.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
RedoButton7.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
RedoButton11.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
+ RedoButton12.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.Y, Modifiers = VirtualKeyModifiers.Control });
SelectAllButton1.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
SelectAllButton2.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
@@ -83,6 +85,7 @@ public CommandBarFlyoutPage()
SelectAllButton6.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
SelectAllButton7.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
SelectAllButton11.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
+ SelectAllButton12.KeyboardAccelerators.Add(new KeyboardAccelerator() { Key = VirtualKey.A, Modifiers = VirtualKeyModifiers.Control });
FlyoutTarget1.ContextFlyout = Flyout1;
FlyoutTarget2.ContextFlyout = Flyout2;
@@ -92,6 +95,7 @@ public CommandBarFlyoutPage()
FlyoutTarget6.ContextFlyout = Flyout6;
FlyoutTarget7.ContextFlyout = Flyout7;
FlyoutTarget11.ContextFlyout = Flyout11;
+ FlyoutTarget12.ContextFlyout = Flyout12;
Flyout1.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
Flyout2.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
@@ -101,6 +105,7 @@ public CommandBarFlyoutPage()
Flyout6.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
Flyout7.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
Flyout11.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
+ Flyout12.Placement = FlyoutPlacementMode.TopEdgeAlignedLeft;
}
public void OnElementClicked(object sender, object args)
@@ -258,6 +263,18 @@ private void OnFlyoutTarget11Click(object sender, RoutedEventArgs e)
ShowFlyoutAt(Flyout11, FlyoutTarget11, FlyoutShowMode.Standard);
}
+ private void OnFlyoutTarget12Click(object sender, RoutedEventArgs e)
+ {
+ DispatcherTimer showFlyoutTimer = new();
+ showFlyoutTimer.Interval = TimeSpan.FromSeconds(5);
+ showFlyoutTimer.Tick += (object sender, object args) =>
+ {
+ ShowFlyoutAt(Flyout12, FlyoutTarget12, FlyoutShowMode.Standard);
+ showFlyoutTimer.Stop();
+ };
+ showFlyoutTimer.Start();
+ }
+
private void ShowFlyoutAt(FlyoutBase flyout, FrameworkElement targetElement, FlyoutShowMode showMode = FlyoutShowMode.Transient)
{
bool useSecondaryCommandDynamicLabel = (bool)UseSecondaryCommandDynamicLabelCheckBox.IsChecked;
diff --git a/controls/dev/dll/packages.config b/controls/dev/dll/packages.config
index 05479e1906..fb45d64359 100644
--- a/controls/dev/dll/packages.config
+++ b/controls/dev/dll/packages.config
@@ -7,7 +7,7 @@
-
+
\ No newline at end of file
diff --git a/controls/dev/dll/pch.h b/controls/dev/dll/pch.h
index ef40657a80..5bccb35021 100644
--- a/controls/dev/dll/pch.h
+++ b/controls/dev/dll/pch.h
@@ -5,6 +5,13 @@
#define NOMINMAX
+// By default C++/WinRT will include some extra source and type info in the exception structs that it creates.
+// This is useful diagnostic info, but it comes at a high cost due to the fact that it breaks COMDAT folding
+// due to template functions that would previously compile down to identical binary code (which gets folded by
+// the compiler) now end up unique for each instantiation of the template.
+// This bloats the file size of MUXC.dll by 50%, so we turn this C++/WinRT feature off.
+#define WINRT_NO_SOURCE_LOCATION
+
#pragma warning(disable : 6221) // Disable implicit cast warning for C++/WinRT headers (tracked by Bug 17528784: C++/WinRT headers trigger C6221 comparing e.code() to int-typed things)
// Disable factory caching in CppWinRT as the global COM pointers that are released during dll/process
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index fbe0195d3f..2e4f6b4001 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -2,17 +2,17 @@
-
+
https://dev.azure.com/microsoft/ProjectReunion/_git/WindowsAppSDK
- 0584534e260a81ebf0a37c37db6faf3dfc82f078
+ e1e38e7e4df1f862ddaac4f4f9a4e77930c55fee
-
+
https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP
- aca3f84ba82804f6bbc99aedf97315da44cde57a
+ 3a7a80cf90baf200787d3ffee0443c6a58aacb1f
-
+
https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP
- aca3f84ba82804f6bbc99aedf97315da44cde57a
+ 3a7a80cf90baf200787d3ffee0443c6a58aacb1f
diff --git a/eng/versions.props b/eng/versions.props
index c97a3610c1..5a8a019256 100644
--- a/eng/versions.props
+++ b/eng/versions.props
@@ -65,7 +65,7 @@
29
7.0.1xx
8.0.1xx
- 2.0.221104.6
+ 2.0.230706.1
1.0.1823.32
0.1.0.3
1.25.0
diff --git a/packages.config b/packages.config
index fd0edebd4a..452773d96e 100644
--- a/packages.config
+++ b/packages.config
@@ -21,7 +21,7 @@
-
+