Skip to content

Commit 9e5fd96

Browse files
committed
Reduce the number of GUID round trips when looking up profiles.
This commit also moves to storing a reference to the active profile inside Pane and propagating it out of Pane through Tab. This lets us duplicate a pane even if its profile is missing, and gives us the freedom in the future to return a "base" profile (;)) Related to #5047.
1 parent 638c6d0 commit 9e5fd96

File tree

12 files changed

+94
-115
lines changed

12 files changed

+94
-115
lines changed

src/cascadia/TerminalApp/AppActionHandlers.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -753,11 +753,10 @@ namespace winrt::TerminalApp::implementation
753753
newTerminalArgs = NewTerminalArgs();
754754
}
755755

756-
const auto profileGuid{ _settings.GetProfileForArgs(newTerminalArgs) };
757-
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
756+
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
758757

759758
// Manually fill in the evaluated profile.
760-
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profileGuid));
759+
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
761760
_OpenNewWindow(false, newTerminalArgs);
762761
actionArgs.Handled(true);
763762
}

src/cascadia/TerminalApp/Pane.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Wi
3434
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr };
3535
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
3636

37-
Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) :
37+
Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
3838
_control{ control },
3939
_lastActive{ lastFocused },
4040
_profile{ profile }
@@ -758,11 +758,9 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio
758758
return;
759759
}
760760

