Repository: microsoft/terminal (language: cpp)

Issue:
Selected tab title not used for `Export Text` file name
### Windows Terminal version

main 1ef4a4276

### Windows build number

10.0.19044.0

### Other Software

_No response_

### Steps to reproduce

- build WT with `Use the tab's active title for "Export Text"` patch applied, commit 2c341c8de
- rename some tabs
- export text from a tab other than active one


`Foo` was the active tab and `Bar` was used for export:
![wt_export_text](https://user-images.githubusercontent.com/3933920/189212775-956220d7-7607-43b3-bd62-a78d51fae0ea.PNG)


### Expected Behavior

- tab's title used for filename

### Actual Behavior

- the active's tab title is being used instead


Discussion / hints:
It's much worse than that: it actually only exports the active tab. It can't export a non-active tab.

How? It takes `tab` in as an action argument...! Did we mess something up this egregiously?
So this and #13942 are somewhat related.

Of the tab related context menu items "Duplicate Tab", "Split Tab", "Export Text" and "Find", the only one that does what you expect on an unfocused tab is "Split Tab".

The callbacks are all set up in `TabManagement.cpp`:

https://github.com/microsoft/terminal/blob/95a9d8c31b3f4e27fb10ccefa525d66eacf26f96/src/cascadia/TerminalApp/TabManagement.cpp#L193-L233

They delegate to:

* `TerminalPage::_DuplicateTab()`: duplicates the currently focused tab
* `TerminalPage::_SplitTab()`: works as expected, as it focuses the selected tab and then splits it
* `TerminalPage::_HandleExportBuffer()`: exports the currently focused tab's content
* `TerminalPage::_Find()`: searches the currently focused tab's control

I guess the quick win would be to replicate what `SplitTab()` does - i.e. focus the selected tab and then do the duplicate/export/find. Is that reasonable?
That seems like a reasonable solution to me. Think that'll knock out all of this issue, #13942 and #13579 all in one go?
Hmm doesn't look like it's that straight forward - `_SetFocusedTab()` is async. As @JerBast suggests - `_DuplicateTab()` and `_SplitTab()` delegate to `_MakePane()`, which won't necessarily get the focused tab due it's async nature.
Generally speaking, I'd rather us fix the event plumbing so that things that come out of (1) the pane, (2) the tab and (3) the terminal control are tagged up appropriately so we know their origination chain. Is that something doable on a reasonable time horizon?
maybe `_MakePane(newTerminalArgs, bool duplicate, existingConnection)` should accept something like `const TerminalTab& sourceTab` instead of `bool duplicate`?
That way `_DuplicateTab` will pass the tab to `_MakePane` and it should work.
Changing `_MakePane` would work for #13942 for sure. For this issue, it is also possible to replace the call to `pane->_HandleExportBuffer(...)` with a call to `pane->_ExportTab(*tab, L"")` directly.
I'd come to the same conclusions. There's no point 3 people working on it though, so I'll leave it to you 🙂 

Fix patch:
diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp
index a5b17523721..8b2cd7b3637 100644
--- a/src/cascadia/TerminalApp/AppActionHandlers.cpp
+++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp
@@ -510,7 +510,10 @@ namespace winrt::TerminalApp::implementation
     void TerminalPage::_HandleFind(const IInspectable& /*sender*/,
                                    const ActionEventArgs& args)
     {
-        _Find();
+        if (const auto activeTab{ _GetFocusedTabImpl() })
+        {
+            _Find(*activeTab);
+        }
         args.Handled(true);
     }
 
diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp
index 97eb581e2fc..7acd7d3f349 100644
--- a/src/cascadia/TerminalApp/TabManagement.cpp
+++ b/src/cascadia/TerminalApp/TabManagement.cpp
@@ -194,9 +194,9 @@ namespace winrt::TerminalApp::implementation
 
             if (page && tab)
             {
-                // Passing null args to the ExportBuffer handler will default it
-                // to prompting for the path
-                page->_HandleExportBuffer(nullptr, nullptr);
+                // Passing empty string as the path to export tab will make it
+                // prompt for the path
+                page->_ExportTab(*tab, L"");
             }
         });
 
@@ -206,7 +206,8 @@ namespace winrt::TerminalApp::implementation
 
             if (page && tab)
             {
-                page->_Find();
+                page->_SetFocusedTab(*tab);
+                page->_Find(*tab);
             }
         });
 
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index 0d49cefd6aa..cf4f0140a27 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -3160,15 +3160,15 @@ namespace winrt::TerminalApp::implementation
 
     // Method Description:
     // - Called when the user tries to do a search using keybindings.
-    //   This will tell the current focused terminal control to create
-    //   a search box and enable find process.
+    //   This will tell the active terminal control of the passed tab
+    //   to create a search box and enable find process.
     // Arguments:
-    // - <none>
+    // - tab: the tab where the search box should be created
     // Return Value:
     // - <none>
-    void TerminalPage::_Find()
+    void TerminalPage::_Find(const TerminalTab& tab)
     {
-        if (const auto& control{ _GetActiveControl() })
+        if (const auto& control{ tab.GetActiveTerminalControl() })
         {
             control.CreateSearchBoxControl();
         }
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index 03c7a0f2383..9c1705706a0 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -388,7 +388,7 @@ namespace winrt::TerminalApp::implementation
         void _OnCommandLineExecutionRequested(const IInspectable& sender, const winrt::hstring& commandLine);
         void _OnSwitchToTabRequested(const IInspectable& sender, const winrt::TerminalApp::TabBase& tab);
 
-        void _Find();
+        void _Find(const TerminalTab& tab);
 
         winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
                                                                       const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);


Test patch: