Repository: microsoft/terminal (language: cpp)

Issue:
Something _WinUI_ did made tabs "slide" when they resize
### Windows Terminal version

1.18.96

### Windows build number

_No response_

### Other Software

_No response_

### Steps to reproduce

I don't think this happened on 1.16.93 (!) which also had MUX 2.8

Have a tab. TabWidthMode = TitleLength (the one true setting)

### Expected Behavior

_No response_

### Actual Behavior

![WindowsTerminal_20230407T102232_986](https://user-images.githubusercontent.com/189190/230634242-9d99255c-56ab-4cc2-886b-2e6d92f80002.gif)

Reordering tabs messes up relation between tabs and panes
### Windows Terminal version

62448969b30325a75f35201427a052de0e4dbb7d

### Windows build number

10.0.25330.0

### Other Software

_No response_

### Steps to reproduce

Open multiple tabs. Reorder them.

### Expected Behavior

_No response_

### Actual Behavior

The relation/index between tabs and panes is now broken.
Selecting a tab will select a pane which does not belong to that tab. Closing panes will close the wrong tab.
See: https://www.youtube.com/watch?v=Qa9jxFnvI8U


Discussion / hints:
Oh no I can't repro this on 1.18.931.0. I don't think that had MUX 2.8...
The easiest way to repro this: just add this line

```json
    "tabWidthMode": "titleLength",
```

and comment / uncomment
This is the upstream https://github.com/microsoft/microsoft-ui-xaml/issues/8384
More concrete repro steps:

* Open two windows
* In one window, open two tabs. Pwsh and CMD are good, so they're clearly separate. 
* Reorder those two. 
* Drag the inactive one to the other window. 
* Experience having the active term core in both windows!



<hr>

~It's so obvious:~
![](https://user-images.githubusercontent.com/18356694/231828087-7a191811-9248-4ef7-970e-5575801c6b84.png)


Wait but no, `_onTabStripDrop` doesn't ever cause a `_MoveTab`. It triggers a `_RequestReceiveContentHandlers`, which is bubbled to the sender, which does a `SendContentToOther`, which does a `_MoveContent` on the dragged tab. Hmm. 
oh its so bad

Just reordering tabs, no tearout, just breaks the entire relationship of it. I wonder if adding these drag/drop handlers somehow broke the reorder events we get...

It sure did. We don't get `TabView.TabItemsChanged` anymore now that we get `TabDragStarting` & `TabStripDrop`. WELP. Let's see what we can do. 
Upstream: https://github.com/microsoft/microsoft-ui-xaml/issues/8388

Fix patch:
diff --git a/dep/nuget/packages.config b/dep/nuget/packages.config
index 2e4323f6912..fb1f261b593 100644
--- a/dep/nuget/packages.config
+++ b/dep/nuget/packages.config
@@ -7,7 +7,7 @@
   <package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
   <package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
   <package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
-  <package id="Microsoft.UI.Xaml" version="2.8.3" targetFramework="native" />
+  <package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
   <package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
   <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
 
diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
index 4bc516bc313..fabbb0757a4 100644
--- a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
+++ b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
@@ -146,7 +146,7 @@
             -->
             <x:Double x:Key="CaptionButtonHeightWindowed">40.0</x:Double>
             <!--  32 + (1 to compensate for GH#10746) + (-1 for GH#15164)  -->
-            <x:Double x:Key="CaptionButtonHeightMaximized">32.0</x:Double>
+            <x:Double x:Key="CaptionButtonHeightMaximized">33.0</x:Double>
 
             <Style x:Key="CaptionButton"
                    TargetType="Button">
diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp
index fbb15f1ed86..2e3ea91fe7c 100644
--- a/src/cascadia/TerminalApp/TabManagement.cpp
+++ b/src/cascadia/TerminalApp/TabManagement.cpp
@@ -888,6 +888,34 @@ namespace winrt::TerminalApp::implementation
             co_await _HandleCloseTabRequested(tab);
         }
     }
+    // Method Description:
+    // - Responds to changes in the TabView's item list by changing the
+    //   tabview's visibility.
+    // - This method is also invoked when tabs are dragged / dropped as part of
+    //   tab reordering and this method hands that case as well in concert with
+    //   TabDragStarting and TabDragCompleted handlers that are set up in
+    //   TerminalPage::Create()
+    // Arguments:
+    // - sender: the control that originated this event
+    // - eventArgs: the event's constituent arguments
+    void TerminalPage::_OnTabItemsChanged(const IInspectable& /*sender*/, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs)
+    {
+        if (_rearranging)
+        {
+            if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemRemoved)
+            {
+                _rearrangeFrom = eventArgs.Index();
+            }
+
+            if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemInserted)
+            {
+                _rearrangeTo = eventArgs.Index();
+            }
+        }
+
+        CommandPalette().Visibility(Visibility::Collapsed);
+        _UpdateTabView();
+    }
 
     // Method Description:
     // - Additional responses to clicking on a TabView's item. Currently, just remove tab with middle click
