Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 104 additions & 5 deletions src/cascadia/TerminalApp/Pane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ Pane::Pane(IPaneContent content, const bool lastFocused) :
_lastActive{ lastFocused }
{
_setPaneContent(std::move(content));
_root.Children().Append(_borderFirst);
_CreatePaneHeader();

const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);

// Set up leaf layout: header in _root row 0, content in _borderFirst row 1.
// The TermControl stays as the direct child of _borderFirst (no Grid wrapper)
// so the SwapChainPanel renders correctly.
_SetupLeafLayout(control);

// Register an event with the control to have it inform us when it gains focus.
if (control)
Expand Down Expand Up @@ -1228,6 +1232,12 @@ void Pane::UpdateVisuals()
const auto& brush{ _ComputeBorderColor() };
_borderFirst.BorderBrush(brush);
_borderSecond.BorderBrush(brush);

// Update pane header color to match focus state
if (_paneHeaderBorder && _paneHeaderBorder.Visibility() == winrt::Windows::UI::Xaml::Visibility::Visible)
{
_paneHeaderBorder.Background(brush);
}
}

// Method Description:
Expand Down Expand Up @@ -1450,9 +1460,9 @@ void Pane::_CloseChild(const bool closeFirst)
_root.RowDefinitions().Clear();

// Reattach the TermControl to our grid.
_root.Children().Append(_borderFirst);
_CreatePaneHeader();
const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);
_SetupLeafLayout(control);

// Make sure to set our _splitState before focusing the control. If you
// fail to do this, when the tab handles the GotFocus event and asks us
Expand Down Expand Up @@ -1755,7 +1765,92 @@ void Pane::_setPaneContent(IPaneContent content)
}

// Method Description:
// - Sets up row/column definitions for this pane. There are three total
// - Creates the pane header UI elements (title bar shown above the content).
// The header is initially collapsed and only shown via ShowPaneHeaders().
void Pane::_CreatePaneHeader()
{
namespace WUX = winrt::Windows::UI::Xaml;

_paneHeaderText = Controls::TextBlock{};
_paneHeaderText.FontSize(12);
_paneHeaderText.Padding({ 8, 2, 8, 2 });
_paneHeaderText.IsTextSelectionEnabled(false);
_paneHeaderText.TextTrimming(WUX::TextTrimming::CharacterEllipsis);
if (_content)
{
_paneHeaderText.Text(_content.Title());
_titleChangedRevoker = _content.TitleChanged(winrt::auto_revoke, [this](auto&&, auto&&) {
_paneHeaderBorder.Dispatcher().RunAsync(
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
[this]() {
if (_content && _paneHeaderText)
{
_paneHeaderText.Text(_content.Title());
}
});
});
}

_paneHeaderBorder = Controls::Border{};
_paneHeaderBorder.Padding({ 0, 0, 0, 0 });
_paneHeaderBorder.Child(_paneHeaderText);
_paneHeaderBorder.Visibility(WUX::Visibility::Collapsed);
}

// Method Description:
// - Sets up the leaf pane layout in _root: a header row (auto-sized) and a
// content row (star-sized). The TermControl stays as the direct child of
// _borderFirst so the SwapChainPanel renders correctly.
void Pane::_SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control)
{
auto headerRow = Controls::RowDefinition{};
headerRow.Height(GridLengthHelper::Auto());
auto contentRow = Controls::RowDefinition{};
contentRow.Height(GridLengthHelper::FromValueAndType(1, GridUnitType::Star));
_root.RowDefinitions().Append(headerRow);
_root.RowDefinitions().Append(contentRow);

Controls::Grid::SetRow(_paneHeaderBorder, 0);
Controls::Grid::SetRow(_borderFirst, 1);

_root.Children().Append(_paneHeaderBorder);
_root.Children().Append(_borderFirst);

if (control)
{
_borderFirst.Child(control);
}
}

// Method Description:
// - Show or hide the pane header title bar on all leaf panes in the tree.
// Called by Tab when the number of panes changes.
void Pane::ShowPaneHeaders(bool show)
{
if (_IsLeaf())
{
if (_paneHeaderBorder)
{
namespace WUX = winrt::Windows::UI::Xaml;
_paneHeaderBorder.Visibility(show ? WUX::Visibility::Visible : WUX::Visibility::Collapsed);

if (show)
{
const auto& brush = _ComputeBorderColor();
_paneHeaderBorder.Background(brush);
_paneHeaderText.Foreground(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::White()));
}
}
}
else
{
_firstChild->ShowPaneHeaders(show);
_secondChild->ShowPaneHeaders(show);
}
}

// Method Description:
// - Sets up row/column definitions for this pane.There are three total
// row/cols. The middle one is for the separator. The first and third are for
// each of the child panes, and are given a size in pixels, based off the
// available space, and the percent of the space they respectively consume,
Expand Down Expand Up @@ -2321,6 +2416,10 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
_root.RowDefinitions().Clear();
_CreateRowColDefinitions();

// Reset Grid.Row on _borderFirst — it may have been set to row 1 in the
// leaf layout (header=row0, content=row1).
Controls::Grid::SetRow(_borderFirst, 0);

_borderFirst.Child(_firstChild->GetRootElement());
_borderSecond.Child(_secondChild->GetRootElement());

