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

Patch the default profile and version into the settings template #5232

Merged
merged 4 commits into from
Apr 7, 2020
Merged
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
1 change: 1 addition & 0 deletions .github/actions/spell-check/dictionary/apis.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rfind
49 changes: 49 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,29 @@ catch (...)

namespace winrt::TerminalApp::implementation
{
// Function Description:
// - Get the AppLogic for the current active Xaml application, or null if there isn't one.
// Return value:
// - A pointer (bare) to the applogic, or nullptr. The app logic outlives all other objects,
// unless the application is in a terrible way, so this is "safe."
AppLogic* AppLogic::Current() noexcept
try
{
if (auto currentXamlApp{ winrt::Windows::UI::Xaml::Application::Current().try_as<winrt::TerminalApp::App>() })
{
if (auto appLogicPointer{ winrt::get_self<AppLogic>(currentXamlApp.Logic()) })
{
return appLogicPointer;
}
}
return nullptr;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return nullptr;
}

AppLogic::AppLogic() :
_dialogLock{},
_loadedInitialSettings{ false },
Expand Down Expand Up @@ -862,6 +885,32 @@ namespace winrt::TerminalApp::implementation
return { L"" };
}

winrt::hstring AppLogic::ApplicationDisplayName() const
{
try
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
return package.DisplayName();
}
CATCH_LOG();

return RS_(L"ApplicationDisplayNameUnpackaged");
}

winrt::hstring AppLogic::ApplicationVersion() const
{
try
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
const auto version{ package.Id().Version() };
winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
return formatted;
}
CATCH_LOG();

return RS_(L"ApplicationVersionUnknown");
}

// -------------------------------- WinRT Events ---------------------------------
// Winrt events need a method for adding a callback to the event and removing the callback.
// These macros will define them both for you.
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace winrt::TerminalApp::implementation
struct AppLogic : AppLogicT<AppLogic>
{
public:
static AppLogic* Current() noexcept;

AppLogic();
~AppLogic() = default;

Expand All @@ -28,6 +30,9 @@ namespace winrt::TerminalApp::implementation
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions);
winrt::hstring EarlyExitMessage();

winrt::hstring ApplicationDisplayName() const;
winrt::hstring ApplicationVersion() const;

Windows::Foundation::Point GetLaunchDimensions(uint32_t dpi);
winrt::Windows::Foundation::Point GetLaunchInitialPositions(int32_t defaultInitialX, int32_t defaultInitialY);
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.idl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ namespace TerminalApp

String Title { get; };

String ApplicationDisplayName { get; };
String ApplicationVersion { get; };

Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi);
Windows.Foundation.Point GetLaunchInitialPositions(Int32 defaultInitialX, Int32 defaultInitialY);
Windows.UI.Xaml.ElementTheme GetRequestedTheme();
Expand Down
46 changes: 40 additions & 6 deletions src/cascadia/TerminalApp/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ static constexpr std::wstring_view PACKAGED_PROFILE_ICON_PATH{ L"ms-appx:///Prof
static constexpr std::wstring_view PACKAGED_PROFILE_ICON_EXTENSION{ L".png" };
static constexpr std::wstring_view DEFAULT_LINUX_ICON_GUID{ L"{9acb9455-ca41-5af7-950f-6bca1bc9722f}" };

// make sure this matches defaults.json.
static constexpr std::wstring_view DEFAULT_WINDOWS_POWERSHELL_GUID{ L"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}" };

// Method Description:
// - Returns the settings currently in use by the entire Terminal application.
// Throws:
// - HR E_INVALIDARG if the app isn't up and running.
const CascadiaSettings& CascadiaSettings::GetCurrentAppSettings()
{
auto currentXamlApp{ winrt::Windows::UI::Xaml::Application::Current().as<winrt::TerminalApp::App>() };
THROW_HR_IF_NULL(E_INVALIDARG, currentXamlApp);

auto appLogic = winrt::get_self<winrt::TerminalApp::implementation::AppLogic>(currentXamlApp.Logic());
auto appLogic{ ::winrt::TerminalApp::implementation::AppLogic::Current() };
THROW_HR_IF_NULL(E_INVALIDARG, appLogic);

return *(appLogic->GetSettings());
}

Expand Down Expand Up @@ -70,7 +69,7 @@ CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles)
// - profileName: the name of the profile's GUID to return.
// Return Value:
// - the GUID associated with the profile name.
std::optional<GUID> CascadiaSettings::FindGuid(const std::wstring& profileName) const noexcept
std::optional<GUID> CascadiaSettings::FindGuid(const std::wstring_view profileName) const noexcept
{
std::optional<GUID> profileGuid{};

Expand Down Expand Up @@ -673,3 +672,38 @@ void CascadiaSettings::_ValidateKeybindings()
_warnings.insert(_warnings.end(), keybindingWarnings.begin(), keybindingWarnings.end());
}
}