@@ -1051,37 +1079,16 @@ namespace winrt::TerminalApp::implementation
     }
 
     void TerminalPage::_TabDragStarted(const IInspectable& /*sender*/,
-                                       const winrt::MUX::Controls::TabViewTabDragStartingEventArgs& eventArgs)
+                                       const IInspectable& /*eventArgs*/)
     {
         _rearranging = true;
         _rearrangeFrom = std::nullopt;
         _rearrangeTo = std::nullopt;
-
-        // Start tracking the index of the tab that is being dragged. In
-        // `_TabDragCompleted`, we'll use this to determine how to reorder our
-        // internal tabs list.
-        const auto& draggedTabViewItem{ eventArgs.Tab() };
-        uint32_t tabIndexFromControl{};
-        const auto tabItems{ _tabView.TabItems() };
-        if (tabItems.IndexOf(draggedTabViewItem, tabIndexFromControl))
-        {
-            // If IndexOf returns true, we've actually got an index
-            _rearrangeFrom = tabIndexFromControl;
-        }
     }
 
     void TerminalPage::_TabDragCompleted(const IInspectable& /*sender*/,
-                                         const winrt::MUX::Controls::TabViewTabDragCompletedEventArgs& eventArgs)
+                                         const IInspectable& /*eventArgs*/)
     {
-        const auto& draggedTabViewItem{ eventArgs.Tab() };
-
-        uint32_t tabIndexFromControl{};
-        const auto tabItems{ _tabView.TabItems() };
-        if (tabItems.IndexOf(draggedTabViewItem, tabIndexFromControl))
-        {
-            _rearrangeTo = tabIndexFromControl;
-        }
-
         auto& from{ _rearrangeFrom };
         auto& to{ _rearrangeTo };
 
diff --git a/src/cascadia/TerminalApp/TabRowControl.xaml b/src/cascadia/TerminalApp/TabRowControl.xaml
index 7d219bba08c..05ada3ec0da 100644
--- a/src/cascadia/TerminalApp/TabRowControl.xaml
+++ b/src/cascadia/TerminalApp/TabRowControl.xaml
@@ -25,7 +25,6 @@
     -->
 
     <mux:TabView x:Name="TabView"
-                 Padding="0,1,0,-1"
                  VerticalAlignment="Bottom"
                  HorizontalContentAlignment="Stretch"
                  AllowDropTabs="True"
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index 3b36382a5dd..405640860b1 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -246,6 +246,7 @@ namespace winrt::TerminalApp::implementation
         });
         _tabView.SelectionChanged({ this, &TerminalPage::_OnTabSelectionChanged });
         _tabView.TabCloseRequested({ this, &TerminalPage::_OnTabCloseRequested });
+        _tabView.TabItemsChanged({ this, &TerminalPage::_OnTabItemsChanged });
 
         _tabView.TabDragStarting({ this, &TerminalPage::_onTabDragStarting });
         _tabView.TabStripDragOver({ this, &TerminalPage::_onTabStripDragOver });