761-
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
762-
auto paneProfile = settings.FindProfile(_profile.value());
763-
if (paneProfile)
761+
if (_profile)
764762
{
765-
auto mode = paneProfile.CloseOnExit();
763+
auto mode = _profile.CloseOnExit();
766764
if ((mode == CloseOnExitMode::Always) ||
767765
(mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
768766
{
@@ -786,27 +784,25 @@ void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspect
786784
{
787785
return;
788786
}
789-
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
790-
auto paneProfile = settings.FindProfile(_profile.value());
791-
if (paneProfile)
787+
if (_profile)
792788
{
793789
// We don't want to do anything if nothing is set, so check for that first
794-
if (static_cast<int>(paneProfile.BellStyle()) != 0)
790+
if (static_cast<int>(_profile.BellStyle()) != 0)
795791
{
796-
if (WI_IsFlagSet(paneProfile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
792+
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
797793
{
798794
// Audible is set, play the sound
799795
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
800796
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
801797
}
802798

803-
if (WI_IsFlagSet(paneProfile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
799+
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
804800
{
805801
_control.BellLightOn();
806802
}
807803

808804
// raise the event with the bool value corresponding to the taskbar flag
809-
_PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(paneProfile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
805+
_PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
810806
}
811807
}
812808
}
@@ -955,10 +951,10 @@ void Pane::SetActive()
955951
// Return Value:
956952
// - nullopt if no children of this pane were the last control to be
957953
// focused, else the GUID of the profile of the last control to be focused
958-
std::optional<GUID> Pane::GetFocusedProfile()
954+
Profile Pane::GetFocusedProfile()
959955
{
960956
auto lastFocused = GetActivePane();
961-
return lastFocused ? lastFocused->_profile : std::nullopt;
957+
return lastFocused ? lastFocused->_profile : nullptr;
962958
}
963959

964960
// Method Description:
@@ -1062,7 +1058,7 @@ void Pane::_FocusFirstChild()
10621058
// - profile: The GUID of the profile these settings should apply to.
10631059
// Return Value:
10641060
// - <none>
1065-
void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const GUID& profile)
1061+
void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const Profile& profile)
10661062
{
10671063
if (!_IsLeaf())
10681064
{
@@ -1071,8 +1067,13 @@ void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const GU
10711067
}
10721068
else
10731069
{
1074-
if (profile == _profile)
1070+
// Because this call may be coming in with a different settings tree,
1071+
// we want to map the incoming profile based on its GUID.
1072+
// Failure to find a matching profile will result in a pane holding
1073+
// a reference to a deleted profile (which is okay!).
1074+
if (profile.Guid() == _profile.Guid())
10751075
{
1076+
_profile = profile;
10761077
auto controlSettings = _control.Settings().as<TerminalSettings>();
10771078
// Update the parent of the control's settings object (and not the object itself) so
10781079
// that any overrides made by the control don't get affected by the reload
@@ -1885,7 +1886,7 @@ std::optional<bool> Pane::PreCalculateCanSplit(const std::shared_ptr<Pane> targe
18851886
// - The two newly created Panes
18861887
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::Split(SplitState splitType,
18871888
const float splitSize,
1888-
const GUID& profile,
1889+
const Profile& profile,
18891890
const TermControl& control)
18901891
{
18911892
if (!_IsLeaf())
@@ -2015,9 +2016,9 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
20152016
// Create two new Panes
20162017
// Move our control, guid into the first one.
20172018
// Move the new guid, control into the second.
2018-
_firstChild = std::make_shared<Pane>(_profile.value(), _control);
2019+
_firstChild = std::make_shared<Pane>(_profile, _control);
20192020
_firstChild->_connectionState = std::exchange(_connectionState, ConnectionState::NotConnected);
2020-
_profile = std::nullopt;
2021+
_profile = nullptr;
20212022
_control = { nullptr };
20222023
_secondChild = newPane;
20232024

src/cascadia/TerminalApp/Pane.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ DEFINE_ENUM_FLAG_OPERATORS(Borders);
4747
class Pane : public std::enable_shared_from_this<Pane>
4848
{
4949
public:
50-
Pane(const GUID& profile,
50+
Pane(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
5151
const winrt::Microsoft::Terminal::Control::TermControl& control,
5252
const bool lastFocused = false);
5353

5454
std::shared_ptr<Pane> GetActivePane();
5555
winrt::Microsoft::Terminal::Control::TermControl GetTerminalControl();
56-
std::optional<GUID> GetFocusedProfile();
56+
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile();
5757

5858
winrt::Windows::UI::Xaml::Controls::Grid GetRootElement();
5959

@@ -63,7 +63,7 @@ class Pane : public std::enable_shared_from_this<Pane>
6363
void SetActive();
6464

6565
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
66-
const GUID& profile);
66+
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
6767
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
6868
void Relayout();
6969
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
@@ -75,7 +75,7 @@ class Pane : public std::enable_shared_from_this<Pane>
7575

7676
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
7777
const float splitSize,
78-
const GUID& profile,
78+
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
7979
const winrt::Microsoft::Terminal::Control::TermControl& control);
8080
bool ToggleSplitOrientation();
8181
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
@@ -160,7 +160,7 @@ class Pane : public std::enable_shared_from_this<Pane>
160160
std::optional<uint32_t> _id;
161161

162162
bool _lastActive{ false };
163-
std::optional<GUID> _profile{ std::nullopt };
163+
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
164164
winrt::event_token _connectionStateChangedToken{ 0 };
165165
winrt::event_token _firstClosedToken{ 0 };
166166
winrt::event_token _secondClosedToken{ 0 };

src/cascadia/TerminalApp/TabManagement.cpp

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,18 @@ namespace winrt::TerminalApp::implementation
5959
HRESULT TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection)
6060
try
6161
{
62-
const auto profileGuid{ _settings.GetProfileForArgs(newTerminalArgs) };
62+
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
6363
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
6464

65-
_CreateNewTabFromSettings(profileGuid, settings, existingConnection);
65+
_CreateNewTabWithProfileAndSettings(profile, settings, existingConnection);
6666

6767
const uint32_t tabCount = _tabs.Size();
6868
const bool usedManualProfile = (newTerminalArgs != nullptr) &&
6969
(newTerminalArgs.ProfileIndex() != nullptr ||
7070
newTerminalArgs.Profile().empty());
7171

7272
// Lookup the name of the color scheme used by this profile.
73-
const auto scheme = _settings.GetColorSchemeForProfile(profileGuid);
73+
const auto scheme = _settings.GetColorSchemeForProfile(profile);
7474
// If they explicitly specified `null` as the scheme (indicating _no_ scheme), log
7575
// that as the empty string.
7676
const auto schemeName = scheme ? scheme.Name() : L"\0";
@@ -82,7 +82,7 @@ namespace winrt::TerminalApp::implementation
8282
TraceLoggingUInt32(1u, "EventVer", "Version of this event"),
8383
TraceLoggingUInt32(tabCount, "TabCount", "Count of tabs currently opened in TerminalApp"),
8484
TraceLoggingBool(usedManualProfile, "ProfileSpecified", "Whether the new tab specified a profile explicitly"),
85-
TraceLoggingGuid(profileGuid, "ProfileGuid", "The GUID of the profile spawned in the new tab"),
85+
TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The GUID of the profile spawned in the new tab"),
8686
TraceLoggingBool(settings.DefaultSettings().UseAcrylic(), "UseAcrylic", "The acrylic preference from the settings"),
8787
TraceLoggingFloat64(settings.DefaultSettings().TintOpacity(), "TintOpacity", "Opacity preference from the settings"),
8888
TraceLoggingWideString(settings.DefaultSettings().FontFace().c_str(), "FontFace", "Font face chosen in the settings"),
@@ -175,10 +175,9 @@ namespace winrt::TerminalApp::implementation
175175
_tabView.TabItems().Append(tabViewItem);
176176

177177
// Set this tab's icon to the icon from the user's profile
178-
if (const auto profileGuid = newTabImpl->GetFocusedProfile())
178+
if (const auto profile{ newTabImpl->GetFocusedProfile() })
179179
{
180-
const auto profile = _settings.FindProfile(profileGuid.value());
181-
if (profile != nullptr && !profile.Icon().empty())
180+
if (!profile.Icon().empty())
182181
{
183182
newTabImpl->UpdateIcon(profile.Icon());
184183
}
@@ -233,14 +232,14 @@ namespace winrt::TerminalApp::implementation
233232
// - Creates a new tab with the given settings. If the tab bar is not being
234233
// currently displayed, it will be shown.
235234
// Arguments:
236-
// - profileGuid: ID to use to lookup profile settings for this connection
235+
// - profile: profile settings for this connection
237236
// - settings: the TerminalSettings object to use to create the TerminalControl with.
238237
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
239-
void TerminalPage::_CreateNewTabFromSettings(GUID profileGuid, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
238+
void TerminalPage::_CreateNewTabWithProfileAndSettings(const Profile& profile, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
240239
{
241240
// Initialize the new tab
242241
// Create a connection based on the values in our settings object if we weren't given one.
243-
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profileGuid, settings.DefaultSettings());
242+
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, settings.DefaultSettings());
244243

245244
// If we had an `existingConnection`, then this is an inbound handoff from somewhere else.
246245
// We need to tell it about our size information so it can match the dimensions of what
@@ -268,7 +267,7 @@ namespace winrt::TerminalApp::implementation
268267
// This way, when we do a settings reload we just update the parent and the overrides remain
269268
auto term = _InitControl(settings, connection);
270269

271-
auto newTabImpl = winrt::make_self<TerminalTab>(profileGuid, term);
270+
auto newTabImpl = winrt::make_self<TerminalTab>(profile, term);
272271
_RegisterTerminalEvents(term);
273272
_InitializeTab(newTabImpl);
274273

@@ -277,7 +276,7 @@ namespace winrt::TerminalApp::implementation
277276
auto newControl = _InitControl(settings, debugConnection);
278277
_RegisterTerminalEvents(newControl);
279278
// Split (auto) with the debug tap.
280-
newTabImpl->SplitPane(SplitState::Automatic, 0.5f, profileGuid, newControl);
279+
newTabImpl->SplitPane(SplitState::Automatic, 0.5f, profile, newControl);
281280
}
282281
}
283282

@@ -288,19 +287,9 @@ namespace winrt::TerminalApp::implementation
288287
// - tab: the Tab to update the title for.
289288
void TerminalPage::_UpdateTabIcon(TerminalTab& tab)
290289
{
291-
const auto lastFocusedProfileOpt = tab.GetFocusedProfile();
292-
if (lastFocusedProfileOpt.has_value())
290+
if (const auto profile = tab.GetFocusedProfile())
293291
{
294-
const auto lastFocusedProfile = lastFocusedProfileOpt.value();
295-
const auto matchingProfile = _settings.FindProfile(lastFocusedProfile);
296-
if (matchingProfile)
297-
{
298-
tab.UpdateIcon(matchingProfile.Icon());
299-
}
300-
else
301-
{
302-
tab.UpdateIcon({});
303-
}
292+
tab.UpdateIcon(profile.Icon());
304293
}
305294
}
306295

@@ -354,31 +343,24 @@ namespace winrt::TerminalApp::implementation
354343
{
355344
try
356345
{
357-
// TODO: GH#5047 - In the future, we should get the Profile of
358-
// the focused pane, and use that to build a new instance of the
359-
// settings so we can duplicate this tab/pane.
360-
//
361-
// Currently, if the profile doesn't exist anymore in our
362-
// settings, we'll silently do nothing.
346+
// TODO: GH#5047 - We're duplicating the whole profile, which might
347+
// be a dangling reference to old settings.
363348
//
364-
// In the future, it will be preferable to just duplicate the
365-
// current control's settings, but we can't do that currently,
366-
// because we won't be able to create a new instance of the
367-
// connection without keeping an instance of the original Profile
368-
// object around.
369-
370-
const auto& profileGuid = tab.GetFocusedProfile();
371-
if (profileGuid.has_value())
349+
// In the future, it may be preferable to just duplicate the
350+
// current control's live settings (which will include changes
351+
// made through VT).
352+
353+
if (const auto profile = tab.GetFocusedProfile())
372354
{
373-
const auto settingsCreateResult{ TerminalSettings::CreateWithProfileByID(_settings, profileGuid.value(), *_bindings) };
355+
const auto settingsCreateResult{ TerminalSettings::CreateWithProfile(_settings, profile, *_bindings) };
374356
const auto workingDirectory = tab.GetActiveTerminalControl().WorkingDirectory();
375357
const auto validWorkingDirectory = !workingDirectory.empty();
376358
if (validWorkingDirectory)
377359
{
378360
settingsCreateResult.DefaultSettings().StartingDirectory(workingDirectory);
379361
}
380362

381-
_CreateNewTabFromSettings(profileGuid.value(), settingsCreateResult);
363+
_CreateNewTabWithProfileAndSettings(profile, settingsCreateResult);
382364

383365
const auto runtimeTabText{ tab.GetTabText() };
384366
if (!runtimeTabText.empty())

0 commit comments

Comments
 (0)