// Method Description
// - Replaces known tokens DEFAULT_PROFILE, PRODUCT and VERSION in the settings template
// with their expected values. DEFAULT_PROFILE is updated to match PowerShell Core's GUID
// if such a profile is detected. If it isn't, it'll be set to Windows PowerShell's GUID.
// Arguments:
// - settingsTemplate: a settings template
// Return value:
// - The new settings string.
std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::string_view settingsTemplate) const
DHowett-MSFT marked this conversation as resolved.
Show resolved Hide resolved
{
std::string finalSettings{ settingsTemplate };
auto replace{ [](std::string& haystack, std::string_view needle, std::string_view replacement) {
auto pos{ std::string::npos };
while ((pos = haystack.rfind(needle, pos)) != std::string::npos)
{
haystack.replace(pos, needle.size(), replacement);
}
} };
Comment on lines +687 to +693
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how many projects have had to write this exact thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:laughing_but_crying_inside:


std::wstring defaultProfileGuid{ DEFAULT_WINDOWS_POWERSHELL_GUID };
if (const auto psCoreProfileGuid{ FindGuid(PowershellCoreProfileGenerator::GetPreferredPowershellProfileName()) })
{
defaultProfileGuid = Utils::GuidToString(*psCoreProfileGuid);
}

replace(finalSettings, "%DEFAULT_PROFILE%", til::u16u8(defaultProfileGuid));
if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() })
{
replace(finalSettings, "%VERSION%", til::u16u8(appLogic->ApplicationVersion()));
replace(finalSettings, "%PRODUCT%", til::u16u8(appLogic->ApplicationDisplayName()));
}

return finalSettings;
}
3 changes: 2 additions & 1 deletion src/cascadia/TerminalApp/CascadiaSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class TerminalApp::CascadiaSettings final
static std::filesystem::path GetSettingsPath();
static std::filesystem::path GetDefaultSettingsPath();

std::optional<GUID> FindGuid(const std::wstring& profileName) const noexcept;
std::optional<GUID> FindGuid(const std::wstring_view profileName) const noexcept;
const Profile* FindProfile(GUID profileGuid) const noexcept;

std::vector<TerminalApp::SettingsLoadWarnings>& GetWarnings();
Expand All @@ -95,6 +95,7 @@ class TerminalApp::CascadiaSettings final
static const Json::Value& _GetDisabledProfileSourcesJsonObject(const Json::Value& json);
bool _PrependSchemaDirective();
bool _AppendDynamicProfilesToUserSettings();
std::string _ApplyFirstRunChangesToSettingsTemplate(std::string_view settingsTemplate) const;

void _ApplyDefaultsFromUserSettings();

Expand Down
20 changes: 13 additions & 7 deletions src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,22 @@ std::unique_ptr<CascadiaSettings> CascadiaSettings::LoadAll()
{
resultPtr->_ParseJsonString(fileData.value(), false);
}
else

// Load profiles from dynamic profile generators. _userSettings should be
// created by now, because we're going to check in there for any generators
// that should be disabled (if the user had any settings.)
resultPtr->_LoadDynamicProfiles();

if (!fileHasData)
{
// We didn't find the user settings. We'll need to create a file
// to use as the user defaults.
// For now, just parse our user settings template as their user settings.
resultPtr->_ParseJsonString(UserSettingsJson, false);
auto userSettings{ resultPtr->_ApplyFirstRunChangesToSettingsTemplate(UserSettingsJson) };
resultPtr->_ParseJsonString(userSettings, false);
needToWriteFile = true;
}

// Load profiles from dynamic profile generators. _userSettings should be
// created by now, because we're going to check in there for any generators
// that should be disabled.
resultPtr->_LoadDynamicProfiles();

// See microsoft/terminal#2325: find the defaultSettings from the user's
// settings. Layer those settings upon all the existing profiles we have
// (defaults and dynamic profiles). We'll also set
Expand Down Expand Up @@ -902,5 +904,9 @@ const Json::Value& CascadiaSettings::_GetProfilesJsonObject(const Json::Value& j
// given object
const Json::Value& CascadiaSettings::_GetDisabledProfileSourcesJsonObject(const Json::Value& json)
{
if (!json)
{
return Json::Value::nullSingleton();
}
return json[JsonKey(DisabledProfileSourcesKey)];
}
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/DefaultProfileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name)
gsl::as_bytes(gsl::make_span(name))) };
TerminalApp::Profile newProfile{ profileGuid };

newProfile.SetName(static_cast<std::wstring>(name));
newProfile.SetName(name);