@@ -4736,8 +4737,6 @@ namespace winrt::TerminalApp::implementation
         co_await wil::resume_foreground(Dispatcher());
         if (const auto& page{ weakThis.get() })
         {
-            // `this` is safe to use
-            //
             // First we need to get the position in the List to drop to
             auto index = -1;
 
@@ -4757,8 +4756,8 @@ namespace winrt::TerminalApp::implementation
                 }
             }
 
-            const auto myId{ _WindowProperties.WindowId() };
-            const auto request = winrt::make_self<RequestReceiveContentArgs>(src, myId, index);
+            // `this` is safe to use
+            const auto request = winrt::make_self<RequestReceiveContentArgs>(src, _WindowProperties.WindowId(), index);
 
             // This will go up to the monarch, who will then dispatch the request
             // back down to the source TerminalPage, who will then perform a
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index cbaaea453fb..5605362c3da 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -415,11 +415,12 @@ namespace winrt::TerminalApp::implementation
 
         fire_and_forget _LaunchSettings(const Microsoft::Terminal::Settings::Model::SettingsTarget target);
 
-        void _TabDragStarted(const IInspectable& sender, const winrt::Microsoft::UI::Xaml::Controls::TabViewTabDragStartingEventArgs& eventArgs);
-        void _TabDragCompleted(const IInspectable& sender, const winrt::Microsoft::UI::Xaml::Controls::TabViewTabDragCompletedEventArgs& eventArgs);
+        void _TabDragStarted(const IInspectable& sender, const IInspectable& eventArgs);
+        void _TabDragCompleted(const IInspectable& sender, const IInspectable& eventArgs);
 
         void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
         void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
+        void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
         void _OnTabCloseRequested(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabCloseRequestedEventArgs& eventArgs);
         void _OnFirstLayout(const IInspectable& sender, const IInspectable& eventArgs);
         void _UpdatedSelectedTab(const winrt::TerminalApp::TabBase& tab);
diff --git a/src/common.nugetversions.props b/src/common.nugetversions.props
index 0955a1bdc45..19d169a45a0 100644
--- a/src/common.nugetversions.props
+++ b/src/common.nugetversions.props
@@ -37,6 +37,6 @@
   </PropertyGroup>
 
   <!-- WinUI (which depends on WebView2 as of 2.8.0) -->
-  <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.props" Condition="'$(TerminalMUX)' == 'true' and Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.props')" />
+  <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.props" Condition="'$(TerminalMUX)' == 'true' and Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.props')" />
 
 </Project>
diff --git a/src/common.nugetversions.targets b/src/common.nugetversions.targets
index 6c501971ab6..0f915d51469 100644
--- a/src/common.nugetversions.targets
+++ b/src/common.nugetversions.targets
@@ -52,7 +52,7 @@
     <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets" Condition="'$(TerminalVisualStudioSetup)' == 'true' and Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" />
 
     <!-- WinUI (which depends on WebView2 as of 2.8.0) -->
-    <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.targets" Condition="'$(TerminalMUX)' == 'true' and Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.targets')" />
+    <Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.targets" Condition="'$(TerminalMUX)' == 'true' and Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.targets')" />
     <!--
       Instead of adding our dependency on WebView2, fake it with another set of rules for XAML.
       See Microsoft.UI.Xaml.Additional.targets for more info.
@@ -88,7 +88,7 @@
     <Error Condition="'$(TerminalVisualStudioSetup)' == 'true' AND !Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets'))" />
 
     <!-- WinUI (which depends on WebView2 as of 2.8.0) -->
-    <Error Condition="'$(TerminalMUX)' == 'true' AND !Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.3\build\native\Microsoft.UI.Xaml.targets'))" />
+    <Error Condition="'$(TerminalMUX)' == 'true' AND !Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.UI.Xaml.2.8.4\build\native\Microsoft.UI.Xaml.targets'))" />
     <Error Condition="'$(TerminalMUX)' == 'true' AND !Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.Web.WebView2.1.0.1661.34\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.Web.WebView2.1.0.1661.34\build\native\Microsoft.Web.WebView2.targets'))" />
 
     <!-- WIL (so widely used that this one does not have a TerminalWIL opt-in property; it is automatic) -->


Test patch: