mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Merge TabBase+TerminalTab into just Tab (#19136)
This removes the need to construct two objects per tab (TabBase, Actual Tab) and the other overhead inherent in WinRT composition-based inheritance. Important renames: - `GetTerminalTabImpl` -> `GetTabImpl` This pull request does not rename `TerminalTabStatus`; that is left as work for a future PR. Closes #17529
This commit is contained in:
parent
cb0289fff2
commit
f22295ef2c
@ -8,7 +8,7 @@
|
||||
#include "../TerminalApp/MinMaxCloseControl.h"
|
||||
#include "../TerminalApp/TabRowControl.h"
|
||||
#include "../TerminalApp/ShortcutActionDispatch.h"
|
||||
#include "../TerminalApp/TerminalTab.h"
|
||||
#include "../TerminalApp/Tab.h"
|
||||
#include "../TerminalApp/CommandPalette.h"
|
||||
#include "../TerminalApp/ContentManager.h"
|
||||
#include "CppWinrtTailored.h"
|
||||
@ -307,7 +307,7 @@ namespace TerminalAppLocalTests
|
||||
// reliably in the unit tests.
|
||||
Log::Comment(L"Ensure we set the first tab as the selected one.");
|
||||
auto tab = page->_tabs.GetAt(0);
|
||||
auto tabImpl = page->_GetTerminalTabImpl(tab);
|
||||
auto tabImpl = page->_GetTabImpl(tab);
|
||||
page->_tabView.SelectedItem(tabImpl->TabViewItem());
|
||||
page->_UpdatedSelectedTab(tab);
|
||||
});
|
||||
@ -510,7 +510,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
result = RunOnUIThread([&page]() {
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(1, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@ -520,7 +520,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(nullptr, SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@ -538,7 +538,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(nullptr, SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(3,
|
||||
tab->GetLeafPaneCount(),
|
||||
L"We should successfully duplicate a pane hosting a deleted profile.");
|
||||
@ -706,7 +706,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@ -717,7 +717,7 @@ namespace TerminalAppLocalTests
|
||||
result = RunOnUIThread([&page]() {
|
||||
ActionEventArgs eventArgs{};
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -727,7 +727,7 @@ namespace TerminalAppLocalTests
|
||||
result = RunOnUIThread([&page]() {
|
||||
ActionEventArgs eventArgs{};
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -744,7 +744,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@ -758,7 +758,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -772,7 +772,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleMoveFocus(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -789,7 +789,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@ -803,7 +803,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -816,7 +816,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleClosePane(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@ -827,7 +827,7 @@ namespace TerminalAppLocalTests
|
||||
Log::Comment(L"Check to ensure there's only one pane left.");
|
||||
|
||||
result = RunOnUIThread([&page]() {
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(1, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
@ -850,7 +850,7 @@ namespace TerminalAppLocalTests
|
||||
uint32_t firstId = 0, secondId = 0, thirdId = 0, fourthId = 0;
|
||||
TestOnUIThread([&]() {
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
firstId = tab->_activePane->Id().value();
|
||||
// We start with 1 tab, split vertically to get
|
||||
// -------------------
|
||||
@ -876,7 +876,7 @@ namespace TerminalAppLocalTests
|
||||
// | | |
|
||||
// -------------------
|
||||
page->_SplitPane(nullptr, SplitDirection::Down, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
// Split again to make the 3rd tab
|
||||
thirdId = tab->_activePane->Id().value();
|
||||
});
|
||||
@ -896,13 +896,13 @@ namespace TerminalAppLocalTests
|
||||
// | | |
|
||||
// -------------------
|
||||
page->_SplitPane(nullptr, SplitDirection::Down, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
fourthId = tab->_activePane->Id().value();
|
||||
});
|
||||
|
||||
Sleep(250);
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// just to be complete, make sure we actually have 4 different ids
|
||||
VERIFY_ARE_NOT_EQUAL(firstId, fourthId);
|
||||
@ -936,7 +936,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@ -967,7 +967,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@ -998,7 +998,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@ -1029,7 +1029,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@ -1174,16 +1174,16 @@ namespace TerminalAppLocalTests
|
||||
|
||||
Log::Comment(L"give alphabetical names to all switch tab actions");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(0))->Title(L"a");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(0))->Title(L"a");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(1))->Title(L"b");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(1))->Title(L"b");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(2))->Title(L"c");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(2))->Title(L"c");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(3))->Title(L"d");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(3))->Title(L"d");
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
|
||||
@ -41,13 +41,13 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
return _GetActiveControl();
|
||||
}
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_senderOrFocusedTab(const IInspectable& sender)
|
||||
winrt::com_ptr<Tab> TerminalPage::_senderOrFocusedTab(const IInspectable& sender)
|
||||
{
|
||||
if (sender)
|
||||
{
|
||||
if (auto tab{ sender.try_as<TerminalApp::TerminalTab>() })
|
||||
if (auto tab = sender.try_as<TerminalApp::Tab>())
|
||||
{
|
||||
return _GetTerminalTabImpl(tab);
|
||||
return _GetTabImpl(tab);
|
||||
}
|
||||
}
|
||||
return _GetFocusedTabImpl();
|
||||
@ -193,17 +193,17 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleCloseOtherPanes(const IInspectable& sender,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& terminalTab{ _senderOrFocusedTab(sender) })
|
||||
if (const auto& activeTab{ _senderOrFocusedTab(sender) })
|
||||
{
|
||||
const auto activePane = terminalTab->GetActivePane();
|
||||
if (terminalTab->GetRootPane() != activePane)
|
||||
const auto activePane = activeTab->GetActivePane();
|
||||
if (activeTab->GetRootPane() != activePane)
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
// Accumulate list of all unfocused leaf panes, ignore read-only panes
|
||||
std::vector<uint32_t> unfocusedPaneIds;
|
||||
const auto activePaneId = activePane->Id();
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& p) {
|
||||
activeTab->GetRootPane()->WalkTree([&](auto&& p) {
|
||||
const auto id = p->Id();
|
||||
if (id.has_value() && id != activePaneId && !p->ContainsReadOnly())
|
||||
{
|
||||
@ -215,7 +215,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Start by removing the panes that were least recently added
|
||||
sort(begin(unfocusedPaneIds), end(unfocusedPaneIds), std::less<uint32_t>());
|
||||
_ClosePanes(terminalTab->get_weak(), std::move(unfocusedPaneIds));
|
||||
_ClosePanes(activeTab->get_weak(), std::move(unfocusedPaneIds));
|
||||
args.Handled(true);
|
||||
return;
|
||||
}
|
||||
@ -281,9 +281,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto& duplicateFromTab{ realArgs.SplitMode() == SplitType::Duplicate ? _GetFocusedTab() : nullptr };
|
||||
|
||||
const auto& terminalTab{ _senderOrFocusedTab(sender) };
|
||||
const auto& activeTab{ _senderOrFocusedTab(sender) };
|
||||
|
||||
_SplitPane(terminalTab,
|
||||
_SplitPane(activeTab,
|
||||
realArgs.SplitDirection(),
|
||||
// This is safe, we're already filtering so the value is (0, 1)
|
||||
realArgs.SplitSize(),
|
||||
@ -302,14 +302,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleTogglePaneZoom(const IInspectable& sender,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto terminalTab{ _senderOrFocusedTab(sender) })
|
||||
if (const auto activeTab{ _senderOrFocusedTab(sender) })
|
||||
{
|
||||
// Don't do anything if there's only one pane. It's already zoomed.
|
||||
if (terminalTab->GetLeafPaneCount() > 1)
|
||||
if (activeTab->GetLeafPaneCount() > 1)
|
||||
{
|
||||
// Togging the zoom on the tab will cause the tab to inform us of
|
||||
// the new root Content for this tab.
|
||||
terminalTab->ToggleZoom();
|
||||
activeTab->ToggleZoom();
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,7 +783,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::vector<winrt::TerminalApp::Tab> tabsToRemove;
|
||||
if (index > 0)
|
||||
{
|
||||
std::copy(begin(_tabs), begin(_tabs) + index, std::back_inserter(tabsToRemove));
|
||||
@ -822,7 +822,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::vector<winrt::TerminalApp::Tab> tabsToRemove;
|
||||
std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove));
|
||||
_RemoveTabs(tabsToRemove);
|
||||
|
||||
@ -1559,7 +1559,6 @@ namespace winrt::TerminalApp::implementation
|
||||
activeTab->ToggleBroadcastInput();
|
||||
args.Handled(true);
|
||||
}
|
||||
// If the focused tab wasn't a TerminalTab, then leave handled=false
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleRestartConnection(const IInspectable& sender,
|
||||
|
||||
@ -1072,7 +1072,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_bindTabs(
|
||||
const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& source,
|
||||
const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& source,
|
||||
const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target)
|
||||
{
|
||||
target.Clear();
|
||||
@ -1084,7 +1084,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPalette::SetTabs(const Collections::IObservableVector<TabBase>& tabs, const Collections::IObservableVector<TabBase>& mruTabs)
|
||||
void CommandPalette::SetTabs(const Collections::IObservableVector<Tab>& tabs, const Collections::IObservableVector<Tab>& mruTabs)
|
||||
{
|
||||
_bindTabs(tabs, _tabActions);
|
||||
_bindTabs(mruTabs, _mruTabActions);
|
||||
|
||||
@ -31,7 +31,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::FilteredCommand> FilteredActions();
|
||||
|
||||
void SetTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& tabs, const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& mruTabs);
|
||||
void SetTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& tabs, const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& mruTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
|
||||
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
|
||||
@ -48,7 +48,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void EnableTabSearchMode();
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::TerminalApp::TabBase> SwitchToTabRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::TerminalApp::Tab> SwitchToTabRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::hstring> CommandLineExecutionRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> PreviewAction;
|
||||
@ -135,7 +135,7 @@ namespace winrt::TerminalApp::implementation
|
||||
Microsoft::Terminal::Settings::Model::TabSwitcherMode _tabSwitcherMode;
|
||||
uint32_t _switcherStartIdx;
|
||||
|
||||
void _bindTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& source, const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target);
|
||||
void _bindTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& source, const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target);
|
||||
void _anchorKeyUpHandler();
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "Tab.idl";
|
||||
import "HighlightedTextControl.idl";
|
||||
import "FilteredCommand.idl";
|
||||
|
||||
@ -20,7 +20,7 @@ namespace TerminalApp
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<FilteredCommand> FilteredActions { get; };
|
||||
|
||||
void SetTabs(Windows.Foundation.Collections.IObservableVector<TabBase> tabs, Windows.Foundation.Collections.IObservableVector<TabBase> mruTabs);
|
||||
void SetTabs(Windows.Foundation.Collections.IObservableVector<Tab> tabs, Windows.Foundation.Collections.IObservableVector<Tab> mruTabs);
|
||||
|
||||
void SetActionMap(Microsoft.Terminal.Settings.Model.IActionMapView actionMap);
|
||||
|
||||
@ -30,7 +30,7 @@ namespace TerminalApp
|
||||
void EnableTabSwitcherMode(UInt32 startIdx, Microsoft.Terminal.Settings.Model.TabSwitcherMode tabSwitcherMode);
|
||||
void EnableTabSearchMode();
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, TabBase> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Tab> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, String> CommandLineExecutionRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> PreviewAction;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalTab.h"
|
||||
#include "Tab.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
@ -19,11 +19,11 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TabPaletteItem::TabPaletteItem(const winrt::TerminalApp::TabBase& tab) :
|
||||
TabPaletteItem::TabPaletteItem(const winrt::TerminalApp::Tab& tab) :
|
||||
_tab{ tab }
|
||||
{
|
||||
_tabChangedRevoker = tab.PropertyChanged(winrt::auto_revoke, [=](auto& sender, auto& e) {
|
||||
if (auto senderTab{ sender.try_as<winrt::TerminalApp::TabBase>() })
|
||||
if (auto senderTab{ sender.try_as<winrt::TerminalApp::Tab>() })
|
||||
{
|
||||
auto changedProperty = e.PropertyName();
|
||||
if (changedProperty == L"Title")
|
||||
@ -38,10 +38,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
if (const auto terminalTab{ tab.try_as<winrt::TerminalApp::TerminalTab>() })
|
||||
if (const auto status = tab.TabStatus())
|
||||
{
|
||||
const auto status = terminalTab.TabStatus();
|
||||
|
||||
_tabStatusChangedRevoker = status.PropertyChanged(winrt::auto_revoke, [=](auto& /*sender*/, auto& /*e*/) {
|
||||
// Sometimes nested bindings do not get updated,
|
||||
// thus let's notify property changed on TabStatus when one of its properties changes
|
||||
|
||||
@ -71,9 +71,9 @@ namespace winrt::TerminalApp::implementation
|
||||
public TabPaletteItemT<TabPaletteItem>,
|
||||
BasePaletteItem<TabPaletteItem, winrt::TerminalApp::PaletteItemType::Tab>
|
||||
{
|
||||
TabPaletteItem(const winrt::TerminalApp::TabBase& tab);
|
||||
TabPaletteItem(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
winrt::TerminalApp::TabBase Tab() const noexcept
|
||||
winrt::TerminalApp::Tab Tab() const noexcept
|
||||
{
|
||||
return _tab.get();
|
||||
}
|
||||
@ -105,16 +105,13 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (auto tab = _tab.get())
|
||||
{
|
||||
if (auto terminalTab = tab.try_as<winrt::TerminalApp::TerminalTab>())
|
||||
{
|
||||
return terminalTab.TabStatus();
|
||||
}
|
||||
return tab.TabStatus();
|
||||
}
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::weak_ref<winrt::TerminalApp::TabBase> _tab;
|
||||
winrt::weak_ref<winrt::TerminalApp::Tab> _tab;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabChangedRevoker;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabStatusChangedRevoker;
|
||||
};
|
||||
|
||||
@ -2429,7 +2429,7 @@ std::optional<uint32_t> Pane::Id() noexcept
|
||||
|
||||
// Method Description:
|
||||
// - Sets this pane's ID
|
||||
// - Panes are given IDs upon creation by TerminalTab
|
||||
// - Panes are given IDs upon creation by Tab
|
||||
// Arguments:
|
||||
// - The number to set this pane's ID to
|
||||
void Pane::Id(uint32_t id) noexcept
|
||||
|
||||
@ -31,7 +31,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalTab;
|
||||
struct Tab;
|
||||
}
|
||||
|
||||
enum class Borders : int
|
||||
@ -398,6 +398,6 @@ private:
|
||||
LayoutSizeNode& operator=(const LayoutSizeNode& other);
|
||||
};
|
||||
|
||||
friend struct winrt::TerminalApp::implementation::TerminalTab;
|
||||
friend struct winrt::TerminalApp::implementation::Tab;
|
||||
friend class ::TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "HighlightedTextControl.idl";
|
||||
import "FilteredCommand.idl";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -4,8 +4,8 @@
|
||||
#pragma once
|
||||
#include "Pane.h"
|
||||
#include "ColorPickupFlyout.h"
|
||||
#include "TabBase.h"
|
||||
#include "TerminalTab.g.h"
|
||||
#include "Tab.h"
|
||||
#include "Tab.g.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
@ -15,10 +15,10 @@ namespace TerminalAppLocalTests
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalTab : TerminalTabT<TerminalTab, TabBase>
|
||||
struct Tab : TabT<Tab>
|
||||
{
|
||||
public:
|
||||
TerminalTab(std::shared_ptr<Pane> rootPane);
|
||||
Tab(std::shared_ptr<Pane> rootPane);
|
||||
|
||||
// Called after construction to perform the necessary setup, which relies on weak_ptr
|
||||
void Initialize();
|
||||
@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile() const noexcept;
|
||||
winrt::TerminalApp::IPaneContent GetActiveContent() const;
|
||||
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState);
|
||||
|
||||
void Scroll(const int delta);
|
||||
|
||||
@ -61,7 +61,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
void UpdateTitle();
|
||||
|
||||
void Shutdown() override;
|
||||
void Shutdown();
|
||||
void ClosePane();
|
||||
|
||||
void SetTabText(winrt::hstring title);
|
||||
@ -69,7 +69,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void ResetTabText();
|
||||
void ActivateTabRenamer();
|
||||
|
||||
virtual std::optional<winrt::Windows::UI::Color> GetTabColor() override;
|
||||
std::optional<winrt::Windows::UI::Color> GetTabColor();
|
||||
void SetRuntimeTabColor(const winrt::Windows::UI::Color& color);
|
||||
void ResetRuntimeTabColor();
|
||||
|
||||
@ -79,7 +79,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void EnterZoom();
|
||||
void ExitZoom();
|
||||
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const override;
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const;
|
||||
|
||||
int GetLeafPaneCount() const noexcept;
|
||||
|
||||
@ -98,16 +98,62 @@ namespace winrt::TerminalApp::implementation
|
||||
return _tabStatus;
|
||||
}
|
||||
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
|
||||
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
|
||||
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor);
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility CloseButtonVisibility();
|
||||
void CloseButtonVisibility(Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility visible);
|
||||
|
||||
til::event<winrt::delegate<void()>> RequestFocusActiveControl;
|
||||
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> CloseRequested;
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
til::typed_event<TerminalApp::TerminalPaneContent> RestartTerminalRequested;
|
||||
|
||||
til::typed_event<TerminalApp::TerminalTab, IInspectable> ActivePaneChanged;
|
||||
til::typed_event<TerminalApp::Tab, IInspectable> ActivePaneChanged;
|
||||
til::event<winrt::delegate<>> TabRaiseVisualBell;
|
||||
til::typed_event<IInspectable, IInspectable> TaskbarProgressChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewIndex, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewNumTabs, 0);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, PropertyChanged.raise, false);
|
||||
WINRT_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, PropertyChanged.raise, nullptr);
|
||||
|
||||
private:
|
||||
static constexpr double HeaderRenameBoxWidthDefault{ 165 };
|
||||
static constexpr double HeaderRenameBoxWidthTitleLength{ std::numeric_limits<double>::infinity() };
|
||||
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
|
||||
winrt::hstring _keyChord{};
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _themeColor{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _unfocusedThemeColor{ nullptr };
|
||||
til::color _tabRowColor;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility _closeButtonVisibility{ Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility::Always };
|
||||
|
||||
std::shared_ptr<Pane> _rootPane{ nullptr };
|
||||
std::shared_ptr<Pane> _activePane{ nullptr };
|
||||
std::shared_ptr<Pane> _zoomedPane{ nullptr };
|
||||
@ -163,12 +209,10 @@ namespace winrt::TerminalApp::implementation
|
||||
SafeDispatcherTimer _bellIndicatorTimer;
|
||||
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _MakeTabViewItem() override;
|
||||
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu() override;
|
||||
virtual winrt::hstring _CreateToolTipTitle() override;
|
||||
void _CreateContextMenu();
|
||||
winrt::hstring _CreateToolTipTitle();
|
||||
|
||||
void _DetachEventHandlersFromContent(const uint32_t paneId);
|
||||
void _AttachEventHandlersToContent(const uint32_t paneId, const winrt::TerminalApp::IPaneContent& content);
|
||||
@ -187,7 +231,23 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _DuplicateTab();
|
||||
|
||||
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() override;
|
||||
winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush();
|
||||
|
||||
void _MakeTabViewItem();
|
||||
|
||||
void _AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
void _EnableMenuItems();
|
||||
void _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateToolTip();
|
||||
|
||||
void _RecalculateAndApplyTabColor();
|
||||
void _ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color);
|
||||
void _ClearTabBackgroundColor();
|
||||
void _RefreshVisualState();
|
||||
|
||||
bool _focused() const noexcept;
|
||||
void _updateIsClosable();
|
||||
|
||||
void _addBroadcastHandlers(const winrt::Microsoft::Terminal::Control::TermControl& control, ContentEventTokens& events);
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
import "ShortcutActionDispatch.idl";
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
unsealed runtimeclass TabBase : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
runtimeclass Tab : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
String Title { get; };
|
||||
String Icon { get; };
|
||||
@ -14,6 +15,9 @@ namespace TerminalApp
|
||||
Microsoft.UI.Xaml.Controls.TabViewItem TabViewItem { get; };
|
||||
Windows.UI.Xaml.FrameworkElement Content { get; };
|
||||
|
||||
// May be Null
|
||||
TerminalTabStatus TabStatus { get; };
|
||||
|
||||
UInt32 TabViewIndex;
|
||||
UInt32 TabViewNumTabs;
|
||||
|
||||
@ -1,753 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "TabBase.h"
|
||||
#include "TabBase.g.cpp"
|
||||
#include "Utils.h"
|
||||
#include "ColorHelper.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::System;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
|
||||
// Method Description:
|
||||
// - Prepares this tab for being removed from the UI hierarchy
|
||||
void TabBase::Shutdown()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// NOTE: `TerminalPage::_HandleCloseTabRequested` relies on the content being null after this call.
|
||||
Content(nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a context menu attached to the tab.
|
||||
// Currently contains elements allowing the user to close the selected tab
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_CreateContextMenu()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Build the menu
|
||||
Controls::MenuFlyout contextMenuFlyout;
|
||||
// GH#5750 - When the context menu is dismissed with ESC, toss the focus
|
||||
// back to our control.
|
||||
contextMenuFlyout.Closed([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->RequestFocusActiveControl.raise();
|
||||
}
|
||||
});
|
||||
_AppendMoveMenuItems(contextMenuFlyout);
|
||||
_AppendCloseMenuItems(contextMenuFlyout);
|
||||
TabViewItem().ContextFlyout(contextMenuFlyout);
|
||||
}
|
||||
|
||||
void TabBase::_AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Move to new window
|
||||
{
|
||||
Controls::FontIcon moveTabToNewWindowTabSymbol;
|
||||
moveTabToNewWindowTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
moveTabToNewWindowTabSymbol.Glyph(L"\xE8A7");
|
||||
|
||||
_moveToNewWindowMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ L"new", MoveTabDirection::Forward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveToNewWindowMenuItem.Text(RS_(L"MoveTabToNewWindowText"));
|
||||
_moveToNewWindowMenuItem.Icon(moveTabToNewWindowTabSymbol);
|
||||
|
||||
const auto moveTabToNewWindowToolTip = RS_(L"MoveTabToNewWindowToolTip");
|
||||
WUX::Controls::ToolTipService::SetToolTip(_moveToNewWindowMenuItem, box_value(moveTabToNewWindowToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_moveToNewWindowMenuItem, moveTabToNewWindowToolTip);
|
||||
}
|
||||
|
||||
// Move left
|
||||
{
|
||||
_moveLeftMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ hstring{}, MoveTabDirection::Backward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveLeftMenuItem.Text(RS_(L"TabMoveLeft"));
|
||||
}
|
||||
|
||||
// Move right
|
||||
{
|
||||
_moveRightMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ hstring{}, MoveTabDirection::Forward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveRightMenuItem.Text(RS_(L"TabMoveRight"));
|
||||
}
|
||||
|
||||
// Create a sub-menu for our extended move tab items.
|
||||
Controls::MenuFlyoutSubItem moveSubMenu;
|
||||
moveSubMenu.Text(RS_(L"TabMoveSubMenu"));
|
||||
moveSubMenu.Items().Append(_moveToNewWindowMenuItem);
|
||||
moveSubMenu.Items().Append(_moveRightMenuItem);
|
||||
moveSubMenu.Items().Append(_moveLeftMenuItem);
|
||||
flyout.Items().Append(moveSubMenu);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Append the close menu items to the context menu flyout
|
||||
// Arguments:
|
||||
// - flyout - the menu flyout to which the close items must be appended
|
||||
// Return Value:
|
||||
// - the sub-item that we use for all the nested "close" entries. This
|
||||
// enables subclasses to add their own entries to this menu.
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem TabBase::_AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Close tabs after
|
||||
_closeTabsAfterMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
CloseTabsAfterArgs args{ tab->_TabViewIndex };
|
||||
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
|
||||
tab->_dispatch.DoAction(*tab, closeTabsAfter);
|
||||
}
|
||||
});
|
||||
_closeTabsAfterMenuItem.Text(RS_(L"TabCloseAfter"));
|
||||
const auto closeTabsAfterToolTip = RS_(L"TabCloseAfterToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(_closeTabsAfterMenuItem, box_value(closeTabsAfterToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_closeTabsAfterMenuItem, closeTabsAfterToolTip);
|
||||
|
||||
// Close other tabs
|
||||
_closeOtherTabsMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
CloseOtherTabsArgs args{ tab->_TabViewIndex };
|
||||
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
|
||||
tab->_dispatch.DoAction(*tab, closeOtherTabs);
|
||||
}
|
||||
});
|
||||
_closeOtherTabsMenuItem.Text(RS_(L"TabCloseOther"));
|
||||
const auto closeOtherTabsToolTip = RS_(L"TabCloseOtherToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(_closeOtherTabsMenuItem, box_value(closeOtherTabsToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_closeOtherTabsMenuItem, closeOtherTabsToolTip);
|
||||
|
||||
// Close
|
||||
Controls::MenuFlyoutItem closeTabMenuItem;
|
||||
Controls::FontIcon closeSymbol;
|
||||
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
closeSymbol.Glyph(L"\xE711");
|
||||
|
||||
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->CloseRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
closeTabMenuItem.Text(RS_(L"TabClose"));
|
||||
closeTabMenuItem.Icon(closeSymbol);
|
||||
const auto closeTabToolTip = RS_(L"TabCloseToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(closeTabMenuItem, box_value(closeTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(closeTabMenuItem, closeTabToolTip);
|
||||
|
||||
// Create a sub-menu for our extended close items.
|
||||
Controls::MenuFlyoutSubItem closeSubMenu;
|
||||
closeSubMenu.Text(RS_(L"TabCloseSubMenu"));
|
||||
closeSubMenu.Items().Append(_closeTabsAfterMenuItem);
|
||||
closeSubMenu.Items().Append(_closeOtherTabsMenuItem);
|
||||
flyout.Items().Append(closeSubMenu);
|
||||
|
||||
flyout.Items().Append(closeTabMenuItem);
|
||||
|
||||
return closeSubMenu;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enable menu items based on tab index and total number of tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_EnableMenuItems()
|
||||
{
|
||||
const auto tabIndex = TabViewIndex();
|
||||
const auto numOfTabs = TabViewNumTabs();
|
||||
|
||||
// enabled if there are other tabs
|
||||
_closeOtherTabsMenuItem.IsEnabled(numOfTabs > 1);
|
||||
|
||||
// enabled if there are other tabs on the right
|
||||
_closeTabsAfterMenuItem.IsEnabled(tabIndex < numOfTabs - 1);
|
||||
|
||||
// enabled if not left-most tab
|
||||
_moveLeftMenuItem.IsEnabled(tabIndex > 0);
|
||||
|
||||
// enabled if not last tab
|
||||
_moveRightMenuItem.IsEnabled(tabIndex < numOfTabs - 1);
|
||||
}
|
||||
|
||||
void TabBase::UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
TabViewIndex(idx);
|
||||
TabViewNumTabs(numTabs);
|
||||
_EnableMenuItems();
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
|
||||
void TabBase::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
|
||||
void TabBase::SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_actionMap = actionMap;
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the key chord resulting in switch to the current tab.
|
||||
// Updates tool tip if required
|
||||
// Arguments:
|
||||
// - keyChord - string representation of the key chord that switches to the current tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_UpdateSwitchToTabKeyChord()
|
||||
{
|
||||
const auto id = fmt::format(FMT_COMPILE(L"Terminal.SwitchToTab{}"), _TabViewIndex);
|
||||
const auto keyChord{ _actionMap.GetKeyBindingForAction(id) };
|
||||
const auto keyChordText = keyChord ? KeyChordSerialization::ToString(keyChord) : L"";
|
||||
|
||||
if (_keyChord == keyChordText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_keyChord = keyChordText;
|
||||
_UpdateToolTip();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a text for the title run in the tool tip by returning tab title
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The value to populate in the title run of the tool tip
|
||||
winrt::hstring TabBase::_CreateToolTipTitle()
|
||||
{
|
||||
return _Title;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets tab tool tip to a concatenation of title and key chord
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_UpdateToolTip()
|
||||
{
|
||||
auto titleRun = WUX::Documents::Run();
|
||||
titleRun.Text(_CreateToolTipTitle());
|
||||
|
||||
auto textBlock = WUX::Controls::TextBlock{};
|
||||
textBlock.TextWrapping(WUX::TextWrapping::Wrap);
|
||||
textBlock.TextAlignment(WUX::TextAlignment::Center);
|
||||
textBlock.Inlines().Append(titleRun);
|
||||
|
||||
if (!_keyChord.empty())
|
||||
{
|
||||
auto keyChordRun = WUX::Documents::Run();
|
||||
keyChordRun.Text(_keyChord);
|
||||
keyChordRun.FontStyle(winrt::Windows::UI::Text::FontStyle::Italic);
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(keyChordRun);
|
||||
}
|
||||
|
||||
WUX::Controls::ToolTip toolTip{};
|
||||
toolTip.Content(textBlock);
|
||||
WUX::Controls::ToolTipService::SetToolTip(TabViewItem(), toolTip);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_MakeTabViewItem()
|
||||
{
|
||||
TabViewItem(::winrt::MUX::Controls::TabViewItem{});
|
||||
|
||||
// GH#3609 If the tab was tapped, and no one else was around to handle
|
||||
// it, then ask our parent to toss focus into the active control.
|
||||
TabViewItem().Tapped([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->RequestFocusActiveControl.raise();
|
||||
}
|
||||
});
|
||||
|
||||
// BODGY: When the tab is drag/dropped, the TabView gets a
|
||||
// TabDragStarting. However, the way it is implemented[^1], the
|
||||
// TabViewItem needs either an Item or a Content for the event to
|
||||
// include the correct TabViewItem. Otherwise, it will just return the
|
||||
// first TabViewItem in the TabView with the same Content as the dragged
|
||||
// tab (which, if the Content is null, will be the _first_ tab).
|
||||
//
|
||||
// So here, we'll stick an empty border in, just so that every tab has a
|
||||
// Content which is not equal to the others.
|
||||
//
|
||||
// [^1]: microsoft-ui-xaml/blob/92fbfcd55f05c92ac65569f5d284c5b36492091e/dev/TabView/TabView.cpp#L751-L758
|
||||
TabViewItem().Content(winrt::WUX::Controls::Border{});
|
||||
}
|
||||
|
||||
std::optional<winrt::Windows::UI::Color> TabBase::GetTabColor()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TabBase::ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_themeColor = focused;
|
||||
_unfocusedThemeColor = unfocused;
|
||||
_tabRowColor = tabRowColor;
|
||||
_RecalculateAndApplyTabColor();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This function dispatches a function to the UI thread to recalculate
|
||||
// what this tab's current background color should be. If a color is set,
|
||||
// it will apply the given color to the tab's background. Otherwise, it
|
||||
// will clear the tab's background color.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_RecalculateAndApplyTabColor()
|
||||
{
|
||||
// GetTabColor will return the color set by the color picker, or the
|
||||
// color specified in the profile. If neither of those were set,
|
||||
// then look to _themeColor to see if there's a value there.
|
||||
// Otherwise, clear our color, falling back to the TabView defaults.
|
||||
const auto currentColor = GetTabColor();
|
||||
if (currentColor.has_value())
|
||||
{
|
||||
_ApplyTabColorOnUIThread(currentColor.value());
|
||||
}
|
||||
else if (_themeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ _BackgroundBrush() };
|
||||
|
||||
if (const auto themeBrush{ _themeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
// ThemeColor.Evaluate will get us a Brush (because the
|
||||
// TermControl could have an acrylic BG, for example). Take
|
||||
// that brush, and get the color out of it. We don't really
|
||||
// want to have the tab items themselves be acrylic.
|
||||
_ApplyTabColorOnUIThread(til::color{ ThemeColor::ColorFromBrush(themeBrush) });
|
||||
}
|
||||
else
|
||||
{
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Applies the given color to the background of this tab's TabViewItem.
|
||||
// - Sets the tab foreground color depending on the luminance of
|
||||
// the background color
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - color: the color the user picked for their tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
Media::SolidColorBrush selectedTabBrush{};
|
||||
Media::SolidColorBrush deselectedTabBrush{};
|
||||
Media::SolidColorBrush fontBrush{};
|
||||
Media::SolidColorBrush deselectedFontBrush{};
|
||||
Media::SolidColorBrush secondaryFontBrush{};
|
||||
Media::SolidColorBrush hoverTabBrush{};
|
||||
Media::SolidColorBrush subtleFillColorSecondaryBrush;
|
||||
Media::SolidColorBrush subtleFillColorTertiaryBrush;
|
||||
|
||||
// calculate the luminance of the current color and select a font
|
||||
// color based on that
|
||||
// see https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(color))
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorSecondary.A = 0x09;
|
||||
subtleFillColorSecondaryBrush.Color(subtleFillColorSecondary);
|
||||
auto subtleFillColorTertiary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorTertiary.A = 0x06;
|
||||
subtleFillColorTertiaryBrush.Color(subtleFillColorTertiary);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::White();
|
||||
subtleFillColorSecondary.A = 0x0F;
|
||||
subtleFillColorSecondaryBrush.Color(subtleFillColorSecondary);
|
||||
auto subtleFillColorTertiary = winrt::Windows::UI::Colors::White();
|
||||
subtleFillColorTertiary.A = 0x0A;
|
||||
subtleFillColorTertiaryBrush.Color(subtleFillColorTertiary);
|
||||
}
|
||||
|
||||
// The tab font should be based on the evaluated appearance of the tab color layered on tab row.
|
||||
const auto layeredTabColor = til::color{ color }.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(layeredTabColor))
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::Black();
|
||||
// For alpha value see: https://github.com/microsoft/microsoft-ui-xaml/blob/7a33ad772d77d908aa6b316ec24e6d2eb3ebf571/dev/CommonStyles/Common_themeresources_any.xaml#L269
|
||||
secondaryFontColor.A = 0x9E;
|
||||
secondaryFontBrush.Color(secondaryFontColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::White());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::White();
|
||||
// For alpha value see: https://github.com/microsoft/microsoft-ui-xaml/blob/7a33ad772d77d908aa6b316ec24e6d2eb3ebf571/dev/CommonStyles/Common_themeresources_any.xaml#L14
|
||||
secondaryFontColor.A = 0xC5;
|
||||
secondaryFontBrush.Color(secondaryFontColor);
|
||||
}
|
||||
|
||||
selectedTabBrush.Color(color);
|
||||
|
||||
// Start with the current tab color, set to Opacity=.3
|
||||
til::color deselectedTabColor{ color };
|
||||
deselectedTabColor = deselectedTabColor.with_alpha(77); // 255 * .3 = 77
|
||||
|
||||
// If we DON'T have a color set from the color picker, or the profile's
|
||||
// tabColor, but we do have a unfocused color in the theme, use the
|
||||
// unfocused theme color here instead.
|
||||
if (!GetTabColor().has_value() &&
|
||||
_unfocusedThemeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ _BackgroundBrush() };
|
||||
|
||||
// Get the color of the brush.
|
||||
if (const auto themeBrush{ _unfocusedThemeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
// We did figure out the brush. Get the color out of it. If it
|
||||
// was "accent" or "terminalBackground", then we're gonna set
|
||||
// the alpha to .3 manually here.
|
||||
// (ThemeColor::UnfocusedTabOpacity will do this for us). If the
|
||||
// user sets both unfocused and focused tab.background to
|
||||
// terminalBackground, this will allow for some differentiation
|
||||
// (and is generally just sensible).
|
||||
deselectedTabColor = til::color{ ThemeColor::ColorFromBrush(themeBrush) }.with_alpha(_unfocusedThemeColor.UnfocusedTabOpacity());
|
||||
}
|
||||
}
|
||||
|
||||
// currently if a tab has a custom color, a deselected state is
|
||||
// signified by using the same color with a bit of transparency
|
||||
deselectedTabBrush.Color(deselectedTabColor.with_alpha(255));
|
||||
deselectedTabBrush.Opacity(deselectedTabColor.a / 255.f);
|
||||
|
||||
hoverTabBrush.Color(color);
|
||||
hoverTabBrush.Opacity(0.6);
|
||||
|
||||
// Account for the color of the tab row when setting the color of text
|
||||
// on inactive tabs. Consider:
|
||||
// * black active tabs
|
||||
// * on a white tab row
|
||||
// * with a transparent inactive tab color
|
||||
//
|
||||
// We don't want that to result in white text on a white tab row for
|
||||
// inactive tabs.
|
||||
const auto deselectedActualColor = deselectedTabColor.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(deselectedActualColor))
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::White());
|
||||
}
|
||||
|
||||
// Add the empty theme dictionaries
|
||||
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
|
||||
ResourceDictionary lightThemeDictionary;
|
||||
ResourceDictionary darkThemeDictionary;
|
||||
ResourceDictionary highContrastThemeDictionary;
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"Light"), lightThemeDictionary);
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"Dark"), darkThemeDictionary);
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"HighContrast"), highContrastThemeDictionary);
|
||||
|
||||
// Apply the color to the tab
|
||||
TabViewItem().Background(deselectedTabBrush);
|
||||
|
||||
// Now actually set the resources we want in them.
|
||||
// Before, we used to put these on the ResourceDictionary directly.
|
||||
// However, HighContrast mode may require some adjustments. So let's just add
|
||||
// all three so we can make those adjustments on the HighContrast version.
|
||||
for (const auto& [k, v] : tabItemThemeResources)
|
||||
{
|
||||
const bool isHighContrast = winrt::unbox_value<hstring>(k) == L"HighContrast";
|
||||
const auto& currentDictionary = v.as<ResourceDictionary>();
|
||||
|
||||
// TabViewItem.Background
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), isHighContrast ? fontBrush : hoverTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush);
|
||||
|
||||
// TabViewItem.Foreground (aka text)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForeground"), deselectedFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), isHighContrast ? selectedTabBrush : fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Foreground (aka X)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForeground"), deselectedFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPressed"), isHighContrast ? deselectedFontBrush : secondaryFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPointerOver"), isHighContrast ? deselectedFontBrush : fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPressedCloseButtonForeground"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPointerOverCloseButtonForeground"), isHighContrast ? selectedTabBrush : fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderSelectedCloseButtonForeground"), fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Background (aka X button)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPressed"), isHighContrast ? selectedTabBrush : subtleFillColorTertiaryBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPointerOver"), isHighContrast ? selectedTabBrush : subtleFillColorSecondaryBrush);
|
||||
|
||||
// A few miscellaneous resources that WinUI said may be removed in the future
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPressed"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPointerOver"), fontBrush);
|
||||
|
||||
// Add a few extra ones for high contrast mode
|
||||
// BODGY: contrary to the docs, Insert() seems to throw if the value already exists
|
||||
// Make sure you don't touch any that already exist here!
|
||||
if (isHighContrast)
|
||||
{
|
||||
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPressed"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPointerOver"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushSelected"), fontBrush);
|
||||
}
|
||||
}
|
||||
|
||||
_RefreshVisualState();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Clear out any color we've set for the TabViewItem.
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_ClearTabBackgroundColor()
|
||||
{
|
||||
static const winrt::hstring keys[] = {
|
||||
// TabViewItem.Background
|
||||
L"TabViewItemHeaderBackground",
|
||||
L"TabViewItemHeaderBackgroundSelected",
|
||||
L"TabViewItemHeaderBackgroundPointerOver",
|
||||
L"TabViewItemHeaderBackgroundPressed",
|
||||
|
||||
// TabViewItem.Foreground (aka text)
|
||||
L"TabViewItemHeaderForeground",
|
||||
L"TabViewItemHeaderForegroundSelected",
|
||||
L"TabViewItemHeaderForegroundPointerOver",
|
||||
L"TabViewItemHeaderForegroundPressed",
|
||||
|
||||
// TabViewItem.CloseButton.Foreground (aka X)
|
||||
L"TabViewItemHeaderCloseButtonForeground",
|
||||
L"TabViewItemHeaderForegroundSelected",
|
||||
L"TabViewItemHeaderCloseButtonForegroundPointerOver",
|
||||
L"TabViewItemHeaderCloseButtonForegroundPressed",
|
||||
|
||||
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
|
||||
L"TabViewItemHeaderPressedCloseButtonForeground",
|
||||
L"TabViewItemHeaderPointerOverCloseButtonForeground",
|
||||
L"TabViewItemHeaderSelectedCloseButtonForeground",
|
||||
|
||||
// TabViewItem.CloseButton.Background (aka X button)
|
||||
L"TabViewItemHeaderCloseButtonBackground",
|
||||
L"TabViewItemHeaderCloseButtonBackgroundPressed",
|
||||
L"TabViewItemHeaderCloseButtonBackgroundPointerOver",
|
||||
|
||||
// A few miscellaneous resources that WinUI said may be removed in the future
|
||||
L"TabViewButtonForegroundActiveTab",
|
||||
L"TabViewButtonForegroundPressed",
|
||||
L"TabViewButtonForegroundPointerOver",
|
||||
|
||||
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushPressed",
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushPointerOver",
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushSelected"
|
||||
};
|
||||
|
||||
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
|
||||
|
||||
// simply clear any of the colors in the tab's dict
|
||||
for (const auto& keyString : keys)
|
||||
{
|
||||
const auto key = winrt::box_value(keyString);
|
||||
for (const auto& [_, v] : tabItemThemeResources)
|
||||
{
|
||||
const auto& themeDictionary = v.as<ResourceDictionary>();
|
||||
themeDictionary.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// GH#11382 DON'T set the background to null. If you do that, then the
|
||||
// tab won't be hit testable at all. Transparent, however, is a totally
|
||||
// valid hit test target. That makes sense.
|
||||
TabViewItem().Background(WUX::Media::SolidColorBrush{ Windows::UI::Colors::Transparent() });
|
||||
|
||||
_RefreshVisualState();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// BODGY
|
||||
// - Toggles the requested theme of the tab view item,
|
||||
// so that changes to the tab color are reflected immediately
|
||||
// - Prior to MUX 2.8, we only toggled the visual state here, but that seemingly
|
||||
// doesn't work in 2.8.
|
||||
// - Just changing the Theme also doesn't seem to work by itself - there
|
||||
// seems to be a way for the tab to set the deselected foreground onto
|
||||
// itself as it becomes selected. If the mouse isn't over the tab, that
|
||||
// can result in mismatched fg/bg's (see GH#15184). So that's right, we
|
||||
// need to do both.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_RefreshVisualState()
|
||||
{
|
||||
const auto& item{ TabViewItem() };
|
||||
|
||||
const auto& reqTheme = TabViewItem().RequestedTheme();
|
||||
item.RequestedTheme(ElementTheme::Light);
|
||||
item.RequestedTheme(ElementTheme::Dark);
|
||||
item.RequestedTheme(reqTheme);
|
||||
|
||||
if (TabViewItem().IsSelected())
|
||||
{
|
||||
VisualStateManager::GoToState(item, L"Normal", true);
|
||||
VisualStateManager::GoToState(item, L"Selected", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager::GoToState(item, L"Selected", true);
|
||||
VisualStateManager::GoToState(item, L"Normal", true);
|
||||
}
|
||||
}
|
||||
|
||||
TabCloseButtonVisibility TabBase::CloseButtonVisibility()
|
||||
{
|
||||
return _closeButtonVisibility;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - set our internal state to track if we were requested to have a visible
|
||||
// tab close button or not.
|
||||
// - This is called every time the active tab changes. That way, the changes
|
||||
// in focused tab can be reflected for the "ActiveOnly" state.
|
||||
void TabBase::CloseButtonVisibility(TabCloseButtonVisibility visibility)
|
||||
{
|
||||
_closeButtonVisibility = visibility;
|
||||
_updateIsClosable();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update our close button's visibility, to reflect both the ReadOnly
|
||||
// state of the tab content, and also if if we were told to have a visible
|
||||
// close button at all.
|
||||
// - the tab being read-only takes precedence. That will always suppress
|
||||
// the close button.
|
||||
// - Otherwise we'll use the state set in CloseButtonVisibility to control
|
||||
// the tab's visibility.
|
||||
void TabBase::_updateIsClosable()
|
||||
{
|
||||
bool isClosable = true;
|
||||
|
||||
if (ReadOnly())
|
||||
{
|
||||
isClosable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (_closeButtonVisibility)
|
||||
{
|
||||
case TabCloseButtonVisibility::Never:
|
||||
isClosable = false;
|
||||
break;
|
||||
case TabCloseButtonVisibility::Hover:
|
||||
isClosable = true;
|
||||
break;
|
||||
case TabCloseButtonVisibility::ActiveOnly:
|
||||
isClosable = _focused();
|
||||
break;
|
||||
default:
|
||||
isClosable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TabViewItem().IsClosable(isClosable);
|
||||
}
|
||||
|
||||
bool TabBase::_focused() const noexcept
|
||||
{
|
||||
return _focusState != FocusState::Unfocused;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
#include "TabBase.g.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class TabTests;
|
||||
};
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TabBase : TabBaseT<TabBase>
|
||||
{
|
||||
public:
|
||||
virtual void Focus(winrt::Windows::UI::Xaml::FocusState focusState) = 0;
|
||||
|
||||
virtual void Shutdown();
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
|
||||
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const = 0;
|
||||
|
||||
virtual std::optional<winrt::Windows::UI::Color> GetTabColor();
|
||||
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor);
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility CloseButtonVisibility();
|
||||
void CloseButtonVisibility(Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility visible);
|
||||
|
||||
til::event<winrt::delegate<void()>> RequestFocusActiveControl;
|
||||
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> CloseRequested;
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewIndex, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewNumTabs, 0);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, PropertyChanged.raise, false);
|
||||
WINRT_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, PropertyChanged.raise, nullptr);
|
||||
|
||||
protected:
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
|
||||
winrt::hstring _keyChord{};
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _themeColor{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _unfocusedThemeColor{ nullptr };
|
||||
til::color _tabRowColor;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility _closeButtonVisibility{ Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility::Always };
|
||||
|
||||
virtual void _CreateContextMenu();
|
||||
virtual winrt::hstring _CreateToolTipTitle();
|
||||
|
||||
virtual void _MakeTabViewItem();
|
||||
|
||||
void _AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
void _EnableMenuItems();
|
||||
void _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateToolTip();
|
||||
|
||||
void _RecalculateAndApplyTabColor();
|
||||
void _ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color);
|
||||
void _ClearTabBackgroundColor();
|
||||
void _RefreshVisualState();
|
||||
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() = 0;
|
||||
|
||||
bool _focused() const noexcept;
|
||||
void _updateIsClosable();
|
||||
|
||||
friend class ::TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
}
|
||||
@ -99,7 +99,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - newTabImpl: the uninitialized tab.
|
||||
// - insertPosition: Optional parameter to indicate the position of tab.
|
||||
void TerminalPage::_InitializeTab(winrt::com_ptr<TerminalTab> newTabImpl, uint32_t insertPosition)
|
||||
void TerminalPage::_InitializeTab(winrt::com_ptr<Tab> newTabImpl, uint32_t insertPosition)
|
||||
{
|
||||
newTabImpl->Initialize();
|
||||
|
||||
@ -206,11 +206,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - pane: The pane to use as the root.
|
||||
// - insertPosition: Optional parameter to indicate the position of tab.
|
||||
TerminalApp::TerminalTab TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
|
||||
TerminalApp::Tab TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
|
||||
{
|
||||
if (pane)
|
||||
{
|
||||
auto newTabImpl = winrt::make_self<TerminalTab>(pane);
|
||||
auto newTabImpl = winrt::make_self<Tab>(pane);
|
||||
_InitializeTab(newTabImpl, insertPosition);
|
||||
return *newTabImpl;
|
||||
}
|
||||
@ -222,7 +222,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab's icon to that icon.
|
||||
// Arguments:
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTabIcon(TerminalTab& tab)
|
||||
void TerminalPage::_UpdateTabIcon(Tab& tab)
|
||||
{
|
||||
if (const auto content{ tab.GetActiveContent() })
|
||||
{
|
||||
@ -272,9 +272,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Duplicates the current focused tab
|
||||
void TerminalPage::_DuplicateFocusedTab()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_DuplicateTab(*terminalTab);
|
||||
_DuplicateTab(*activeTab);
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Duplicates specified tab
|
||||
// Arguments:
|
||||
// - tab: tab to duplicate
|
||||
void TerminalPage::_DuplicateTab(const TerminalTab& tab)
|
||||
void TerminalPage::_DuplicateTab(const Tab& tab)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -315,7 +315,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Exports the content of the Terminal Buffer inside the tab
|
||||
// Arguments:
|
||||
// - tab: tab to export
|
||||
safe_void_coroutine TerminalPage::_ExportTab(const TerminalTab& tab, winrt::hstring filepath)
|
||||
safe_void_coroutine TerminalPage::_ExportTab(const Tab& tab, winrt::hstring filepath)
|
||||
{
|
||||
// This will be used to set up the file picker "filter", to select .txt
|
||||
// files by default.
|
||||
@ -401,7 +401,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::TabBase tab)
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab)
|
||||
{
|
||||
if (tab.ReadOnly())
|
||||
{
|
||||
@ -414,7 +414,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
auto t = winrt::get_self<implementation::TabBase>(tab);
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
|
||||
@ -425,7 +425,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Removes the tab (both TerminalControl and XAML)
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
void TerminalPage::_RemoveTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_RemoveTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t tabIndex{};
|
||||
if (!_tabs.IndexOf(tab, tabIndex))
|
||||
@ -597,7 +597,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab - tab to select
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_OnSwitchToTabRequested(const IInspectable& /*sender*/, const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_OnSwitchToTabRequested(const IInspectable& /*sender*/, const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t index{};
|
||||
if (_tabs.IndexOf(tab, index))
|
||||
@ -628,7 +628,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// no tab is currently selected, returns nullopt.
|
||||
// Return Value:
|
||||
// - the index of the currently focused tab if there is one, else nullopt
|
||||
std::optional<uint32_t> TerminalPage::_GetTabIndex(const TerminalApp::TabBase& tab) const noexcept
|
||||
std::optional<uint32_t> TerminalPage::_GetTabIndex(const TerminalApp::Tab& tab) const noexcept
|
||||
{
|
||||
uint32_t i;
|
||||
if (_tabs.IndexOf(tab, i))
|
||||
@ -641,7 +641,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns the currently focused tab. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetFocusedTab() const noexcept
|
||||
winrt::TerminalApp::Tab TerminalPage::_GetFocusedTab() const noexcept
|
||||
{
|
||||
if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
@ -653,11 +653,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns a com_ptr to the currently focused tab implementation. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_GetFocusedTabImpl() const noexcept
|
||||
winrt::com_ptr<Tab> TerminalPage::_GetFocusedTabImpl() const noexcept
|
||||
{
|
||||
if (auto tab{ _GetFocusedTab() })
|
||||
{
|
||||
return _GetTerminalTabImpl(tab);
|
||||
return _GetTabImpl(tab);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -665,7 +665,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns a tab corresponding to a view item. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept
|
||||
winrt::TerminalApp::Tab TerminalPage::_GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept
|
||||
{
|
||||
uint32_t tabIndexFromControl{};
|
||||
const auto items{ _tabView.TabItems() };
|
||||
@ -687,7 +687,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: tab to focus.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
safe_void_coroutine TerminalPage::_SetFocusedTab(const winrt::TerminalApp::TabBase tab)
|
||||
safe_void_coroutine TerminalPage::_SetFocusedTab(const winrt::TerminalApp::Tab tab)
|
||||
{
|
||||
// GH#1117: This is a workaround because _tabView.SelectedIndex(tabIndex)
|
||||
// sometimes set focus to an incorrect tab after removing some tabs
|
||||
@ -774,11 +774,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab's Closed event.
|
||||
safe_void_coroutine TerminalPage::_CloseFocusedPane()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
if (const auto pane{ terminalTab->GetActivePane() })
|
||||
if (const auto pane{ activeTab->GetActivePane() })
|
||||
{
|
||||
if (co_await _PaneConfirmCloseReadOnly(pane))
|
||||
{
|
||||
@ -793,7 +793,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - weakTab: weak reference to the tab that the pane belongs to.
|
||||
// - paneIds: collection of the IDs of the panes that are marked for removal.
|
||||
void TerminalPage::_ClosePanes(weak_ref<TerminalTab> weakTab, std::vector<uint32_t> paneIds)
|
||||
void TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
|
||||
{
|
||||
if (auto strongTab{ weakTab.get() })
|
||||
{
|
||||
@ -838,7 +838,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Closes provided tabs one by one
|
||||
// Arguments:
|
||||
// - tabs - tabs to remove
|
||||
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs)
|
||||
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs)
|
||||
{
|
||||
for (auto& tab : tabs)
|
||||
{
|
||||
@ -926,7 +926,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// WinUI asynchronously updates its tab view items, so it may happen that we're given a
|
||||
// `TabViewItem` that still contains a `TabBase` which has actually already been removed.
|
||||
// `TabViewItem` that still contains a `Tab` which has actually already been removed.
|
||||
// First we must yield once, to flush out whatever TabView is currently doing.
|
||||
const auto strong = get_strong();
|
||||
co_await wil::resume_foreground(Dispatcher());
|
||||
@ -966,7 +966,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_UpdatedSelectedTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_UpdatedSelectedTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
// Unfocus all the tabs.
|
||||
for (const auto& tab : _tabs)
|
||||
@ -1007,10 +1007,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_updateThemeColors();
|
||||
|
||||
auto tab_impl = _GetTerminalTabImpl(tab);
|
||||
if (tab_impl)
|
||||
auto tabImpl = _GetTabImpl(tab);
|
||||
if (tabImpl)
|
||||
{
|
||||
auto profile = tab_impl->GetFocusedProfile();
|
||||
auto profile = tabImpl->GetFocusedProfile();
|
||||
_UpdateBackground(profile);
|
||||
}
|
||||
}
|
||||
@ -1057,7 +1057,7 @@ namespace winrt::TerminalApp::implementation
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto tab{ _tabs.GetAt(i) };
|
||||
auto tabImpl{ winrt::get_self<TabBase>(tab) };
|
||||
auto tabImpl{ winrt::get_self<Tab>(tab) };
|
||||
tabImpl->UpdateTabViewIndex(i, size);
|
||||
}
|
||||
}
|
||||
@ -1068,7 +1068,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: tab to bump.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateMRUTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_UpdateMRUTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t mruIndex;
|
||||
if (_mruTabs.IndexOf(tab, mruIndex))
|
||||
|
||||
@ -99,15 +99,12 @@
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BasePaletteItem.h" />
|
||||
<ClInclude Include="TabBase.h">
|
||||
<DependentUpon>TabBase.idl</DependentUpon>
|
||||
<ClInclude Include="Tab.h">
|
||||
<DependentUpon>Tab.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TaskbarState.h">
|
||||
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TerminalTab.h">
|
||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TerminalPage.h">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -206,16 +203,13 @@
|
||||
<DependentUpon>PaletteItemTemplateSelector.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TabBase.cpp">
|
||||
<DependentUpon>TabBase.idl</DependentUpon>
|
||||
<ClCompile Include="Tab.cpp">
|
||||
<DependentUpon>Tab.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fzf/fzf.cpp" />
|
||||
<ClCompile Include="TaskbarState.cpp">
|
||||
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalTab.cpp">
|
||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalPage.cpp">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -333,9 +327,8 @@
|
||||
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="TabBase.idl" />
|
||||
<Midl Include="Tab.idl" />
|
||||
<Midl Include="TaskbarState.idl" />
|
||||
<Midl Include="TerminalTab.idl" />
|
||||
<Midl Include="TerminalPage.idl">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
||||
@ -81,9 +81,6 @@
|
||||
<Midl Include="ShortcutActionDispatch.idl">
|
||||
<Filter>settings</Filter>
|
||||
</Midl>
|
||||
<Midl Include="TerminalTab.idl">
|
||||
<Filter>tab</Filter>
|
||||
</Midl>
|
||||
<Midl Include="FilteredCommand.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
@ -91,7 +88,7 @@
|
||||
<Filter>tab</Filter>
|
||||
</Midl>
|
||||
<Midl Include="PaletteItemTemplateSelector.idl" />
|
||||
<Midl Include="TabBase.idl" />
|
||||
<Midl Include="Tab.idl" />
|
||||
<Midl Include="TerminalWindow.idl" />
|
||||
<Midl Include="TaskbarState.idl" />
|
||||
<Midl Include="IPaneContent.idl" />
|
||||
|
||||
@ -59,8 +59,8 @@ namespace winrt
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalPage::TerminalPage(TerminalApp::WindowProperties properties, const TerminalApp::ContentManager& manager) :
|
||||
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
|
||||
_mruTabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
|
||||
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
||||
_mruTabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
||||
_manager{ manager },
|
||||
_hostingHwnd{},
|
||||
_WindowProperties{ std::move(properties) }
|
||||
@ -84,9 +84,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#13211 - if we haven't yet set the owning hwnd, reparent all the controls now.
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
tabImpl->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
if (const auto& term{ pane->GetTerminalControl() })
|
||||
{
|
||||
term.OwningHwnd(reinterpret_cast<uint64_t>(hwnd));
|
||||
@ -566,9 +566,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#6586: now that we're done processing all startup commands,
|
||||
// focus the active control. This will work as expected for both
|
||||
// commandline invocations and for `wt` action invocations.
|
||||
if (const auto& terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto& tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto& content{ terminalTab->GetActiveContent() })
|
||||
if (const auto& content{ tabImpl->GetActiveContent() })
|
||||
{
|
||||
content.Focus(FocusState::Programmatic);
|
||||
}
|
||||
@ -1755,7 +1755,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// TitleChanged event.
|
||||
// Arguments:
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTitle(const TerminalTab& tab)
|
||||
void TerminalPage::_UpdateTitle(const Tab& tab)
|
||||
{
|
||||
auto newTabTitle = tab.Title();
|
||||
|
||||
@ -1833,13 +1833,13 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Connects event handlers to the TerminalTab for events that we want to
|
||||
// - Connects event handlers to the Tab for events that we want to
|
||||
// handle. This includes:
|
||||
// * the TitleChanged event, for changing the text of the tab
|
||||
// * the Color{Selected,Cleared} events to change the color of a tab.
|
||||
// Arguments:
|
||||
// - hostingTab: The Tab that's hosting this TermControl instance
|
||||
void TerminalPage::_RegisterTabEvents(TerminalTab& hostingTab)
|
||||
void TerminalPage::_RegisterTabEvents(Tab& hostingTab)
|
||||
{
|
||||
auto weakTab{ hostingTab.get_weak() };
|
||||
auto weakThis{ get_weak() };
|
||||
@ -1922,9 +1922,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// to the terminal when no other panes are present (GH#6219)
|
||||
bool TerminalPage::_MoveFocus(const FocusDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->NavigateFocus(direction);
|
||||
return tabImpl->NavigateFocus(direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1938,19 +1938,19 @@ namespace winrt::TerminalApp::implementation
|
||||
// - true if panes were swapped.
|
||||
bool TerminalPage::_SwapPane(const FocusDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
return terminalTab->SwapPane(direction);
|
||||
return tabImpl->SwapPane(direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TermControl TerminalPage::_GetActiveControl()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->GetActiveTerminalControl();
|
||||
return tabImpl->GetActiveTerminalControl();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -2057,7 +2057,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (auto tab : _tabs)
|
||||
{
|
||||
auto t = winrt::get_self<implementation::TabBase>(tab);
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto tabActions = t->BuildStartupActions(serializeBuffer ? BuildStartupKind::PersistAll : BuildStartupKind::PersistLayout);
|
||||
actions.insert(actions.end(), std::make_move_iterator(tabActions.begin()), std::make_move_iterator(tabActions.end()));
|
||||
}
|
||||
@ -2152,14 +2152,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// - rowsToScroll: a number of lines to move the viewport. If not provided we will use a system default.
|
||||
void TerminalPage::_Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
uint32_t realRowsToScroll;
|
||||
if (rowsToScroll == nullptr)
|
||||
{
|
||||
// The magic value of WHEEL_PAGESCROLL indicates that we need to scroll the entire page
|
||||
realRowsToScroll = _systemRowsToScroll == WHEEL_PAGESCROLL ?
|
||||
terminalTab->GetActiveTerminalControl().ViewHeight() :
|
||||
tabImpl->GetActiveTerminalControl().ViewHeight() :
|
||||
_systemRowsToScroll;
|
||||
}
|
||||
else
|
||||
@ -2168,7 +2168,7 @@ namespace winrt::TerminalApp::implementation
|
||||
realRowsToScroll = rowsToScroll.Value();
|
||||
}
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, realRowsToScroll);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2199,9 +2199,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// specified window instead of moving it in our tab row.
|
||||
if (!windowId.empty())
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto pane{ terminalTab->GetActivePane() })
|
||||
if (const auto pane{ tabImpl->GetActivePane() })
|
||||
{
|
||||
auto startupActions = pane->BuildStartupActions(0, 1, BuildStartupKind::MovePane);
|
||||
_DetachPaneFromWindow(pane);
|
||||
@ -2240,7 +2240,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab before its index changes.
|
||||
if (tabIdx < _tabs.Size())
|
||||
{
|
||||
auto targetTab = _GetTerminalTabImpl(_tabs.GetAt(tabIdx));
|
||||
auto targetTab = _GetTabImpl(_tabs.GetAt(tabIdx));
|
||||
// if the selected tab is not a host of terminals (e.g. settings)
|
||||
// don't attempt to add a pane to it.
|
||||
if (!targetTab)
|
||||
@ -2288,15 +2288,12 @@ namespace winrt::TerminalApp::implementation
|
||||
});
|
||||
}
|
||||
|
||||
void TerminalPage::_DetachTabFromWindow(const winrt::com_ptr<TabBase>& tab)
|
||||
void TerminalPage::_DetachTabFromWindow(const winrt::com_ptr<Tab>& tab)
|
||||
{
|
||||
if (const auto terminalTab = tab.try_as<TerminalTab>())
|
||||
// Detach the root pane, which will act like the whole tab got detached.
|
||||
if (const auto rootPane = tab->GetRootPane())
|
||||
{
|
||||
// Detach the root pane, which will act like the whole tab got detached.
|
||||
if (const auto rootPane = terminalTab->GetRootPane())
|
||||
{
|
||||
_DetachPaneFromWindow(rootPane);
|
||||
}
|
||||
_DetachPaneFromWindow(rootPane);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2324,7 +2321,7 @@ namespace winrt::TerminalApp::implementation
|
||||
RequestMoveContent.raise(*this, *request);
|
||||
}
|
||||
|
||||
bool TerminalPage::_MoveTab(winrt::com_ptr<TerminalTab> tab, MoveTabArgs args)
|
||||
bool TerminalPage::_MoveTab(winrt::com_ptr<Tab> tab, MoveTabArgs args)
|
||||
{
|
||||
if (!tab)
|
||||
{
|
||||
@ -2392,10 +2389,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// When the tab's active pane changes, we'll want to lookup a new icon
|
||||
// for it. The Title change will be propagated upwards through the tab's
|
||||
// PropertyChanged event handler.
|
||||
void TerminalPage::_activePaneChanged(winrt::TerminalApp::TerminalTab sender,
|
||||
void TerminalPage::_activePaneChanged(winrt::TerminalApp::Tab sender,
|
||||
Windows::Foundation::IInspectable /*args*/)
|
||||
{
|
||||
if (const auto tab{ _GetTerminalTabImpl(sender) })
|
||||
if (const auto tab{ _GetTabImpl(sender) })
|
||||
{
|
||||
// Possibly update the icon of the tab.
|
||||
_UpdateTabIcon(*tab);
|
||||
@ -2484,7 +2481,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - splitDirection: one value from the TerminalApp::SplitDirection enum, indicating how the
|
||||
// new pane should be split from its parent.
|
||||
// - splitSize: the size of the split
|
||||
void TerminalPage::_SplitPane(const winrt::com_ptr<TerminalTab>& tab,
|
||||
void TerminalPage::_SplitPane(const winrt::com_ptr<Tab>& tab,
|
||||
const SplitDirection splitDirection,
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> newPane)
|
||||
@ -2565,10 +2562,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_ToggleSplitOrientation()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
terminalTab->ToggleSplitOrientation();
|
||||
tabImpl->ToggleSplitOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2582,10 +2579,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_ResizePane(const ResizeDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
terminalTab->ResizePane(direction);
|
||||
tabImpl->ResizePane(direction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2597,23 +2594,23 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_ScrollPage(ScrollDirection scrollDirection)
|
||||
{
|
||||
// Do nothing if for some reason, there's no terminal tab in focus. We don't want to crash.
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto termHeight = control.ViewHeight();
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, termHeight);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_ScrollToBufferEdge(ScrollDirection scrollDirection)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, INT_MAX);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2725,9 +2722,9 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->CalcSnappedDimension(widthOrHeight, dimension);
|
||||
return tabImpl->CalcSnappedDimension(widthOrHeight, dimension);
|
||||
}
|
||||
}
|
||||
return dimension;
|
||||
@ -3343,7 +3340,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// connection, then we'll return nullptr. Otherwise, we'll return a new
|
||||
// Pane for this connection.
|
||||
std::shared_ptr<Pane> TerminalPage::_MakeTerminalPane(const NewTerminalArgs& newTerminalArgs,
|
||||
const winrt::TerminalApp::TabBase& sourceTab,
|
||||
const winrt::TerminalApp::Tab& sourceTab,
|
||||
TerminalConnection::ITerminalConnection existingConnection)
|
||||
{
|
||||
// First things first - Check for making a pane from content ID.
|
||||
@ -3361,15 +3358,15 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalSettingsCreateResult controlSettings{ nullptr };
|
||||
Profile profile{ nullptr };
|
||||
|
||||
if (const auto& terminalTab{ _GetTerminalTabImpl(sourceTab) })
|
||||
if (const auto& tabImpl{ _GetTabImpl(sourceTab) })
|
||||
{
|
||||
profile = terminalTab->GetFocusedProfile();
|
||||
profile = tabImpl->GetFocusedProfile();
|
||||
if (profile)
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = TerminalSettings::CreateWithProfile(_settings, profile, *_bindings);
|
||||
const auto workingDirectory = terminalTab->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
{
|
||||
@ -3433,7 +3430,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto debugContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, newControl) };
|
||||
auto debugPane = std::make_shared<Pane>(debugContent);
|
||||
|
||||
// Since we're doing this split directly on the pane (instead of going through TerminalTab,
|
||||
// Since we're doing this split directly on the pane (instead of going through Tab,
|
||||
// we need to handle the panes 'active' states
|
||||
|
||||
// Set the pane we're splitting to active (otherwise Split will not do anything)
|
||||
@ -3451,7 +3448,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// NOTE: callers of _MakePane should be able to accept nullptr as a return
|
||||
// value gracefully.
|
||||
std::shared_ptr<Pane> TerminalPage::_MakePane(const INewContentArgs& contentArgs,
|
||||
const winrt::TerminalApp::TabBase& sourceTab,
|
||||
const winrt::TerminalApp::Tab& sourceTab,
|
||||
TerminalConnection::ITerminalConnection existingConnection)
|
||||
|
||||
{
|
||||
@ -3485,9 +3482,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// Prevent the user from opening a bunch of snippets panes.
|
||||
//
|
||||
// Look at the focused tab, and if it already has one, then just focus it.
|
||||
if (const auto& focusedTab{ _GetFocusedTab() })
|
||||
if (const auto& focusedTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
const auto rootPane{ focusedTab.try_as<TerminalTab>()->GetRootPane() };
|
||||
const auto rootPane{ focusedTab->GetRootPane() };
|
||||
const bool found = rootPane == nullptr ? false : rootPane->WalkTree([](const auto& p) -> bool {
|
||||
if (const auto& snippets{ p->GetContent().try_as<SnippetsPaneContent>() })
|
||||
{
|
||||
@ -3643,21 +3640,21 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// Let the tab know that there are new settings. It's up to each content to decide what to do with them.
|
||||
terminalTab->UpdateSettings(_settings);
|
||||
tabImpl->UpdateSettings(_settings);
|
||||
|
||||
// Update the icon of the tab for the currently focused profile in that tab.
|
||||
// Only do this for TerminalTabs. Other types of tabs won't have multiple panes
|
||||
// and profiles so the Title and Icon will be set once and only once on init.
|
||||
_UpdateTabIcon(*terminalTab);
|
||||
_UpdateTabIcon(*tabImpl);
|
||||
|
||||
// Force the TerminalTab to re-grab its currently active control's title.
|
||||
terminalTab->UpdateTitle();
|
||||
tabImpl->UpdateTitle();
|
||||
}
|
||||
|
||||
auto tabImpl{ winrt::get_self<TabBase>(tab) };
|
||||
auto tabImpl{ winrt::get_self<Tab>(tab) };
|
||||
tabImpl->SetActionMap(_settings.ActionMap());
|
||||
}
|
||||
|
||||
@ -3776,7 +3773,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto tabImpl{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
auto tabState{ tabImpl->GetCombinedTaskbarState() };
|
||||
// lowest priority wins
|
||||
@ -3819,11 +3816,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_visible = showOrHide;
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// Manually enumerate the panes in each tab; this will let us recycle TerminalSettings
|
||||
// objects but only have to iterate one time.
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
tabImpl->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
if (auto control = pane->GetTerminalControl())
|
||||
{
|
||||
control.WindowVisibilityChanged(showOrHide);
|
||||
@ -3841,7 +3838,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: the tab where the search box should be created
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_Find(const TerminalTab& tab)
|
||||
void TerminalPage::_Find(const Tab& tab)
|
||||
{
|
||||
if (const auto& control{ tab.GetActiveTerminalControl() })
|
||||
{
|
||||
@ -3959,7 +3956,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_newTabButton.Background(backgroundBrush);
|
||||
_newTabButton.Foreground(foregroundBrush);
|
||||
|
||||
// This is just like what we do in TabBase::_RefreshVisualState. We need
|
||||
// This is just like what we do in Tab::_RefreshVisualState. We need
|
||||
// to manually toggle the visual state, so the setters in the visual
|
||||
// state group will re-apply, and set our currently selected colors in
|
||||
// the resources.
|
||||
@ -4210,25 +4207,18 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns a com_ptr to the implementation type of the given tab if it's a TerminalTab.
|
||||
// - Returns a com_ptr to the implementation type of the given tab if it's a Tab.
|
||||
// If the tab is not a TerminalTab, returns nullptr.
|
||||
// Arguments:
|
||||
// - tab: the projected type of a Tab
|
||||
// Return Value:
|
||||
// - If the tab is a TerminalTab, a com_ptr to the implementation type.
|
||||
// If the tab is not a TerminalTab, nullptr
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_GetTerminalTabImpl(const TerminalApp::TabBase& tab)
|
||||
winrt::com_ptr<Tab> TerminalPage::_GetTabImpl(const TerminalApp::Tab& tab)
|
||||
{
|
||||
if (auto terminalTab = tab.try_as<TerminalApp::TerminalTab>())
|
||||
{
|
||||
winrt::com_ptr<TerminalTab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TerminalTab>(terminalTab));
|
||||
return tabImpl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tab));
|
||||
return tabImpl;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@ -4715,10 +4705,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// The root pane will propagate the theme change to all its children.
|
||||
if (const auto& rootPane{ terminalTab->GetRootPane() })
|
||||
if (const auto& rootPane{ tabImpl->GetRootPane() })
|
||||
{
|
||||
rootPane->UpdateResources(_paneResources);
|
||||
}
|
||||
@ -4779,7 +4769,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Second: Update the colors of our individual TabViewItems. This
|
||||
// applies tab.background to the tabs via TerminalTab::ThemeColor.
|
||||
// applies tab.background to the tabs via Tab::ThemeColor.
|
||||
//
|
||||
// Do this second, so that we already know the bgColor of the titlebar.
|
||||
{
|
||||
@ -4787,8 +4777,8 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto tabUnfocusedBackground = theme.Tab() ? theme.Tab().UnfocusedBackground() : nullptr;
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
winrt::com_ptr<TabBase> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TabBase>(tab));
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tab));
|
||||
tabImpl->ThemeColor(tabBackground, tabUnfocusedBackground, bgColor);
|
||||
}
|
||||
}
|
||||
@ -5257,8 +5247,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// Get the tab impl from this event.
|
||||
const auto eventTab = e.Tab();
|
||||
const auto tabBase = _GetTabByTabViewItem(eventTab);
|
||||
winrt::com_ptr<TabBase> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TabBase>(tabBase));
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tabBase));
|
||||
if (tabImpl)
|
||||
{
|
||||
// First: stash the tab we started dragging.
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "TerminalPage.g.h"
|
||||
#include "TerminalTab.h"
|
||||
#include "Tab.h"
|
||||
#include "AppKeyBindings.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "RenameWindowRequestedArgs.g.h"
|
||||
@ -219,13 +219,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::TabBase> _tabs;
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::TabBase> _mruTabs;
|
||||
static winrt::com_ptr<TerminalTab> _GetTerminalTabImpl(const TerminalApp::TabBase& tab);
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _tabs;
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _mruTabs;
|
||||
static winrt::com_ptr<Tab> _GetTabImpl(const TerminalApp::Tab& tab);
|
||||
|
||||
void _UpdateTabIndices();
|
||||
|
||||
TerminalApp::TerminalTab _settingsTab{ nullptr };
|
||||
TerminalApp::Tab _settingsTab{ nullptr };
|
||||
|
||||
bool _isInFocusMode{ false };
|
||||
bool _isFullscreen{ false };
|
||||
@ -277,7 +277,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
struct StashedDragData
|
||||
{
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::TabBase> draggedTab{ nullptr };
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::Tab> draggedTab{ nullptr };
|
||||
winrt::Windows::Foundation::Point dragOffset{ 0, 0 };
|
||||
} _stashed;
|
||||
|
||||
@ -305,7 +305,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _OpenNewTabDropdown();
|
||||
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs);
|
||||
TerminalApp::TerminalTab _CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition = -1);
|
||||
TerminalApp::Tab _CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition = -1);
|
||||
|
||||
std::wstring _evaluatePathForCwd(std::wstring_view path);
|
||||
|
||||
@ -328,25 +328,25 @@ namespace winrt::TerminalApp::implementation
|
||||
void _HookupKeyBindings(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap) noexcept;
|
||||
void _RegisterActionCallbacks();
|
||||
|
||||
void _UpdateTitle(const TerminalTab& tab);
|
||||
void _UpdateTabIcon(TerminalTab& tab);
|
||||
void _UpdateTitle(const Tab& tab);
|
||||
void _UpdateTabIcon(Tab& tab);
|
||||
void _UpdateTabView();
|
||||
void _UpdateTabWidthMode();
|
||||
void _SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance);
|
||||
|
||||
void _DuplicateFocusedTab();
|
||||
void _DuplicateTab(const TerminalTab& tab);
|
||||
void _DuplicateTab(const Tab& tab);
|
||||
|
||||
safe_void_coroutine _ExportTab(const TerminalTab& tab, winrt::hstring filepath);
|
||||
safe_void_coroutine _ExportTab(const Tab& tab, winrt::hstring filepath);
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::TabBase tab);
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::Tab tab);
|
||||
void _CloseTabAtIndex(uint32_t index);
|
||||
void _RemoveTab(const winrt::TerminalApp::TabBase& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs);
|
||||
void _RemoveTab(const winrt::TerminalApp::Tab& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs);
|
||||
|
||||
void _InitializeTab(winrt::com_ptr<TerminalTab> newTabImpl, uint32_t insertPosition = -1);
|
||||
void _InitializeTab(winrt::com_ptr<Tab> newTabImpl, uint32_t insertPosition = -1);
|
||||
void _RegisterTerminalEvents(Microsoft::Terminal::Control::TermControl term);
|
||||
void _RegisterTabEvents(TerminalTab& hostingTab);
|
||||
void _RegisterTabEvents(Tab& hostingTab);
|
||||
|
||||
void _DismissTabContextMenus();
|
||||
void _FocusCurrentTab(const bool focusAlways);
|
||||
@ -357,7 +357,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _MoveFocus(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool _SwapPane(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool _MovePane(const Microsoft::Terminal::Settings::Model::MovePaneArgs args);
|
||||
bool _MoveTab(winrt::com_ptr<TerminalTab> tab, const Microsoft::Terminal::Settings::Model::MoveTabArgs args);
|
||||
bool _MoveTab(winrt::com_ptr<Tab> tab, const Microsoft::Terminal::Settings::Model::MoveTabArgs args);
|
||||
|
||||
template<typename F>
|
||||
bool _ApplyToActiveControls(F f)
|
||||
@ -381,21 +381,21 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _GetActiveControl();
|
||||
std::optional<uint32_t> _GetFocusedTabIndex() const noexcept;
|
||||
std::optional<uint32_t> _GetTabIndex(const TerminalApp::TabBase& tab) const noexcept;
|
||||
TerminalApp::TabBase _GetFocusedTab() const noexcept;
|
||||
winrt::com_ptr<TerminalTab> _GetFocusedTabImpl() const noexcept;
|
||||
TerminalApp::TabBase _GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept;
|
||||
std::optional<uint32_t> _GetTabIndex(const TerminalApp::Tab& tab) const noexcept;
|
||||
TerminalApp::Tab _GetFocusedTab() const noexcept;
|
||||
winrt::com_ptr<Tab> _GetFocusedTabImpl() const noexcept;
|
||||
TerminalApp::Tab _GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept;
|
||||
|
||||
void _HandleClosePaneRequested(std::shared_ptr<Pane> pane);
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::TabBase tab);
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::Tab tab);
|
||||
safe_void_coroutine _CloseFocusedPane();
|
||||
void _ClosePanes(weak_ref<TerminalTab> weakTab, std::vector<uint32_t> paneIds);
|
||||
void _ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> _PaneConfirmCloseReadOnly(std::shared_ptr<Pane> pane);
|
||||
void _AddPreviouslyClosedPaneOrTab(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>&& args);
|
||||
|
||||
void _Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll);
|
||||
|
||||
void _SplitPane(const winrt::com_ptr<TerminalTab>& tab,
|
||||
void _SplitPane(const winrt::com_ptr<Tab>& tab,
|
||||
const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> newPane);
|
||||
@ -439,14 +439,14 @@ namespace winrt::TerminalApp::implementation
|
||||
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);
|
||||
void _UpdatedSelectedTab(const winrt::TerminalApp::Tab& tab);
|
||||
void _UpdateBackground(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
|
||||
|
||||
void _OnDispatchCommandRequested(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::Command& command);
|
||||
void _OnCommandLineExecutionRequested(const IInspectable& sender, const winrt::hstring& commandLine);
|
||||
void _OnSwitchToTabRequested(const IInspectable& sender, const winrt::TerminalApp::TabBase& tab);
|
||||
void _OnSwitchToTabRequested(const IInspectable& sender, const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
void _Find(const TerminalTab& tab);
|
||||
void _Find(const Tab& tab);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _CreateNewControlAndContent(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
||||
@ -455,10 +455,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::IPaneContent _makeSettingsContent();
|
||||
std::shared_ptr<Pane> _MakeTerminalPane(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr,
|
||||
const winrt::TerminalApp::TabBase& sourceTab = nullptr,
|
||||
const winrt::TerminalApp::Tab& sourceTab = nullptr,
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
std::shared_ptr<Pane> _MakePane(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs = nullptr,
|
||||
const winrt::TerminalApp::TabBase& sourceTab = nullptr,
|
||||
const winrt::TerminalApp::Tab& sourceTab = nullptr,
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
|
||||
void _RefreshUIForSettingsReload();
|
||||
@ -475,7 +475,7 @@ namespace winrt::TerminalApp::implementation
|
||||
static int _ComputeScrollDelta(ScrollDirection scrollDirection, const uint32_t rowsToScroll);
|
||||
static uint32_t _ReadSystemRowsToScroll();
|
||||
|
||||
void _UpdateMRUTab(const winrt::TerminalApp::TabBase& tab);
|
||||
void _UpdateMRUTab(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
void _TryMoveTab(const uint32_t currentTabIndex, const int32_t suggestedNewTabIndex);
|
||||
|
||||
@ -534,7 +534,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _onTabDroppedOutside(winrt::Windows::Foundation::IInspectable sender, winrt::Microsoft::UI::Xaml::Controls::TabViewTabDroppedOutsideEventArgs e);
|
||||
|
||||
void _DetachPaneFromWindow(std::shared_ptr<Pane> pane);
|
||||
void _DetachTabFromWindow(const winrt::com_ptr<TabBase>& terminalTab);
|
||||
void _DetachTabFromWindow(const winrt::com_ptr<Tab>& tabImpl);
|
||||
void _MoveContent(std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>&& actions,
|
||||
const winrt::hstring& windowName,
|
||||
const uint32_t tabIndex,
|
||||
@ -546,9 +546,9 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
winrt::com_ptr<TerminalTab> _senderOrFocusedTab(const IInspectable& sender);
|
||||
winrt::com_ptr<Tab> _senderOrFocusedTab(const IInspectable& sender);
|
||||
|
||||
void _activePaneChanged(winrt::TerminalApp::TerminalTab tab, Windows::Foundation::IInspectable args);
|
||||
void _activePaneChanged(winrt::TerminalApp::Tab tab, Windows::Foundation::IInspectable args);
|
||||
safe_void_coroutine _doHandleSuggestions(Microsoft::Terminal::Settings::Model::SuggestionsArgs realArgs);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass TerminalTab : TabBase
|
||||
{
|
||||
TerminalTabStatus TabStatus { get; };
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,6 @@
|
||||
<ClInclude Include="../TitlebarControl.h" />
|
||||
<ClInclude Include="../TabRowControl.h" />
|
||||
<ClInclude Include="../App.h" />
|
||||
<ClInclude Include="../TerminalTab.h" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user