std::wstring iconPath{ PACKAGED_PROFILE_ICON_PATH };
iconPath.append(Microsoft::Console::Utils::GuidToString(profileGuid));
Expand Down
12 changes: 11 additions & 1 deletion src/cascadia/TerminalApp/PowershellCoreProfileGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static constexpr std::wstring_view POWERSHELL_PREVIEW_PFN{ L"Microsoft.PowerShel
static constexpr std::wstring_view PWSH_EXE{ L"pwsh.exe" };
static constexpr std::wstring_view POWERSHELL_ICON{ L"ms-appx:///ProfileIcons/pwsh.png" };
static constexpr std::wstring_view POWERSHELL_PREVIEW_ICON{ L"ms-appx:///ProfileIcons/pwsh-preview.png" };
static constexpr std::wstring_view POWERSHELL_PREFERRED_PROFILE_NAME{ L"PowerShell" };

namespace
{
Expand Down Expand Up @@ -322,8 +323,17 @@ std::vector<TerminalApp::Profile> PowershellCoreProfileGenerator::GenerateProfil
// (or the closest approximation thereof). It may choose a preview instance as the "best" if it is a higher version.
auto firstProfile = profiles.begin();
firstProfile->SetGuid(PowershellCoreGuid);
firstProfile->SetName(L"PowerShell");
firstProfile->SetName(POWERSHELL_PREFERRED_PROFILE_NAME);
}

return profiles;
}

// Function Description:
// - Returns the thing it's named for.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too cheeky?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh. Always nice to have a few of these sprinkled throughout haha

// Return value:
// - the thing it says in the name
const std::wstring_view PowershellCoreProfileGenerator::GetPreferredPowershellProfileName()
{
return POWERSHELL_PREFERRED_PROFILE_NAME;
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/PowershellCoreProfileGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ namespace TerminalApp
class PowershellCoreProfileGenerator : public TerminalApp::IDynamicProfileGenerator
{
public:
static const std::wstring_view GetPreferredPowershellProfileName();

PowershellCoreProfileGenerator() = default;
~PowershellCoreProfileGenerator() = default;
std::wstring_view GetNamespace() override;
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalApp/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,9 +718,9 @@ void Profile::SetStartingDirectory(std::wstring startingDirectory) noexcept
_startingDirectory = std::move(startingDirectory);
}

void Profile::SetName(std::wstring name) noexcept
void Profile::SetName(const std::wstring_view name) noexcept
{
_name = std::move(name);
_name = static_cast<std::wstring>(name);
}

void Profile::SetUseAcrylic(bool useAcrylic) noexcept
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class TerminalApp::Profile final
void SetAcrylicOpacity(double opacity) noexcept;
void SetCommandline(std::wstring cmdline) noexcept;
void SetStartingDirectory(std::wstring startingDirectory) noexcept;
void SetName(std::wstring name) noexcept;
void SetName(const std::wstring_view name) noexcept;
void SetUseAcrylic(bool useAcrylic) noexcept;
void SetDefaultForeground(COLORREF defaultForeground) noexcept;
void SetDefaultBackground(COLORREF defaultBackground) noexcept;
Expand Down
6 changes: 3 additions & 3 deletions src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,11 @@ Temporarily using the Windows Terminal default settings.
<value>Privacy Policy</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_DisplayNameUnpackaged" xml:space="preserve">
<data name="ApplicationDisplayNameUnpackaged" xml:space="preserve">
<value>Windows Terminal (Unpackaged)</value>
<comment>This display name is used when the application's name cannot be determined</comment>
</data>
<data name="AboutDialog_VersionUnknown" xml:space="preserve">
<data name="ApplicationVersionUnknown" xml:space="preserve">
<value>Unknown</value>
<comment>This is displayed when the version of the application cannot be determined</comment>
</data>
Expand All @@ -283,4 +283,4 @@ Temporarily using the Windows Terminal default settings.
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Do you want to close all tabs?</value>
</data>
</root>
</root>
19 changes: 7 additions & 12 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "TerminalPage.h"
#include "ActionAndArgs.h"
#include "Utils.h"
#include "AppLogic.h"
#include "../../types/inc/utils.hpp"

#include <LibraryResources.h>
Expand Down Expand Up @@ -234,28 +235,22 @@ namespace winrt::TerminalApp::implementation

winrt::hstring TerminalPage::ApplicationDisplayName()
{
try
if (const auto appLogic{ implementation::AppLogic::Current() })
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
return package.DisplayName();
return appLogic->ApplicationDisplayName();
}
CATCH_LOG();

return RS_(L"AboutDialog_DisplayNameUnpackaged");
return RS_(L"ApplicationDisplayNameUnpackaged");
}

winrt::hstring TerminalPage::ApplicationVersion()
{
try
if (const auto appLogic{ implementation::AppLogic::Current() })
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
const auto version{ package.Id().Version() };
winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
return formatted;
return appLogic->ApplicationVersion();
}
CATCH_LOG();

return RS_(L"AboutDialog_VersionUnknown");
return RS_(L"ApplicationVersionUnknown");
}

// Method Description:
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalApp/userDefaults.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// This file was generated by %PRODUCT% %VERSION%
DHowett-MSFT marked this conversation as resolved.
Show resolved Hide resolved

// To view the default settings, hold "alt" while clicking on the "Settings" button.
// For documentation on these settings, see: https://aka.ms/terminal-documentation

{
"$schema": "https://aka.ms/terminal-profiles-schema",

"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"defaultProfile": "%DEFAULT_PROFILE%",

"profiles":
{
Expand Down