Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for new panes with specifc profiles and other settings overrides #3825

Merged
33 commits merged into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6752b1a
Basic POC - you can add profile, commandline, startingDirectory to ov…
zadjii-msft Nov 26, 2019
9474240
Add a 'splitPane' keybinding that can be used for splitting a pane ei…
zadjii-msft Nov 26, 2019
fb93105
Update documentation too
zadjii-msft Nov 27, 2019
451aaab
Good lord this is important
zadjii-msft Nov 27, 2019
31a9046
Add a test too, though I have no idea if it works
zadjii-msft Nov 27, 2019
b5a264b
"style" -> "split"
zadjii-msft Nov 27, 2019
e0cd014
pr comments from carlos
zadjii-msft Nov 27, 2019
de60a30
Merge remote-tracking branch 'origin/master' into dev/migrie/f/splitP…
zadjii-msft Nov 27, 2019
9f93a53
Merge remote-tracking branch 'origin/master' into dev/migrie/f/new-te…
zadjii-msft Nov 27, 2019
9eac8a6
Merge branch 'dev/migrie/f/splitPane-action' into dev/migrie/f/new-te…
zadjii-msft Nov 27, 2019
2c1742d
This almost works
zadjii-msft Nov 27, 2019
49a546e
clean up some chaotically bad code writing
zadjii-msft Nov 28, 2019
4c0b071
Merge remote-tracking branch 'origin/master' into dev/migrie/f/new-te…
zadjii-msft Dec 2, 2019
22f76e4
Add title to the terminal args too
zadjii-msft Dec 2, 2019
65f10e9
Try adding a test - remember that everything is a horrifying nightmare
zadjii-msft Dec 2, 2019
b392ba0
I this restores the functionality of the local winrt objects, not XAML
zadjii-msft Dec 2, 2019
3be37fd
I this restores the functionality of the local winrt objects, not XAML
zadjii-msft Dec 2, 2019
8a0bb8d
Fix the unit tests, add comments
zadjii-msft Dec 2, 2019
1760de2
That's what I get for not building before pushing
zadjii-msft Dec 3, 2019
7d05f34
Merge branch 'dev/migrie/3536-fix-localtests' into dev/migrie/f/new-t…
zadjii-msft Dec 3, 2019
93db1ed
write a big honkin test
zadjii-msft Dec 3, 2019
2073869
Comments are important
zadjii-msft Dec 3, 2019
9226042
update the schema too
zadjii-msft Dec 3, 2019
919f626
Merge remote-tracking branch 'origin/master' into dev/migrie/f/new-te…
zadjii-msft Dec 3, 2019
f2ad5fc
Merge remote-tracking branch 'origin/master' into dev/migrie/f/new-te…
zadjii-msft Dec 4, 2019
9fe4a71
remove this optional<int> param, it makes me sad
zadjii-msft Dec 4, 2019
b019f24
fixes from PR comments
zadjii-msft Dec 5, 2019
484e444
Suggestions from Dustin's review
zadjii-msft Dec 5, 2019
6e02caa
Merge branch 'master' into dev/migrie/f/new-terminal-args
zadjii-msft Dec 6, 2019
73715e6
update the schema too
zadjii-msft Dec 6, 2019
fcdd2cf
Some nits from Dustin
zadjii-msft Dec 6, 2019
4a99051
Merge remote-tracking branch 'origin/master' into dev/migrie/f/new-te…
zadjii-msft Dec 6, 2019
b8eecb6
Don't take a trip to beeftown on negative parameters
zadjii-msft Dec 6, 2019
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
10 changes: 5 additions & 5 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
"profile": {
"description": "Either the GUID or name of a profile to use, instead of launching the default",
"type": "string"
},
"index": {
"type": "integer",
"description": "The index of the profile in the new tab dropdown to open"
}
},
"type": "object"
Expand Down Expand Up @@ -143,11 +147,7 @@
{ "$ref": "#/definitions/NewTerminalArgs" },
{
"properties": {
"action": { "type":"string", "pattern": "newTab" },
"index": {
"type": "integer",
"description": "The index in the new tab dropdown to open in a new tab"
}
"action": { "type":"string", "pattern": "newTab" }
}
}
]
Expand Down
23 changes: 14 additions & 9 deletions src/cascadia/LocalTests_TerminalApp/KeyBindingsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_NULL(realArgs.ProfileIndex());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_NULL(realArgs.TerminalArgs().ProfileIndex());
}
{
Log::Comment(NoThrowString().Format(
Expand All @@ -256,8 +257,9 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_NOT_NULL(realArgs.ProfileIndex());
VERIFY_ARE_EQUAL(0, realArgs.ProfileIndex().Value());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().ProfileIndex());
VERIFY_ARE_EQUAL(0, realArgs.TerminalArgs().ProfileIndex().Value());
}
{
Log::Comment(NoThrowString().Format(
Expand All @@ -268,8 +270,9 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_NOT_NULL(realArgs.ProfileIndex());
VERIFY_ARE_EQUAL(0, realArgs.ProfileIndex().Value());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().ProfileIndex());
VERIFY_ARE_EQUAL(0, realArgs.TerminalArgs().ProfileIndex().Value());
}
{
Log::Comment(NoThrowString().Format(
Expand All @@ -281,8 +284,9 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_NOT_NULL(realArgs.ProfileIndex());
VERIFY_ARE_EQUAL(11, realArgs.ProfileIndex().Value());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().ProfileIndex());
VERIFY_ARE_EQUAL(11, realArgs.TerminalArgs().ProfileIndex().Value());
}
{
Log::Comment(NoThrowString().Format(
Expand All @@ -293,8 +297,9 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_NOT_NULL(realArgs.ProfileIndex());
VERIFY_ARE_EQUAL(8, realArgs.ProfileIndex().Value());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().ProfileIndex());
VERIFY_ARE_EQUAL(8, realArgs.TerminalArgs().ProfileIndex().Value());
}

{
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace winrt::TerminalApp::implementation
{
args->_TabTitle = winrt::to_hstring(tabTitle.asString());
}
if (auto index{ json[JsonKey(TabTitleKey)] })
if (auto index{ json[JsonKey(ProfileIndexKey)] })
{
args->_ProfileIndex = index.asInt();
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ namespace winrt::TerminalApp::implementation
}

// Use the default profile to determine how big of a window we need.
TerminalSettings settings = _settings->MakeSettings(std::nullopt);
const auto [_, settings] = _settings->BuildSettings(nullptr);

// TODO MSFT:21150597 - If the global setting "Always show tab bar" is
// set or if "Show tabs in title bar" is set, then we'll need to add
Expand Down
98 changes: 47 additions & 51 deletions src/cascadia/TerminalApp/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,35 +115,6 @@ const Profile* CascadiaSettings::FindProfile(GUID profileGuid) const noexcept
return nullptr;
}

// Method Description:
// - Create a TerminalSettings object from the given profile.
// If the profileGuidArg is not provided, this method will use the default
// profile.
// The TerminalSettings object that is created can be used to initialize both
// the Control's settings, and the Core settings of the terminal.
// Arguments:
// - profileGuidArg: an optional GUID to use to lookup the profile to create the
// settings from. If this arg is not provided, or the GUID does not match a
// profile, then this method will use the default profile.
// Return Value:
// - <none>
TerminalSettings CascadiaSettings::MakeSettings(std::optional<GUID> profileGuidArg) const
{
GUID profileGuid = profileGuidArg ? profileGuidArg.value() : _globals.GetDefaultProfile();
const Profile* const profile = FindProfile(profileGuid);
if (profile == nullptr)
{
throw E_INVALIDARG;
}

TerminalSettings result = profile->CreateTerminalSettings(_globals.GetColorSchemes());

// Place our appropriate global settings into the Terminal Settings
_globals.ApplyToSettings(result);

return result;
}

// Method Description:
// - Returns an iterable collection of all of our Profiles.
// Arguments:
Expand Down Expand Up @@ -454,15 +425,12 @@ void CascadiaSettings::_ValidateAllSchemesExist()
}

// Method Description:
// - Create a TerminalSettings object for the provided combination of
// profileIndex and newTerminalArgs. We'll use the index and newTerminalArgs
// to look up the profile that should be used to create these
// TerminalSettings. Then, we'll apply settings contained in the
// - Create a TerminalSettings object for the provided newTerminalArgs. We'll
// use the newTerminalArgs to look up the profile that should be used to
// create these TerminalSettings. Then, we'll apply settings contained in the
// newTerminalArgs to the profile's settings, to enable customization on top
// of the profile's default values.
// Arguments:
// - index: if provided, the index in the list of profiles to get the GUID for.
// If omitted, instead use the default profile's GUID
// - newTerminalArgs: An object that may contain a profile name or GUID to
// actually use. If the Profile value is not a guid, we'll treat it as a name,
// and attempt to look the profile up by name instead.
Expand All @@ -474,7 +442,7 @@ void CascadiaSettings::_ValidateAllSchemesExist()
std::tuple<GUID, TerminalSettings> CascadiaSettings::BuildSettings(const NewTerminalArgs& newTerminalArgs) const
{
const GUID profileGuid = _GetProfileForArgs(newTerminalArgs);
auto settings = MakeSettings(profileGuid);
auto settings = BuildSettings(profileGuid);

if (newTerminalArgs)
{
Expand All @@ -496,6 +464,30 @@ std::tuple<GUID, TerminalSettings> CascadiaSettings::BuildSettings(const NewTerm
return { profileGuid, settings };
}

// Method Description:
// - Create a TerminalSettings object for the profile with a GUID matching the
// provided GUID. If no profile matches this GUID, then this method will
// throw.
// Arguments:
// - profileGuid: The GUID of a profile to use to create a settings object for.
// Return Value:
// - the GUID of the created profile, and a fully initialized TerminalSettings object
TerminalSettings CascadiaSettings::BuildSettings(GUID profileGuid) const
{
const Profile* const profile = FindProfile(profileGuid);
if (profile == nullptr)
{
throw E_INVALIDARG;
}
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

TerminalSettings result = profile->CreateTerminalSettings(_globals.GetColorSchemes());

// Place our appropriate global settings into the Terminal Settings
_globals.ApplyToSettings(result);

return result;
}

// Method Description:
// - Helper to get the GUID of a profile, given an optional index and a possible
// "profile" value to override that.
Expand Down Expand Up @@ -532,33 +524,37 @@ GUID CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs
{
bool wasGuid = false;

try
// Do a quick heuristic check - is the profile 38 chars long (the
// length of a GUID string), and does it start with '{'? Because if
// it doesn't, it's _definitely_ not a GUID.
if (newTerminalArgs.Profile().size() == 38 && newTerminalArgs.Profile()[0] == L'{')
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
const auto newGUID = Utils::GuidFromString(newTerminalArgs.Profile().c_str());

for (const auto& p : _profiles)
try
{
if (p.GetGuid() == newGUID)
const auto newGUID = Utils::GuidFromString(newTerminalArgs.Profile().c_str());

for (const auto& p : _profiles)
{
profileGuid = newGUID;
wasGuid = true;
break;
if (p.GetGuid() == newGUID)
{
profileGuid = newGUID;
wasGuid = true;
break;
}
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}
}
CATCH_LOG();
}
CATCH_LOG();

// Here, we were unable to use the profile string as a GUID to
// lookup a profile. Instead, try using the string to look the
// Profile up by name.
if (!wasGuid)
{
for (const auto& p : _profiles)
const auto guidFromName = FindGuid(newTerminalArgs.Profile().c_str());
if (guidFromName.has_value())
{
if (p.GetName() == newTerminalArgs.Profile())
{
profileGuid = p.GetGuid();
}
profileGuid = guidFromName.value();
}
}
}
Expand All @@ -584,7 +580,7 @@ GUID CascadiaSettings::_GetProfileForIndex(std::optional<int> index) const
{
const auto realIndex = index.value();
// If we don't have that many profiles, then do nothing.
if (realIndex >= gsl::narrow<decltype(realIndex)>(_profiles.size()))
if (realIndex >= gsl::narrow_cast<decltype(realIndex)>(_profiles.size()))
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
return _globals.GetDefaultProfile();
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/CascadiaSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class TerminalApp::CascadiaSettings final

static const CascadiaSettings& GetCurrentAppSettings();

winrt::Microsoft::Terminal::Settings::TerminalSettings MakeSettings(std::optional<GUID> profileGuid) const;
std::tuple<GUID, winrt::Microsoft::Terminal::Settings::TerminalSettings> BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const;
winrt::Microsoft::Terminal::Settings::TerminalSettings BuildSettings(GUID profileGuid) const;

GlobalAppSettings& GlobalSettings();

Expand Down
35 changes: 23 additions & 12 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,11 @@ namespace winrt::TerminalApp::implementation
_RegisterActionCallbacks();

//Event Bindings (Early)
_newTabButton.Click([this](auto&&, auto&&) {
this->_OpenNewTab(nullptr);
_newTabButton.Click([weakThis](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->_OpenNewTab(nullptr);
}
});
_tabView.SelectionChanged({ this, &TerminalPage::_OnTabSelectionChanged });
_tabView.TabCloseRequested({ this, &TerminalPage::_OnTabCloseRequested });
Expand Down Expand Up @@ -318,10 +321,15 @@ namespace winrt::TerminalApp::implementation
profileMenuItem.FontWeight(FontWeights::Bold());
}

profileMenuItem.Click([this, profileIndex](auto&&, auto&&) {
auto newTerminalArgs = winrt::make_self<winrt::TerminalApp::implementation::NewTerminalArgs>();
newTerminalArgs->ProfileIndex(profileIndex);
this->_OpenNewTab(*newTerminalArgs);
auto weakThis{ get_weak() };

profileMenuItem.Click([profileIndex, weakThis](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
auto newTerminalArgs = winrt::make_self<winrt::TerminalApp::implementation::NewTerminalArgs>();
newTerminalArgs->ProfileIndex(profileIndex);
page->_OpenNewTab(*newTerminalArgs);
}
});
newTabFlyout.Items().Append(profileMenuItem);
}
Expand Down Expand Up @@ -701,9 +709,11 @@ namespace winrt::TerminalApp::implementation
const auto& _tab = _tabs.at(focusedTabIndex);

const auto& profileGuid = _tab->GetFocusedProfile();
const auto& settings = _settings->MakeSettings(profileGuid);

_CreateNewTabFromSettings(profileGuid.value(), settings);
if (profileGuid.has_value())
{
const auto settings = _settings->BuildSettings(profileGuid.value());
_CreateNewTabFromSettings(profileGuid.value(), settings);
}
}

// Method Description:
Expand Down Expand Up @@ -936,8 +946,9 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - splitType: one value from the TerminalApp::SplitState enum, indicating how the
// new pane should be split from its parent.
// - profile: The profile GUID to associate with the newly created pane. If
// this is nullopt, use the default profile.
// - newTerminalArgs: An object that may contain a blob of parameters to
// control which profile is created and with possible other
// configurations. See CascadiaSettings::BuildSettings for more details.
void TerminalPage::_SplitPane(const TerminalApp::SplitState splitType,
const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs)
{
Expand Down Expand Up @@ -1350,7 +1361,7 @@ namespace winrt::TerminalApp::implementation
for (auto& profile : profiles)
{
const GUID profileGuid = profile.GetGuid();
TerminalSettings settings = _settings->MakeSettings(profileGuid);
const auto settings = _settings->BuildSettings(profileGuid);

for (auto& tab : _tabs)
{
Expand Down