Expand Down
8 changes: 8 additions & 0 deletions src/cascadia/TerminalApp/Pane.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class Pane : public std::enable_shared_from_this<Pane>
bool ContainsReadOnly() const;

void EnableBroadcast(bool enabled);
void ShowPaneHeaders(bool show);
void BroadcastKey(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
void BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
void BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const winrt::hstring& text);
Expand Down Expand Up @@ -235,6 +236,11 @@ class Pane : public std::enable_shared_from_this<Pane>
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};

// Per-pane title header (visible when there are split panes)
winrt::Windows::UI::Xaml::Controls::Border _paneHeaderBorder{ nullptr };
winrt::Windows::UI::Xaml::Controls::TextBlock _paneHeaderText{ nullptr };
winrt::TerminalApp::IPaneContent::TitleChanged_revoker _titleChangedRevoker;

PaneResources _themeResources;

#pragma region Properties that need to be transferred between child / parent panes upon splitting / closing
Expand Down Expand Up @@ -266,6 +272,8 @@ class Pane : public std::enable_shared_from_this<Pane>
void _SetupChildCloseHandlers();
winrt::TerminalApp::IPaneContent _takePaneContent();
void _setPaneContent(winrt::TerminalApp::IPaneContent content);
void _CreatePaneHeader();
void _SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control);
bool _HasChild(const std::shared_ptr<Pane> child);
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const;

Expand Down
13 changes: 13 additions & 0 deletions src/cascadia/TerminalApp/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ namespace winrt::TerminalApp::implementation
// The tabWidthMode may have changed, update the header control accordingly
_UpdateHeaderControlMaxWidth();

// Refresh pane header visibility based on the current setting
const auto showHeaders = settings.GlobalSettings().ShowPaneHeaders() && _rootPane->GetLeafPaneCount() > 1;
_rootPane->ShowPaneHeaders(showHeaders);

// Update the settings on all our panes.
_rootPane->WalkTree([&](const auto& pane) {
pane->UpdateSettings(settings);
Expand Down Expand Up @@ -646,6 +650,14 @@ namespace winrt::TerminalApp::implementation
// After split, Close Pane Menu Item should be visible
_closePaneMenuItem.Visibility(WUX::Visibility::Visible);

// Show pane headers now that we have multiple panes (if the setting is enabled)
try
{
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
_rootPane->ShowPaneHeaders(settings.GlobalSettings().ShowPaneHeaders());
}
CATCH_LOG();

// The active pane has an id if it is a leaf
if (activePaneId)
{
Expand Down Expand Up @@ -1324,6 +1336,7 @@ namespace winrt::TerminalApp::implementation
if (_rootPane->GetLeafPaneCount() == 1)
{
_closePaneMenuItem.Visibility(WUX::Visibility::Collapsed);
_rootPane->ShowPaneHeaders(false);
}

_RecalculateAndApplyReadOnly();
Expand Down
7 changes: 7 additions & 0 deletions src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

<!-- Show pane headers -->
<local:SettingContainer x:Name="ShowPaneHeaders"
x:Uid="Globals_ShowPaneHeaders">
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowPaneHeaders, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

<!-- Show Acrylic in Tab Row -->
<local:SettingContainer x:Name="AcrylicTabRow"
x:Uid="Globals_AcrylicTabRow">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowTabs);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsFullscreen);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowPaneHeaders);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsInTitlebar);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, UseAcrylicInTabRow);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTitleInTitlebar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace Microsoft.Terminal.Settings.Editor

PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, AlwaysShowTabs);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsFullscreen);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowPaneHeaders);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsInTitlebar);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, UseAcrylicInTabRow);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTitleInTitlebar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2593,6 +2593,14 @@
<value>When enabled, the tab bar will be visible when the app is full screen.</value>
<comment>A description for what the "show tabs in full screen" setting does.</comment>
</data>
<data name="Globals_ShowPaneHeaders.Header" xml:space="preserve">
<value>Show pane title headers</value>
<comment>Header for a control to toggle if the app should show title headers above each pane when multiple panes are open.</comment>
</data>
<data name="Globals_ShowPaneHeaders.HelpText" xml:space="preserve">
<value>When enabled, a title header is shown above each pane when multiple panes are open.</value>
<comment>A description for what the "show pane headers" setting does. Presented near "Globals_ShowPaneHeaders.Header".</comment>
</data>
<data name="Profile_PathTranslationStyle.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Path translation</value>
<comment>Name for a control to select how file and directory paths are translated.</comment>
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_SETTING(Int32, InitialCols);
INHERITABLE_SETTING(Boolean, AlwaysShowTabs);
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
INHERITABLE_SETTING(Boolean, ShowPaneHeaders);
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ Author(s):
X(winrt::Windows::Foundation::Collections::IVector<Model::NewTabMenuEntry>, NewTabMenu, "newTabMenu", winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} })) \
X(bool, AllowHeadless, "compatibility.allowHeadless", false) \
X(hstring, SearchWebDefaultQueryUrl, "searchWebDefaultQueryUrl", L"https://www.bing.com/search?q=%22%s%22") \
X(bool, ShowTabsFullscreen, "showTabsFullscreen", false)
X(bool, ShowTabsFullscreen, "showTabsFullscreen", false) \
X(bool, ShowPaneHeaders, "showPaneHeaders", true)

// Also add these settings to:
// * Profile.idl
Expand Down
Loading