Merge remote-tracking branch 'origin/main' into dev/migrie/oop/ragnarok

This commit is contained in:
Mike Griese 2021-11-10 10:27:35 -06:00
commit d51c2cff35
110 changed files with 1112 additions and 1196 deletions

View file

@ -9,6 +9,7 @@ BUILDBRANCH
BUILDMSG
BUILDNUMBER
BYPOSITION
BYCOMMAND
charconv
CLASSNOTAVAILABLE
cmdletbinding
@ -16,6 +17,7 @@ COLORPROPERTY
colspan
COMDLG
comparand
commandlinetoargv
cstdint
CXICON
CYICON
@ -85,6 +87,7 @@ LSHIFT
MENUCOMMAND
MENUDATA
MENUINFO
MENUITEMINFOW
memicmp
mptt
mov
@ -159,6 +162,7 @@ toupper
TTask
TVal
UChar
ULARGE
UPDATEINIFILE
userenv
wcsstr

View file

@ -214,7 +214,7 @@ resources useful and interesting:
* Windows Terminal Launch: [Build 2019
Session](https://www.youtube.com/watch?v=KMudkRcwjCw)
* Run As Radio: [Show 645 - Windows Terminal with Richard
Turner](http://www.runasradio.com/Shows/Show/645)
Turner](https://www.runasradio.com/Shows/Show/645)
* Azure Devops Podcast: [Episode 54 - Kayla Cinnamon and Rich Turner on DevOps
on the Windows
Terminal](http://azuredevopspodcast.clear-measure.com/kayla-cinnamon-and-rich-turner-on-devops-on-the-windows-terminal-team-episode-54)

View file

@ -1478,6 +1478,11 @@
"description": "When set to true, trailing white-spaces will be removed from text in rectangular (block) selection while copied to your clipboard. When set to false, the white-spaces will be preserved.",
"type": "boolean"
},
"trimPaste": {
"default": true,
"description": "When enabled, the Terminal will automatically trim trailing whitespace characters when pasting text",
"type": "boolean"
},
"experimental.detectURLs": {
"default": true,
"description": "When set to true, URLs will be detected by the Terminal. This will cause URLs to underline on hover and be clickable by pressing Ctrl.",

View file

@ -268,7 +268,7 @@ Today, if the deserialization of `CascadiaSettings` encounters any errors, an ex
To get around this issue, when `CascadiaSettings` encounters a serialization error, it must internally record
any pertinent information for that error, and return the simple `CascadiaSettings` as if nothing happened.
The consumer must then call `CascadiaSettings::GetErrors()` and `CascadiaSettings::GetWarnings()` to properly
understand whether an error ocurred and how to present that to the user.
understand whether an error occurred and how to present that to the user.
#### TerminalApp: Loading and Reloading Changes

View file

@ -12,8 +12,30 @@ static_assert(alignof(TextAttribute) == 2);
// Ensure that we can memcpy() and memmove() the struct for performance.
static_assert(std::is_trivially_copyable_v<TextAttribute>);
BYTE TextAttribute::s_legacyDefaultForeground = 7;
BYTE TextAttribute::s_legacyDefaultBackground = 0;
namespace
{
constexpr std::array<TextColor, 16> s_initLegacyColorMap(const BYTE defaultIndex)
{
std::array<TextColor, 16> legacyColorMap;
for (auto i = 0u; i < legacyColorMap.size(); i++)
{
const auto legacyIndex = TextColor::TransposeLegacyIndex(i);
gsl::at(legacyColorMap, i) = i == defaultIndex ? TextColor{} : TextColor{ legacyIndex, true };
}
return legacyColorMap;
}
BYTE s_legacyDefaultForeground = 7;
BYTE s_legacyDefaultBackground = 0;
BYTE s_ansiDefaultForeground = 7;
BYTE s_ansiDefaultBackground = 0;
}
// These maps allow for an efficient conversion from a legacy attribute index
// to a TextColor with the corresponding ANSI index, also taking into account
// the legacy index values that need to be converted to a default TextColor.
std::array<TextColor, 16> TextAttribute::s_legacyForegroundColorMap = s_initLegacyColorMap(7);
std::array<TextColor, 16> TextAttribute::s_legacyBackgroundColorMap = s_initLegacyColorMap(0);
// Routine Description:
// - Sets the legacy attributes which map to and from the default colors.
@ -23,8 +45,22 @@ BYTE TextAttribute::s_legacyDefaultBackground = 0;
// - None
void TextAttribute::SetLegacyDefaultAttributes(const WORD defaultAttributes) noexcept
{
// First we reset the current default color map entries to what they should
// be for a regular translation from a legacy index to an ANSI TextColor.
gsl::at(s_legacyForegroundColorMap, s_legacyDefaultForeground) = TextColor{ s_ansiDefaultForeground, true };
gsl::at(s_legacyBackgroundColorMap, s_legacyDefaultBackground) = TextColor{ s_ansiDefaultBackground, true };
// Then we save the new default attribute values and their corresponding
// ANSI translations. We use the latter values to more efficiently handle
// the "VT Quirk" conversion below.
s_legacyDefaultForeground = defaultAttributes & FG_ATTRS;
s_legacyDefaultBackground = (defaultAttributes & BG_ATTRS) >> 4;
s_ansiDefaultForeground = TextColor::TransposeLegacyIndex(s_legacyDefaultForeground);
s_ansiDefaultBackground = TextColor::TransposeLegacyIndex(s_legacyDefaultBackground);
// Finally we set the new default color map entries.
gsl::at(s_legacyForegroundColorMap, s_legacyDefaultForeground) = TextColor{};
gsl::at(s_legacyBackgroundColorMap, s_legacyDefaultBackground) = TextColor{};
}
// Routine Description:
@ -55,13 +91,13 @@ TextAttribute TextAttribute::StripErroneousVT16VersionsOfLegacyDefaults(const Te
const auto bg{ attribute.GetBackground() };
auto copy{ attribute };
if (fg.IsIndex16() &&
attribute.IsBold() == WI_IsFlagSet(s_legacyDefaultForeground, FOREGROUND_INTENSITY) &&
fg.GetIndex() == (s_legacyDefaultForeground & ~FOREGROUND_INTENSITY))
attribute.IsBold() == WI_IsFlagSet(s_ansiDefaultForeground, FOREGROUND_INTENSITY) &&
fg.GetIndex() == (s_ansiDefaultForeground & ~FOREGROUND_INTENSITY))
{
// We don't want to turn 1;37m into 39m (or even 1;39m), as this was meant to mimic a legacy color.
copy.SetDefaultForeground();
}
if (bg.IsIndex16() && bg.GetIndex() == s_legacyDefaultBackground)
if (bg.IsIndex16() && bg.GetIndex() == s_ansiDefaultBackground)
{
copy.SetDefaultBackground();
}

View file

@ -41,8 +41,8 @@ public:
explicit constexpr TextAttribute(const WORD wLegacyAttr) noexcept :
_wAttrLegacy{ gsl::narrow_cast<WORD>(wLegacyAttr & META_ATTRS) },
_foreground{ s_LegacyIndexOrDefault(wLegacyAttr & FG_ATTRS, s_legacyDefaultForeground) },
_background{ s_LegacyIndexOrDefault((wLegacyAttr & BG_ATTRS) >> 4, s_legacyDefaultBackground) },
_foreground{ gsl::at(s_legacyForegroundColorMap, wLegacyAttr & FG_ATTRS) },
_background{ gsl::at(s_legacyBackgroundColorMap, (wLegacyAttr & BG_ATTRS) >> 4) },
_extendedAttrs{ ExtendedAttributes::Normal },
_hyperlinkId{ 0 }
{
@ -167,13 +167,8 @@ public:
}
private:
static constexpr TextColor s_LegacyIndexOrDefault(const BYTE requestedIndex, const BYTE defaultIndex)
{
return requestedIndex == defaultIndex ? TextColor{} : TextColor{ requestedIndex, true };
}
static BYTE s_legacyDefaultForeground;
static BYTE s_legacyDefaultBackground;
static std::array<TextColor, 16> s_legacyForegroundColorMap;
static std::array<TextColor, 16> s_legacyBackgroundColorMap;
uint16_t _wAttrLegacy; // sizeof: 2, alignof: 2
uint16_t _hyperlinkId; // sizeof: 2, alignof: 2

View file

@ -32,7 +32,7 @@ constexpr std::array<BYTE, 256> CompressedRgbToIndex16 = {
// A table mapping indexed colors from the 256-color palette,
// down to one of the 16 colors in the legacy palette.
constexpr std::array<BYTE, 256> Index256ToIndex16 = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15,
0, 1, 1, 1, 9, 9, 2, 1, 1, 1, 1, 1, 2, 2, 3, 3,
3, 3, 2, 2, 11, 11, 3, 3, 10, 10, 11, 11, 11, 11, 10, 10,
10, 10, 11, 11, 5, 5, 5, 5, 1, 1, 8, 8, 1, 1, 9, 9,
@ -252,11 +252,7 @@ BYTE TextColor::GetLegacyIndex(const BYTE defaultIndex) const noexcept
{
return defaultIndex;
}
else if (IsIndex16())
{
return GetIndex();
}
else if (IsIndex256())
else if (IsIndex16() || IsIndex256())
{
return til::at(Index256ToIndex16, GetIndex());
}

View file

@ -48,6 +48,23 @@ enum class ColorType : BYTE
struct TextColor
{
public:
static constexpr BYTE DARK_BLACK = 0;
static constexpr BYTE DARK_RED = 1;
static constexpr BYTE DARK_GREEN = 2;
static constexpr BYTE DARK_YELLOW = 3;
static constexpr BYTE DARK_BLUE = 4;
static constexpr BYTE DARK_MAGENTA = 5;
static constexpr BYTE DARK_CYAN = 6;
static constexpr BYTE DARK_WHITE = 7;
static constexpr BYTE BRIGHT_BLACK = 8;
static constexpr BYTE BRIGHT_RED = 9;
static constexpr BYTE BRIGHT_GREEN = 10;
static constexpr BYTE BRIGHT_YELLOW = 11;
static constexpr BYTE BRIGHT_BLUE = 12;
static constexpr BYTE BRIGHT_MAGENTA = 13;
static constexpr BYTE BRIGHT_CYAN = 14;
static constexpr BYTE BRIGHT_WHITE = 15;
constexpr TextColor() noexcept :
_meta{ ColorType::IsDefault },
_red{ 0 },
@ -96,6 +113,16 @@ public:
COLORREF GetRGB() const noexcept;
static constexpr BYTE TransposeLegacyIndex(const size_t index)
{
// When converting a 16-color index in the legacy Windows order to or
// from an ANSI-compatible order, we need to swap the bits in positions
// 0 and 2. We do this by XORing the index with 00000101, but only if
// one (but not both) of those bit positions is set.
const auto oneBitSet = (index ^ (index >> 2)) & 1;
return gsl::narrow_cast<BYTE>(index ^ oneBitSet ^ (oneBitSet << 2));
}
private:
union
{

View file

@ -237,7 +237,7 @@ void TextAttributeTests::TestRoundtripDefaultColors()
Log::Comment(L"Foreground legacy default index should map to default text color.");
legacyAttribute = fgLegacyDefault | BACKGROUND_GREEN;
textAttribute.SetDefaultForeground();
textAttribute.SetIndexedBackground256(BACKGROUND_GREEN >> 4);
textAttribute.SetIndexedBackground256(TextColor::DARK_GREEN);
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
Log::Comment(L"Default foreground text color should map back to legacy default index.");
@ -245,7 +245,7 @@ void TextAttributeTests::TestRoundtripDefaultColors()
Log::Comment(L"Background legacy default index should map to default text color.");
legacyAttribute = FOREGROUND_GREEN | bgLegacyDefault;
textAttribute.SetIndexedForeground256(FOREGROUND_GREEN);
textAttribute.SetIndexedForeground256(TextColor::DARK_GREEN);
textAttribute.SetDefaultBackground();
VERIFY_ARE_EQUAL(textAttribute, TextAttribute{ legacyAttribute });
@ -288,7 +288,7 @@ void TextAttributeTests::TestBoldAsBright()
VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true));
VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false));
attr.SetIndexedForeground(0);
attr.SetIndexedForeground(TextColor::DARK_BLACK);
VERIFY_IS_TRUE(attr.IsBold());
Log::Comment(L"Foreground should be bright black when bold is bright is enabled");
@ -297,7 +297,7 @@ void TextAttributeTests::TestBoldAsBright()
Log::Comment(L"Foreground should be dark black when bold is bright is disabled");
VERIFY_ARE_EQUAL(std::make_pair(darkBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false));
attr.SetIndexedBackground(2);
attr.SetIndexedBackground(TextColor::DARK_GREEN);
VERIFY_IS_TRUE(attr.IsBold());
Log::Comment(L"background should be unaffected by 'bold is bright'");
@ -312,7 +312,7 @@ void TextAttributeTests::TestBoldAsBright()
Log::Comment(L"When set to a bright color, and bold, 'bold is bright' changes nothing");
attr.SetBold(true);
attr.SetIndexedForeground(8);
attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
VERIFY_IS_TRUE(attr.IsBold());
VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true));
VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false));

View file

@ -80,7 +80,7 @@ namespace SettingsModelLocalTests
std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable;
const auto campbellSpan = gsl::make_span(expectedCampbellTable);
Utils::InitializeCampbellColorTable(campbellSpan);
Utils::InitializeColorTable(campbellSpan);
Utils::SetColorTableAlpha(campbellSpan, 0);
for (size_t i = 0; i < expectedCampbellTable.size(); i++)

View file

@ -503,7 +503,7 @@ namespace TerminalAppLocalTests
Log::Comment(NoThrowString().Format(L"Duplicate the first pane"));
result = RunOnUIThread([&page]() {
page->_SplitPane(SplitDirection::Automatic, SplitType::Duplicate, 0.5f, nullptr);
page->_SplitPane(SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, true, nullptr));
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
@ -521,7 +521,7 @@ namespace TerminalAppLocalTests
Log::Comment(NoThrowString().Format(L"Duplicate the pane, and don't crash"));
result = RunOnUIThread([&page]() {
page->_SplitPane(SplitDirection::Automatic, SplitType::Duplicate, 0.5f, nullptr);
page->_SplitPane(SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, true, nullptr));
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
@ -839,7 +839,7 @@ namespace TerminalAppLocalTests
// | 1 | 2 |
// | | |
// -------------------
page->_SplitPane(SplitDirection::Right, SplitType::Duplicate, 0.5f, nullptr);
page->_SplitPane(SplitDirection::Right, 0.5f, page->_MakePane(nullptr, true, nullptr));
secondId = tab->_activePane->Id().value();
});
Sleep(250);
@ -857,7 +857,7 @@ namespace TerminalAppLocalTests
// | 3 | |
// | | |
// -------------------
page->_SplitPane(SplitDirection::Down, SplitType::Duplicate, 0.5f, nullptr);
page->_SplitPane(SplitDirection::Down, 0.5f, page->_MakePane(nullptr, true, nullptr));
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
// Split again to make the 3rd tab
thirdId = tab->_activePane->Id().value();
@ -877,7 +877,7 @@ namespace TerminalAppLocalTests
// | 3 | 4 |
// | | |
// -------------------
page->_SplitPane(SplitDirection::Down, SplitType::Duplicate, 0.5f, nullptr);
page->_SplitPane(SplitDirection::Down, 0.5f, page->_MakePane(nullptr, true, nullptr));
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
fourthId = tab->_activePane->Id().value();
});

View file

@ -174,10 +174,9 @@ namespace winrt::TerminalApp::implementation
else if (const auto& realArgs = args.ActionArgs().try_as<SplitPaneArgs>())
{
_SplitPane(realArgs.SplitDirection(),
realArgs.SplitMode(),
// This is safe, we're already filtering so the value is (0, 1)
::base::saturated_cast<float>(realArgs.SplitSize()),
realArgs.TerminalArgs());
_MakePane(realArgs.TerminalArgs(), realArgs.SplitMode() == SplitType::Duplicate));
args.Handled(true);
}
}

View file

@ -334,6 +334,9 @@ namespace winrt::TerminalApp::implementation
_RefreshThemeRoutine();
_ApplyStartupTaskStateChange();
auto args = winrt::make_self<SystemMenuChangeArgs>(RS_(L"SettingsMenuItem"), SystemMenuChangeAction::Add, SystemMenuItemHandler(this, &AppLogic::_OpenSettingsUI));
_SystemMenuChangeRequestedHandlers(*this, *args);
TraceLoggingWrite(
g_hTerminalAppProvider,
"AppCreated",
@ -1051,6 +1054,11 @@ namespace winrt::TerminalApp::implementation
_SettingsChangedHandlers(*this, nullptr);
}
void AppLogic::_OpenSettingsUI()
{
_root->OpenSettingsUI();
}
// Method Description:
// - Returns a pointer to the global shared settings.
[[nodiscard]] CascadiaSettings AppLogic::GetSettings() const noexcept
@ -1557,6 +1565,11 @@ namespace winrt::TerminalApp::implementation
return _root->IsQuakeWindow();
}
void AppLogic::RequestExitFullscreen()
{
_root->SetFullscreen(false);
}
bool AppLogic::GetMinimizeToNotificationArea()
{
if constexpr (Feature_NotificationIcon::IsEnabled())

View file

@ -5,6 +5,7 @@
#include "AppLogic.g.h"
#include "FindTargetWindowResult.g.h"
#include "SystemMenuChangeArgs.g.h"
#include "Jumplist.h"
#include "LanguageProfileNotifier.h"
#include "TerminalPage.h"
@ -35,6 +36,17 @@ namespace winrt::TerminalApp::implementation
FindTargetWindowResult(id, L""){};
};
struct SystemMenuChangeArgs : SystemMenuChangeArgsT<SystemMenuChangeArgs>
{
WINRT_PROPERTY(winrt::hstring, Name, L"");
WINRT_PROPERTY(SystemMenuChangeAction, Action, SystemMenuChangeAction::Add);
WINRT_PROPERTY(SystemMenuItemHandler, Handler, nullptr);
public:
SystemMenuChangeArgs(const winrt::hstring& name, SystemMenuChangeAction action, SystemMenuItemHandler handler = nullptr) :
_Name{ name }, _Action{ action }, _Handler{ handler } {};
};
struct AppLogic : AppLogicT<AppLogic, IInitializeWithWindow>
{
public:
@ -79,6 +91,7 @@ namespace winrt::TerminalApp::implementation
void SetPersistedLayoutIdx(const uint32_t idx);
void SetNumberOfOpenWindows(const uint64_t num);
bool IsQuakeWindow() const noexcept;
void RequestExitFullscreen();
Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
bool CenterOnLaunch();
@ -113,6 +126,7 @@ namespace winrt::TerminalApp::implementation
// -------------------------------- WinRT Events ---------------------------------
TYPED_EVENT(RequestedThemeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);
TYPED_EVENT(SettingsChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(SystemMenuChangeRequested, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SystemMenuChangeArgs);
private:
bool _isUwp{ false };
@ -163,6 +177,7 @@ namespace winrt::TerminalApp::implementation
void _RegisterSettingsChange();
fire_and_forget _DispatchReloadSettings();
void _ReloadSettings();
void _OpenSettingsUI();
void _ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme);

View file

@ -19,6 +19,20 @@ namespace TerminalApp
String WindowName { get; };
};
delegate void SystemMenuItemHandler();
enum SystemMenuChangeAction
{
Add = 0,
Remove = 1
};
[default_interface] runtimeclass SystemMenuChangeArgs {
String Name { get; };
SystemMenuChangeAction Action { get; };
SystemMenuItemHandler Handler { get; };
};
[default_interface] runtimeclass AppLogic : IDirectKeyListener, IDialogPresenter
{
AppLogic();
@ -60,6 +74,7 @@ namespace TerminalApp
void SetPersistedLayoutIdx(UInt32 idx);
void SetNumberOfOpenWindows(UInt64 num);
void RenameFailed();
void RequestExitFullscreen();
Boolean IsQuakeWindow();
Windows.Foundation.Size GetLaunchDimensions(UInt32 dpi);
@ -110,5 +125,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.SystemMenuChangeArgs> SystemMenuChangeRequested;
}
}

View file

@ -2335,35 +2335,32 @@ std::optional<bool> Pane::PreCalculateCanSplit(const std::shared_ptr<Pane> targe
}
// Method Description:
// - Split the focused pane in our tree of panes, and place the given
// TermControl into the newly created pane. If we're the focused pane, then
// we'll create two new children, and place them side-by-side in our Grid.
// - The same as above, except this takes in the pane directly instead of a
// profile and control to make a pane with
// Arguments:
// - splitType: what type of split we want to create.
// - profile: The profile to associate with the newly created pane.
// - control: A TermControl to use in the new pane.
// - splitSize: the desired size of the split
// - newPane: the new pane
// Return Value:
// - The two newly created Panes, with the original pane first
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::Split(SplitDirection splitType,
const float splitSize,
const Profile& profile,
const TermControl& control)
std::shared_ptr<Pane> newPane)
{
if (!_lastActive)
{
if (_firstChild && _firstChild->_HasFocusedChild())
{
return _firstChild->Split(splitType, splitSize, profile, control);
return _firstChild->Split(splitType, splitSize, newPane);
}
else if (_secondChild && _secondChild->_HasFocusedChild())
{
return _secondChild->Split(splitType, splitSize, profile, control);
return _secondChild->Split(splitType, splitSize, newPane);
}
return { nullptr, nullptr };
}
auto newPane = std::make_shared<Pane>(profile, control);
return _Split(splitType, splitSize, newPane);
}

View file

@ -110,8 +110,7 @@ public:
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control);
std::shared_ptr<Pane> pane);
bool ToggleSplitOrientation();
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateAutoSplit(const std::shared_ptr<Pane> target,

View file

@ -68,7 +68,7 @@ namespace winrt::TerminalApp::implementation
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
_CreateNewTabWithProfileAndSettings(profile, settings, existingConnection);
_CreateNewTabFromPane(_MakePane(newTerminalArgs, false, existingConnection));
const uint32_t tabCount = _tabs.Size();
const bool usedManualProfile = (newTerminalArgs != nullptr) &&
@ -244,58 +244,6 @@ namespace winrt::TerminalApp::implementation
_InitializeTab(newTabImpl);
}
// Method Description:
// - Creates a new tab with the given settings. If the tab bar is not being
// currently displayed, it will be shown.
// Arguments:
// - profile: profile settings for this connection
// - settings: the TerminalSettings object to use to create the TerminalControl with.
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
void TerminalPage::_CreateNewTabWithProfileAndSettings(const Profile& profile, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
{
// Initialize the new tab
// Create a connection based on the values in our settings object if we weren't given one.
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, settings.DefaultSettings());
// If we had an `existingConnection`, then this is an inbound handoff from somewhere else.
// We need to tell it about our size information so it can match the dimensions of what
// we are about to present.
if (existingConnection)
{
connection.Resize(settings.DefaultSettings().InitialRows(), settings.DefaultSettings().InitialCols());
}
TerminalConnection::ITerminalConnection debugConnection{ nullptr };
if (_settings.GlobalSettings().DebugFeaturesEnabled())
{
const CoreWindow window = CoreWindow::GetForCurrentThread();
const auto rAltState = window.GetKeyState(VirtualKey::RightMenu);
const auto lAltState = window.GetKeyState(VirtualKey::LeftMenu);
const bool bothAltsPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) &&
WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down);
if (bothAltsPressed)
{
std::tie(connection, debugConnection) = OpenDebugTapConnection(connection);
}
}
// Give term control a child of the settings so that any overrides go in the child
// This way, when we do a settings reload we just update the parent and the overrides remain
auto term = _InitControl(settings, connection);
auto newTabImpl = winrt::make_self<TerminalTab>(profile, term);
_RegisterTerminalEvents(term);
_InitializeTab(newTabImpl);
if (debugConnection) // this will only be set if global debugging is on and tap is active
{
auto newControl = _InitControl(settings, debugConnection);
_RegisterTerminalEvents(newControl);
// Split (auto) with the debug tap.
newTabImpl->SplitPane(SplitDirection::Automatic, 0.5f, profile, newControl);
}
}
// Method Description:
// - Get the icon of the currently focused terminal control, and set its
// tab's icon to that icon.
@ -365,28 +313,14 @@ namespace winrt::TerminalApp::implementation
// In the future, it may be preferable to just duplicate the
// current control's live settings (which will include changes
// made through VT).
_CreateNewTabFromPane(_MakePane(nullptr, true, nullptr));
if (auto profile = tab.GetFocusedProfile())
const auto runtimeTabText{ tab.GetTabText() };
if (!runtimeTabText.empty())
{
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
profile = GetClosestProfileForDuplicationOfProfile(profile);
const auto settingsCreateResult{ TerminalSettings::CreateWithProfile(_settings, profile, *_bindings) };
const auto workingDirectory = tab.GetActiveTerminalControl().WorkingDirectory();
const auto validWorkingDirectory = !workingDirectory.empty();
if (validWorkingDirectory)
if (auto newTab{ _GetFocusedTabImpl() })
{
settingsCreateResult.DefaultSettings().StartingDirectory(workingDirectory);
}
_CreateNewTabWithProfileAndSettings(profile, settingsCreateResult);
const auto runtimeTabText{ tab.GetTabText() };
if (!runtimeTabText.empty())
{
if (auto newTab{ _GetFocusedTabImpl() })
{
newTab->SetTabText(runtimeTabText);
}
newTab->SetTabText(runtimeTabText);
}
}
}
@ -402,7 +336,7 @@ namespace winrt::TerminalApp::implementation
try
{
_SetFocusedTab(tab);
_SplitPane(tab, SplitDirection::Automatic, SplitType::Duplicate);
_SplitPane(tab, SplitDirection::Automatic, 0.5f, _MakePane(nullptr, true));
}
CATCH_LOG();
}

View file

@ -850,14 +850,7 @@ namespace winrt::TerminalApp::implementation
WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) &&
WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down);
if (altPressed && !debugTap)
{
this->_SplitPane(SplitDirection::Automatic,
SplitType::Manual,
0.5f,
newTerminalArgs);
}
else if (shiftPressed && !debugTap)
if (shiftPressed && !debugTap)
{
// Manually fill in the evaluated profile.
if (newTerminalArgs.ProfileIndex() != nullptr)
@ -873,7 +866,17 @@ namespace winrt::TerminalApp::implementation
}
else
{
LOG_IF_FAILED(this->_OpenNewTab(newTerminalArgs));
const auto newPane = _MakePane(newTerminalArgs);
if (altPressed && !debugTap)
{
this->_SplitPane(SplitDirection::Automatic,
0.5f,
newPane);
}
else
{
_CreateNewTabFromPane(newPane);
}
}
}
@ -1485,18 +1488,15 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Split the focused pane either horizontally or vertically, and place the
// given TermControl into the newly created pane.
// given pane accordingly in the tree
// Arguments:
// - newPane: the pane to add to our tree of panes
// - splitDirection: one value from the TerminalApp::SplitDirection enum, indicating how the
// new pane should be split from its parent.
// - splitMode: value from TerminalApp::SplitType enum, indicating the profile to be used in the newly split pane.
// - 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.
// - splitSize: the size of the split
void TerminalPage::_SplitPane(const SplitDirection splitDirection,
const SplitType splitMode,
const float splitSize,
const NewTerminalArgs& newTerminalArgs)
std::shared_ptr<Pane> newPane)
{
const auto focusedTab{ _GetFocusedTabImpl() };
@ -1506,104 +1506,52 @@ namespace winrt::TerminalApp::implementation
return;
}
_SplitPane(*focusedTab, splitDirection, splitMode, splitSize, newTerminalArgs);
_SplitPane(*focusedTab, splitDirection, splitSize, newPane);
}
// Method Description:
// - Split the focused pane of the given tab, either horizontally or vertically, and place the
// given TermControl into the newly created pane.
// given pane accordingly
// Arguments:
// - tab: The tab that is going to be split.
// - newPane: the pane to add to our tree of panes
// - splitDirection: one value from the TerminalApp::SplitDirection enum, indicating how the
// new pane should be split from its parent.
// - splitMode: value from TerminalApp::SplitType enum, indicating the profile to be used in the newly split pane.
// - 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.
// - splitSize: the size of the split
void TerminalPage::_SplitPane(TerminalTab& tab,
const SplitDirection splitDirection,
const SplitType splitMode,
const float splitSize,
const NewTerminalArgs& newTerminalArgs)
std::shared_ptr<Pane> newPane)
{
try
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
const winrt::Windows::Foundation::Size availableSpace{ contentWidth, contentHeight };
auto realSplitType = splitDirection;
if (realSplitType == SplitDirection::Automatic)
{
TerminalSettingsCreateResult controlSettings{ nullptr };
Profile profile{ nullptr };
realSplitType = tab.PreCalculateAutoSplit(availableSpace);
}
if (splitMode == SplitType::Duplicate)
const auto canSplit = tab.PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
if (!canSplit)
{
return;
}
_UnZoomIfNeeded();
tab.SplitPane(realSplitType, splitSize, newPane);
// After GH#6586, the control will no longer focus itself
// automatically when it's finished being laid out. Manually focus
// the control here instead.
if (_startupState == StartupState::Initialized)
{
if (const auto control = _GetActiveControl())
{
profile = tab.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 = tab.GetActiveTerminalControl().WorkingDirectory();
const auto validWorkingDirectory = !workingDirectory.empty();
if (validWorkingDirectory)
{
controlSettings.DefaultSettings().StartingDirectory(workingDirectory);
}
}
// TODO: GH#5047 - In the future, we should get the Profile of
// the focused pane, and use that to build a new instance of the
// settings so we can duplicate this tab/pane.
//
// Currently, if the profile doesn't exist anymore in our
// settings, we'll silently do nothing.
//
// In the future, it will be preferable to just duplicate the
// current control's settings, but we can't do that currently,
// because we won't be able to create a new instance of the
// connection without keeping an instance of the original Profile
// object around.
}
if (!profile)
{
profile = _settings.GetProfileForArgs(newTerminalArgs);
controlSettings = TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings);
}
const auto controlConnection = _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings());
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
const winrt::Windows::Foundation::Size availableSpace{ contentWidth, contentHeight };
auto realSplitType = splitDirection;
if (realSplitType == SplitDirection::Automatic)
{
realSplitType = tab.PreCalculateAutoSplit(availableSpace);
}
const auto canSplit = tab.PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
if (!canSplit)
{
return;
}
auto newControl = _InitControl(controlSettings, controlConnection);
// Hookup our event handlers to the new terminal
_RegisterTerminalEvents(newControl);
_UnZoomIfNeeded();
tab.SplitPane(realSplitType, splitSize, profile, newControl);
// After GH#6586, the control will no longer focus itself
// automatically when it's finished being laid out. Manually focus
// the control here instead.
if (_startupState == StartupState::Initialized)
{
if (const auto control = _GetActiveControl())
{
control.Focus(FocusState::Programmatic);
}
control.Focus(FocusState::Programmatic);
}
}
CATCH_LOG();
}
// Method Description:
@ -2111,7 +2059,7 @@ namespace winrt::TerminalApp::implementation
{
if (target == SettingsTarget::SettingsUI)
{
_OpenSettingsUI();
OpenSettingsUI();
}
else
{
@ -2184,6 +2132,96 @@ namespace winrt::TerminalApp::implementation
return term;
}
// Method Description:
// - Creates a pane and returns a shared_ptr to it
// - The caller should handle where the pane goes after creation,
// either to split an already existing pane or to create a new tab with it
// Arguments:
// - 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.
// - duplicate: a boolean to indicate whether the pane we create should be
// a duplicate of the currently focused pane
// - existingConnection: optionally receives a connection from the outside
// world instead of attempting to create one
std::shared_ptr<Pane> TerminalPage::_MakePane(const NewTerminalArgs& newTerminalArgs, const bool duplicate, TerminalConnection::ITerminalConnection existingConnection)
{
TerminalSettingsCreateResult controlSettings{ nullptr };
Profile profile{ nullptr };
if (duplicate)
{
const auto focusedTab{ _GetFocusedTabImpl() };
if (focusedTab)
{
profile = focusedTab->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 = focusedTab->GetActiveTerminalControl().WorkingDirectory();
const auto validWorkingDirectory = !workingDirectory.empty();
if (validWorkingDirectory)
{
controlSettings.DefaultSettings().StartingDirectory(workingDirectory);
}
}
}
}
if (!profile)
{
profile = _settings.GetProfileForArgs(newTerminalArgs);
controlSettings = TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings);
}
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings());
if (existingConnection)
{
connection.Resize(controlSettings.DefaultSettings().InitialRows(), controlSettings.DefaultSettings().InitialCols());
}
TerminalConnection::ITerminalConnection debugConnection{ nullptr };
if (_settings.GlobalSettings().DebugFeaturesEnabled())
{
const CoreWindow window = CoreWindow::GetForCurrentThread();
const auto rAltState = window.GetKeyState(VirtualKey::RightMenu);
const auto lAltState = window.GetKeyState(VirtualKey::LeftMenu);
const bool bothAltsPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) &&
WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down);
if (bothAltsPressed)
{
std::tie(connection, debugConnection) = OpenDebugTapConnection(connection);
}
}
const auto control = _InitControl(controlSettings, connection);
_RegisterTerminalEvents(control);
auto resultPane = std::make_shared<Pane>(profile, control);
if (debugConnection) // this will only be set if global debugging is on and tap is active
{
auto newControl = _InitControl(controlSettings, debugConnection);
_RegisterTerminalEvents(newControl);
// Split (auto) with the debug tap.
auto debugPane = std::make_shared<Pane>(profile, newControl);
// Since we're doing this split directly on the pane (instead of going through TerminalTab,
// we need to handle the panes 'active' states
// Set the pane we're splitting to active (otherwise Split will not do anything)
resultPane->SetActive();
auto [original, _] = resultPane->Split(SplitDirection::Automatic, 0.5f, debugPane);
// Set the non-debug pane as active
resultPane->ClearActive();
original->SetActive();
}
return resultPane;
}
// Method Description:
// - Hook up keybindings, and refresh the UI of the terminal.
// This includes update the settings of all the tabs according
@ -2493,9 +2531,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalPage::ToggleFullscreen()
{
_isFullscreen = !_isFullscreen;
_UpdateTabView();
_FullscreenChangedHandlers(*this, nullptr);
SetFullscreen(!_isFullscreen);
}
// Method Description:
@ -2712,6 +2748,17 @@ namespace winrt::TerminalApp::implementation
return _isAlwaysOnTop;
}
void TerminalPage::SetFullscreen(bool newFullscreen)
{
if (_isFullscreen == newFullscreen)
{
return;
}
_isFullscreen = newFullscreen;
_UpdateTabView();
_FullscreenChangedHandlers(*this, nullptr);
}
HRESULT TerminalPage::_OnNewConnection(const ConptyConnection& connection)
{
// We need to be on the UI thread in order for _OpenNewTab to run successfully.
@ -2739,7 +2786,7 @@ namespace winrt::TerminalApp::implementation
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
const auto settings{ TerminalSettings::CreateWithProfile(_settings, profile, *_bindings) };
_CreateNewTabWithProfileAndSettings(profile, settings, connection);
_CreateNewTabFromPane(_MakePane(newTerminalArgs, false, connection));
// Request a summon of this window to the foreground
_SummonWindowRequestedHandlers(*this, nullptr);
@ -2755,7 +2802,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
// Return Value:
// - <none>
void TerminalPage::_OpenSettingsUI()
void TerminalPage::OpenSettingsUI()
{
// If we're holding the settings tab's switch command, don't create a new one, switch to the existing one.
if (!_settingsTab)
@ -3373,7 +3420,7 @@ namespace winrt::TerminalApp::implementation
TraceLoggingWrite(g_hTerminalAppProvider, "SetAsDefaultTipInteracted", TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
_OpenSettingsUI();
OpenSettingsUI();
}
// Method Description:

View file

@ -83,6 +83,7 @@ namespace winrt::TerminalApp::implementation
bool FocusMode() const;
bool Fullscreen() const;
bool AlwaysOnTop() const;
void SetFullscreen(bool);
void SetStartupActions(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
@ -121,6 +122,8 @@ namespace winrt::TerminalApp::implementation
bool IsQuakeWindow() const noexcept;
bool IsElevated() const noexcept;
void OpenSettingsUI();
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
// -------------------------------- WinRT Events ---------------------------------
@ -209,7 +212,6 @@ namespace winrt::TerminalApp::implementation
void _OpenNewTabDropdown();
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
void _CreateNewTabFromPane(std::shared_ptr<Pane> pane);
void _CreateNewTabWithProfileAndSettings(const Microsoft::Terminal::Settings::Model::Profile& profile, const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
winrt::fire_and_forget _OpenNewWindow(const bool elevate, const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
@ -297,14 +299,12 @@ namespace winrt::TerminalApp::implementation
void _Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll);
void _SplitPane(const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
const float splitSize = 0.5f,
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
const float splitSize,
std::shared_ptr<Pane> newPane);
void _SplitPane(TerminalTab& tab,
const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
const float splitSize = 0.5f,
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
const float splitSize,
std::shared_ptr<Pane> newPane);
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void _ToggleSplitOrientation();
@ -351,6 +351,10 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
std::shared_ptr<Pane> _MakePane(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr,
const bool duplicate = false,
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
void _RefreshUIForSettingsReload();
void _SetNonClientAreaColors(const Windows::UI::Color& selectedTabColor);
@ -366,8 +370,6 @@ namespace winrt::TerminalApp::implementation
void _UnZoomIfNeeded();
void _OpenSettingsUI();
static int _ComputeScrollDelta(ScrollDirection scrollDirection, const uint32_t rowsToScroll);
static uint32_t _ReadSystemRowsToScroll();

View file

@ -25,18 +25,6 @@ namespace winrt
namespace winrt::TerminalApp::implementation
{
TerminalTab::TerminalTab(const Profile& profile, const TermControl& control)
{
_rootPane = std::make_shared<Pane>(profile, control, true);
_rootPane->Id(_nextPaneId);
_activePane = _rootPane;
_mruPanes.insert(_mruPanes.begin(), _nextPaneId);
++_nextPaneId;
_Setup();
}
TerminalTab::TerminalTab(std::shared_ptr<Pane> rootPane)
{
_rootPane = rootPane;
@ -64,8 +52,9 @@ namespace winrt::TerminalApp::implementation
// focus the first one.
if (_activePane == nullptr)
{
_rootPane->FocusPane(firstId);
_activePane = _rootPane->GetActivePane();
const auto firstPane = _rootPane->FindPane(firstId);
firstPane->SetActive();
_activePane = firstPane;
}
// If the focused pane is a leaf, add it to the MRU panes
if (const auto id = _activePane->Id())
@ -503,39 +492,48 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Split the focused pane in our tree of panes, and place the
// given TermControl into the newly created pane.
// given pane into the tree of panes according to the split
// Arguments:
// - splitType: The type of split we want to create.
// - profile: The profile GUID to associate with the newly created pane.
// - control: A TermControl to use in the new pane.
// - splitType: The type of split we want to create
// - splitSize: The size of the split we want to create
// - pane: The new pane to add to the tree of panes; note that this pane
// could itself be a parent pane/the root node of a tree of panes
// Return Value:
// - <none>
void TerminalTab::SplitPane(SplitDirection splitType,
const float splitSize,
const Profile& profile,
TermControl& control)
std::shared_ptr<Pane> pane)
{
// Add the new event handlers to the new pane(s)
// and update their ids.
pane->WalkTree([&](auto p) {
_AttachEventHandlersToPane(p);
if (p->_IsLeaf())
{
p->Id(_nextPaneId);
_AttachEventHandlersToControl(p->Id().value(), p->_control);
_nextPaneId++;
}
return false;
});
// Make sure to take the ID before calling Split() - Split() will clear out the active pane's ID
const auto activePaneId = _activePane->Id();
// Depending on which direction will be split, the new pane can be
// either the first or second child, but this will always return the
// original pane first.
auto [original, newPane] = _activePane->Split(splitType, splitSize, profile, control);
auto [original, newPane] = _activePane->Split(splitType, splitSize, pane);
// The active pane has an id if it is a leaf
if (activePaneId)
{
original->Id(activePaneId.value());
}
newPane->Id(_nextPaneId);
++_nextPaneId;
_activePane = original;
// Add a event handlers to the new panes' GotFocus event. When the pane
// gains focus, we'll mark it as the new active pane.
_AttachEventHandlersToControl(newPane->Id().value(), control);
_AttachEventHandlersToPane(original);
_AttachEventHandlersToPane(newPane);
// Immediately update our tracker of the focused pane now. If we're
// splitting panes during startup (from a commandline), then it's

View file

@ -21,7 +21,6 @@ namespace winrt::TerminalApp::implementation
struct TerminalTab : TerminalTabT<TerminalTab, TabBase>
{
public:
TerminalTab(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile, const winrt::Microsoft::Terminal::Control::TermControl& control);
TerminalTab(std::shared_ptr<Pane> rootPane);
// Called after construction to perform the necessary setup, which relies on weak_ptr
@ -40,8 +39,7 @@ namespace winrt::TerminalApp::implementation
void SplitPane(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
winrt::Microsoft::Terminal::Control::TermControl& control);
std::shared_ptr<Pane> newPane);
void ToggleSplitOrientation();
winrt::fire_and_forget UpdateIcon(const winrt::hstring iconPath);

View file

@ -429,8 +429,9 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
// EXIT POINT
const auto hr = wil::ResultFromCaughtException();
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
winrt::hstring failureText{ fmt::format(std::wstring_view{ RS_(L"ProcessFailedToLaunch") },
fmt::format(_errorFormat, hr),
fmt::format(_errorFormat, static_cast<unsigned int>(hr)),
_commandline) };
_TerminalOutputHandlers(failureText);
@ -457,6 +458,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
try
{
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
winrt::hstring exitText{ fmt::format(std::wstring_view{ RS_(L"ProcessExited") }, fmt::format(_errorFormat, status)) };
_TerminalOutputHandlers(L"\r\n");
_TerminalOutputHandlers(exitText);

View file

@ -1211,9 +1211,7 @@ try
{
const gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() };
// First set up the basic 256 colors
Utils::Initialize256ColorTable(tableView);
// Then use fill the first 16 values with the Campbell scheme
Utils::InitializeCampbellColorTable(tableView);
Utils::InitializeColorTable(tableView);
// Then make sure all the values have an alpha of 255
Utils::SetColorTableAlpha(tableView, 0xff);
}

View file

@ -7,29 +7,6 @@
using namespace Microsoft::Console::VirtualTerminal;
using namespace Microsoft::Console::VirtualTerminal::DispatchTypes;
// clang-format off
const BYTE RED_ATTR = 0x01;
const BYTE GREEN_ATTR = 0x02;
const BYTE BLUE_ATTR = 0x04;
const BYTE BRIGHT_ATTR = 0x08;
const BYTE DARK_BLACK = 0;
const BYTE DARK_RED = RED_ATTR;
const BYTE DARK_GREEN = GREEN_ATTR;
const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR;
const BYTE DARK_BLUE = BLUE_ATTR;
const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR;
const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR;
const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR;
const BYTE BRIGHT_BLACK = BRIGHT_ATTR;
const BYTE BRIGHT_RED = BRIGHT_ATTR | RED_ATTR;
const BYTE BRIGHT_GREEN = BRIGHT_ATTR | GREEN_ATTR;
const BYTE BRIGHT_YELLOW = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR;
const BYTE BRIGHT_BLUE = BRIGHT_ATTR | BLUE_ATTR;
const BYTE BRIGHT_MAGENTA = BRIGHT_ATTR | RED_ATTR | BLUE_ATTR;
const BYTE BRIGHT_CYAN = BRIGHT_ATTR | GREEN_ATTR | BLUE_ATTR;
const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR;
// clang-format on
// Routine Description:
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG)
// These options are followed by either a 2 (RGB) or 5 (xterm index)
@ -169,100 +146,100 @@ bool TerminalDispatch::SetGraphicsRendition(const VTParameters options) noexcept
attr.SetOverlined(false);
break;
case ForegroundBlack:
attr.SetIndexedForeground(DARK_BLACK);
attr.SetIndexedForeground(TextColor::DARK_BLACK);
break;
case ForegroundBlue:
attr.SetIndexedForeground(DARK_BLUE);
attr.SetIndexedForeground(TextColor::DARK_BLUE);
break;
case ForegroundGreen:
attr.SetIndexedForeground(DARK_GREEN);
attr.SetIndexedForeground(TextColor::DARK_GREEN);
break;
case ForegroundCyan:
attr.SetIndexedForeground(DARK_CYAN);
attr.SetIndexedForeground(TextColor::DARK_CYAN);
break;
case ForegroundRed:
attr.SetIndexedForeground(DARK_RED);
attr.SetIndexedForeground(TextColor::DARK_RED);
break;
case ForegroundMagenta:
attr.SetIndexedForeground(DARK_MAGENTA);
attr.SetIndexedForeground(TextColor::DARK_MAGENTA);
break;
case ForegroundYellow:
attr.SetIndexedForeground(DARK_YELLOW);
attr.SetIndexedForeground(TextColor::DARK_YELLOW);
break;
case ForegroundWhite:
attr.SetIndexedForeground(DARK_WHITE);
attr.SetIndexedForeground(TextColor::DARK_WHITE);
break;
case BackgroundBlack:
attr.SetIndexedBackground(DARK_BLACK);
attr.SetIndexedBackground(TextColor::DARK_BLACK);
break;
case BackgroundBlue:
attr.SetIndexedBackground(DARK_BLUE);
attr.SetIndexedBackground(TextColor::DARK_BLUE);
break;
case BackgroundGreen:
attr.SetIndexedBackground(DARK_GREEN);
attr.SetIndexedBackground(TextColor::DARK_GREEN);
break;
case BackgroundCyan:
attr.SetIndexedBackground(DARK_CYAN);
attr.SetIndexedBackground(TextColor::DARK_CYAN);
break;
case BackgroundRed:
attr.SetIndexedBackground(DARK_RED);
attr.SetIndexedBackground(TextColor::DARK_RED);
break;
case BackgroundMagenta:
attr.SetIndexedBackground(DARK_MAGENTA);
attr.SetIndexedBackground(TextColor::DARK_MAGENTA);
break;
case BackgroundYellow:
attr.SetIndexedBackground(DARK_YELLOW);
attr.SetIndexedBackground(TextColor::DARK_YELLOW);
break;
case BackgroundWhite:
attr.SetIndexedBackground(DARK_WHITE);
attr.SetIndexedBackground(TextColor::DARK_WHITE);
break;
case BrightForegroundBlack:
attr.SetIndexedForeground(BRIGHT_BLACK);
attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
break;
case BrightForegroundBlue:
attr.SetIndexedForeground(BRIGHT_BLUE);
attr.SetIndexedForeground(TextColor::BRIGHT_BLUE);
break;
case BrightForegroundGreen:
attr.SetIndexedForeground(BRIGHT_GREEN);
attr.SetIndexedForeground(TextColor::BRIGHT_GREEN);
break;
case BrightForegroundCyan:
attr.SetIndexedForeground(BRIGHT_CYAN);
attr.SetIndexedForeground(TextColor::BRIGHT_CYAN);
break;
case BrightForegroundRed:
attr.SetIndexedForeground(BRIGHT_RED);
attr.SetIndexedForeground(TextColor::BRIGHT_RED);
break;
case BrightForegroundMagenta:
attr.SetIndexedForeground(BRIGHT_MAGENTA);
attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA);
break;
case BrightForegroundYellow:
attr.SetIndexedForeground(BRIGHT_YELLOW);
attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW);
break;
case BrightForegroundWhite:
attr.SetIndexedForeground(BRIGHT_WHITE);
attr.SetIndexedForeground(TextColor::BRIGHT_WHITE);
break;
case BrightBackgroundBlack:
attr.SetIndexedBackground(BRIGHT_BLACK);
attr.SetIndexedBackground(TextColor::BRIGHT_BLACK);
break;
case BrightBackgroundBlue:
attr.SetIndexedBackground(BRIGHT_BLUE);
attr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
break;
case BrightBackgroundGreen:
attr.SetIndexedBackground(BRIGHT_GREEN);
attr.SetIndexedBackground(TextColor::BRIGHT_GREEN);
break;
case BrightBackgroundCyan:
attr.SetIndexedBackground(BRIGHT_CYAN);
attr.SetIndexedBackground(TextColor::BRIGHT_CYAN);
break;
case BrightBackgroundRed:
attr.SetIndexedBackground(BRIGHT_RED);
attr.SetIndexedBackground(TextColor::BRIGHT_RED);
break;
case BrightBackgroundMagenta:
attr.SetIndexedBackground(BRIGHT_MAGENTA);
attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA);
break;
case BrightBackgroundYellow:
attr.SetIndexedBackground(BRIGHT_YELLOW);
attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
break;
case BrightBackgroundWhite:
attr.SetIndexedBackground(BRIGHT_WHITE);
attr.SetIndexedBackground(TextColor::BRIGHT_WHITE);
break;
case ForegroundExtended:
i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true);

View file

@ -86,8 +86,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(_profile, ForceFullRepaintRendering);
OBSERVABLE_PROJECTED_SETTING(_profile, SoftwareRendering);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Foreground);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Background);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), SelectionBackground);

View file

@ -53,8 +53,6 @@ namespace Microsoft.Terminal.Settings.Editor
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Commandline);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, StartingDirectory);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ForceFullRepaintRendering);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SoftwareRendering);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Foreground);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Background);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, SelectionBackground);

View file

@ -16,17 +16,6 @@ static constexpr std::string_view ForegroundKey{ "foreground" };
static constexpr std::string_view BackgroundKey{ "background" };
static constexpr std::string_view SelectionBackgroundKey{ "selectionBackground" };
static constexpr std::string_view CursorColorKey{ "cursorColor" };
static constexpr std::string_view CursorShapeKey{ "cursorShape" };
static constexpr std::string_view CursorHeightKey{ "cursorHeight" };
static constexpr std::string_view BackgroundImageKey{ "backgroundImage" };
static constexpr std::string_view ColorSchemeKey{ "colorScheme" };
static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" };
static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImageStretchMode" };
static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" };
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
static constexpr std::string_view PixelShaderPathKey{ "experimental.pixelShaderPath" };
static constexpr std::string_view IntenseTextStyleKey{ "intenseTextStyle" };
static constexpr std::string_view AdjustIndistinguishableColorsKey{ "adjustIndistinguishableColors" };
static constexpr std::string_view LegacyAcrylicTransparencyKey{ "acrylicOpacity" };
static constexpr std::string_view OpacityKey{ "opacity" };
@ -38,22 +27,17 @@ AppearanceConfig::AppearanceConfig(winrt::weak_ref<Profile> sourceProfile) :
winrt::com_ptr<AppearanceConfig> AppearanceConfig::CopyAppearance(const AppearanceConfig* source, winrt::weak_ref<Profile> sourceProfile)
{
auto appearance{ winrt::make_self<AppearanceConfig>(std::move(sourceProfile)) };
appearance->_BackgroundImagePath = source->_BackgroundImagePath;
appearance->_BackgroundImageOpacity = source->_BackgroundImageOpacity;
appearance->_BackgroundImageStretchMode = source->_BackgroundImageStretchMode;
appearance->_ColorSchemeName = source->_ColorSchemeName;
appearance->_Foreground = source->_Foreground;
appearance->_Background = source->_Background;
appearance->_SelectionBackground = source->_SelectionBackground;
appearance->_CursorColor = source->_CursorColor;
appearance->_CursorShape = source->_CursorShape;
appearance->_CursorHeight = source->_CursorHeight;
appearance->_BackgroundImageAlignment = source->_BackgroundImageAlignment;
appearance->_RetroTerminalEffect = source->_RetroTerminalEffect;
appearance->_PixelShaderPath = source->_PixelShaderPath;
appearance->_IntenseTextStyle = source->_IntenseTextStyle;
appearance->_Opacity = source->_Opacity;
appearance->_AdjustIndistinguishableColors = source->_AdjustIndistinguishableColors;
#define APPEARANCE_SETTINGS_COPY(type, name, jsonKey, ...) \
appearance->_##name = source->_##name;
MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_COPY)
#undef APPEARANCE_SETTINGS_COPY
return appearance;
}
@ -65,19 +49,13 @@ Json::Value AppearanceConfig::ToJson() const
JsonUtils::SetValueForKey(json, BackgroundKey, _Background);
JsonUtils::SetValueForKey(json, SelectionBackgroundKey, _SelectionBackground);
JsonUtils::SetValueForKey(json, CursorColorKey, _CursorColor);
JsonUtils::SetValueForKey(json, ColorSchemeKey, _ColorSchemeName);
JsonUtils::SetValueForKey(json, CursorHeightKey, _CursorHeight);
JsonUtils::SetValueForKey(json, CursorShapeKey, _CursorShape);
JsonUtils::SetValueForKey(json, BackgroundImageKey, _BackgroundImagePath);
JsonUtils::SetValueForKey(json, BackgroundImageOpacityKey, _BackgroundImageOpacity);
JsonUtils::SetValueForKey(json, BackgroundImageStretchModeKey, _BackgroundImageStretchMode);
JsonUtils::SetValueForKey(json, BackgroundImageAlignmentKey, _BackgroundImageAlignment);
JsonUtils::SetValueForKey(json, RetroTerminalEffectKey, _RetroTerminalEffect);
JsonUtils::SetValueForKey(json, PixelShaderPathKey, _PixelShaderPath);
JsonUtils::SetValueForKey(json, IntenseTextStyleKey, _IntenseTextStyle);
JsonUtils::SetValueForKey(json, AdjustIndistinguishableColorsKey, _AdjustIndistinguishableColors);
JsonUtils::SetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter<double, IntAsFloatPercentConversionTrait>{});
#define APPEARANCE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);
MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_TO_JSON)
#undef APPEARANCE_SETTINGS_TO_JSON
return json;
}
@ -98,19 +76,14 @@ void AppearanceConfig::LayerJson(const Json::Value& json)
JsonUtils::GetValueForKey(json, BackgroundKey, _Background);
JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _SelectionBackground);
JsonUtils::GetValueForKey(json, CursorColorKey, _CursorColor);
JsonUtils::GetValueForKey(json, CursorHeightKey, _CursorHeight);
JsonUtils::GetValueForKey(json, ColorSchemeKey, _ColorSchemeName);
JsonUtils::GetValueForKey(json, CursorShapeKey, _CursorShape);
JsonUtils::GetValueForKey(json, BackgroundImageKey, _BackgroundImagePath);
JsonUtils::GetValueForKey(json, BackgroundImageOpacityKey, _BackgroundImageOpacity);
JsonUtils::GetValueForKey(json, BackgroundImageStretchModeKey, _BackgroundImageStretchMode);
JsonUtils::GetValueForKey(json, BackgroundImageAlignmentKey, _BackgroundImageAlignment);
JsonUtils::GetValueForKey(json, RetroTerminalEffectKey, _RetroTerminalEffect);
JsonUtils::GetValueForKey(json, PixelShaderPathKey, _PixelShaderPath);
JsonUtils::GetValueForKey(json, IntenseTextStyleKey, _IntenseTextStyle);
JsonUtils::GetValueForKey(json, AdjustIndistinguishableColorsKey, _AdjustIndistinguishableColors);
JsonUtils::GetValueForKey(json, LegacyAcrylicTransparencyKey, _Opacity);
JsonUtils::GetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter<double, IntAsFloatPercentConversionTrait>{});
#define APPEARANCE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(json, jsonKey, _##name);
MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_LAYER_JSON)
#undef APPEARANCE_SETTINGS_LAYER_JSON
}
winrt::Microsoft::Terminal::Settings::Model::Profile AppearanceConfig::SourceProfile()

View file

@ -19,6 +19,7 @@ Author(s):
#include "AppearanceConfig.g.h"
#include "JsonUtils.h"
#include "IInheritable.h"
#include "MTSMSettings.h"
#include <DefaultSettings.h>
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
@ -35,26 +36,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ExpandedBackgroundImagePath();
INHERITABLE_SETTING(Model::IAppearanceConfig, ConvergedAlignment, BackgroundImageAlignment, ConvergedAlignment::Horizontal_Center | ConvergedAlignment::Vertical_Center);
INHERITABLE_SETTING(Model::IAppearanceConfig, uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, ColorSchemeName, L"Campbell");
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, Foreground, nullptr);
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, Background, nullptr);
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, SelectionBackground, nullptr);
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, CursorColor, nullptr);
INHERITABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::CursorStyle, CursorShape, Microsoft::Terminal::Core::CursorStyle::Bar);
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, BackgroundImagePath);
INHERITABLE_SETTING(Model::IAppearanceConfig, double, BackgroundImageOpacity, 1.0);
INHERITABLE_SETTING(Model::IAppearanceConfig, Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::UniformToFill);
INHERITABLE_SETTING(Model::IAppearanceConfig, bool, RetroTerminalEffect, false);
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, PixelShaderPath, L"");
INHERITABLE_SETTING(Model::IAppearanceConfig, Model::IntenseStyle, IntenseTextStyle, Model::IntenseStyle::Bright);
INHERITABLE_SETTING(Model::IAppearanceConfig, double, Opacity, 1.0);
INHERITABLE_SETTING(Model::IAppearanceConfig, bool, AdjustIndistinguishableColors, true);
#define APPEARANCE_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
INHERITABLE_SETTING(Model::IAppearanceConfig, type, name, ##__VA_ARGS__)
MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_INITIALIZE)
#undef APPEARANCE_SETTINGS_INITIALIZE
private:
winrt::weak_ref<Profile> _sourceProfile;

View file

@ -287,8 +287,6 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source)
DUPLICATE_SETTING_MACRO(Commandline);
DUPLICATE_SETTING_MACRO(StartingDirectory);
DUPLICATE_SETTING_MACRO(AntialiasingMode);
DUPLICATE_SETTING_MACRO(ForceFullRepaintRendering);
DUPLICATE_SETTING_MACRO(SoftwareRendering);
DUPLICATE_SETTING_MACRO(HistorySize);
DUPLICATE_SETTING_MACRO(SnapOnInput);
DUPLICATE_SETTING_MACRO(AltGrAliasing);

View file

@ -12,11 +12,6 @@ using namespace Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
static constexpr std::string_view FontInfoKey{ "font" };
static constexpr std::string_view FontFaceKey{ "face" };
static constexpr std::string_view FontSizeKey{ "size" };
static constexpr std::string_view FontWeightKey{ "weight" };
static constexpr std::string_view FontFeaturesKey{ "features" };
static constexpr std::string_view FontAxesKey{ "axes" };
static constexpr std::string_view LegacyFontFaceKey{ "fontFace" };
static constexpr std::string_view LegacyFontSizeKey{ "fontSize" };
static constexpr std::string_view LegacyFontWeightKey{ "fontWeight" };
@ -29,11 +24,12 @@ winrt::Microsoft::Terminal::Settings::Model::implementation::FontConfig::FontCon
winrt::com_ptr<FontConfig> FontConfig::CopyFontInfo(const FontConfig* source, winrt::weak_ref<Profile> sourceProfile)
{
auto fontInfo{ winrt::make_self<FontConfig>(std::move(sourceProfile)) };
fontInfo->_FontFace = source->_FontFace;
fontInfo->_FontSize = source->_FontSize;
fontInfo->_FontWeight = source->_FontWeight;
fontInfo->_FontAxes = source->_FontAxes;
fontInfo->_FontFeatures = source->_FontFeatures;
#define FONT_SETTINGS_COPY(type, name, jsonKey, ...) \
fontInfo->_##name = source->_##name;
MTSM_FONT_SETTINGS(FONT_SETTINGS_COPY)
#undef FONT_SETTINGS_COPY
return fontInfo;
}
@ -41,11 +37,10 @@ Json::Value FontConfig::ToJson() const
{
Json::Value json{ Json::ValueType::objectValue };
JsonUtils::SetValueForKey(json, FontFaceKey, _FontFace);
JsonUtils::SetValueForKey(json, FontSizeKey, _FontSize);
JsonUtils::SetValueForKey(json, FontWeightKey, _FontWeight);
JsonUtils::SetValueForKey(json, FontAxesKey, _FontAxes);
JsonUtils::SetValueForKey(json, FontFeaturesKey, _FontFeatures);
#define FONT_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);
MTSM_FONT_SETTINGS(FONT_SETTINGS_TO_JSON)
#undef FONT_SETTINGS_TO_JSON
return json;
}
@ -69,11 +64,10 @@ void FontConfig::LayerJson(const Json::Value& json)
{
// A font object is defined, use that
const auto fontInfoJson = json[JsonKey(FontInfoKey)];
JsonUtils::GetValueForKey(fontInfoJson, FontFaceKey, _FontFace);
JsonUtils::GetValueForKey(fontInfoJson, FontSizeKey, _FontSize);
JsonUtils::GetValueForKey(fontInfoJson, FontWeightKey, _FontWeight);
JsonUtils::GetValueForKey(fontInfoJson, FontFeaturesKey, _FontFeatures);
JsonUtils::GetValueForKey(fontInfoJson, FontAxesKey, _FontAxes);
#define FONT_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(fontInfoJson, jsonKey, _##name);
MTSM_FONT_SETTINGS(FONT_SETTINGS_LAYER_JSON)
#undef FONT_SETTINGS_LAYER_JSON
}
else
{

View file

@ -19,6 +19,7 @@ Author(s):
#include "pch.h"
#include "FontConfig.g.h"
#include "JsonUtils.h"
#include "MTSMSettings.h"
#include "../inc/cppwinrt_utils.h"
#include "IInheritable.h"
#include <DefaultSettings.h>
@ -39,11 +40,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Model::Profile SourceProfile();
INHERITABLE_SETTING(Model::FontConfig, hstring, FontFace, DEFAULT_FONT_FACE);
INHERITABLE_SETTING(Model::FontConfig, int32_t, FontSize, DEFAULT_FONT_SIZE);
INHERITABLE_SETTING(Model::FontConfig, Windows::UI::Text::FontWeight, FontWeight, DEFAULT_FONT_WEIGHT);
INHERITABLE_SETTING(Model::FontConfig, IFontAxesMap, FontAxes);
INHERITABLE_SETTING(Model::FontConfig, IFontFeatureMap, FontFeatures);
#define FONT_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
INHERITABLE_SETTING(Model::FontConfig, type, name, ##__VA_ARGS__)
MTSM_FONT_SETTINGS(FONT_SETTINGS_INITIALIZE)
#undef FONT_SETTINGS_INITIALIZE
private:
winrt::weak_ref<Profile> _sourceProfile;

View file

@ -18,48 +18,7 @@ using namespace winrt::Microsoft::UI::Xaml::Controls;
static constexpr std::string_view LegacyKeybindingsKey{ "keybindings" };
static constexpr std::string_view ActionsKey{ "actions" };
static constexpr std::string_view DefaultProfileKey{ "defaultProfile" };
static constexpr std::string_view AlwaysShowTabsKey{ "alwaysShowTabs" };
static constexpr std::string_view InitialRowsKey{ "initialRows" };
static constexpr std::string_view InitialColsKey{ "initialCols" };
static constexpr std::string_view InitialPositionKey{ "initialPosition" };
static constexpr std::string_view CenterOnLaunchKey{ "centerOnLaunch" };
static constexpr std::string_view ShowTitleInTitlebarKey{ "showTerminalTitleInTitlebar" };
static constexpr std::string_view LanguageKey{ "language" };
static constexpr std::string_view ThemeKey{ "theme" };
static constexpr std::string_view TabWidthModeKey{ "tabWidthMode" };
static constexpr std::string_view UseAcrylicInTabRowKey{ "useAcrylicInTabRow" };
static constexpr std::string_view ShowTabsInTitlebarKey{ "showTabsInTitlebar" };
static constexpr std::string_view WordDelimitersKey{ "wordDelimiters" };
static constexpr std::string_view InputServiceWarningKey{ "inputServiceWarning" };
static constexpr std::string_view CopyOnSelectKey{ "copyOnSelect" };
static constexpr std::string_view CopyFormattingKey{ "copyFormatting" };
static constexpr std::string_view WarnAboutLargePasteKey{ "largePasteWarning" };
static constexpr std::string_view WarnAboutMultiLinePasteKey{ "multiLinePasteWarning" };
static constexpr std::string_view TrimPasteKey{ "trimPaste" };
static constexpr std::string_view LaunchModeKey{ "launchMode" };
static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" };
static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" };
static constexpr std::string_view EnableStartupTaskKey{ "startOnUserLogin" };
static constexpr std::string_view FirstWindowPreferenceKey{ "firstWindowPreference" };
static constexpr std::string_view AlwaysOnTopKey{ "alwaysOnTop" };
static constexpr std::string_view LegacyUseTabSwitcherModeKey{ "useTabSwitcher" };
static constexpr std::string_view TabSwitcherModeKey{ "tabSwitcherMode" };
static constexpr std::string_view DisableAnimationsKey{ "disableAnimations" };
static constexpr std::string_view StartupActionsKey{ "startupActions" };
static constexpr std::string_view FocusFollowMouseKey{ "focusFollowMouse" };
static constexpr std::string_view WindowingBehaviorKey{ "windowingBehavior" };
static constexpr std::string_view TrimBlockSelectionKey{ "trimBlockSelection" };
static constexpr std::string_view AlwaysShowNotificationIconKey{ "alwaysShowNotificationIcon" };
static constexpr std::string_view MinimizeToNotificationAreaKey{ "minimizeToNotificationArea" };
static constexpr std::string_view DisabledProfileSourcesKey{ "disabledProfileSources" };
static constexpr std::string_view ShowAdminShieldKey{ "showAdminShield" };
static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" };
static constexpr std::string_view ForceFullRepaintRenderingKey{ "experimental.rendering.forceFullRepaint" };
static constexpr std::string_view SoftwareRenderingKey{ "experimental.rendering.software" };
static constexpr std::string_view ForceVTInputKey{ "experimental.input.forceVT" };
static constexpr std::string_view DetectURLsKey{ "experimental.detectURLs" };
// Method Description:
// - Copies any extraneous data from the parent before completing a CreateChild call
@ -86,45 +45,6 @@ void GlobalAppSettings::_FinalizeInheritance()
winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
{
auto globals{ winrt::make_self<GlobalAppSettings>() };
globals->_InitialRows = _InitialRows;
globals->_InitialCols = _InitialCols;
globals->_AlwaysShowTabs = _AlwaysShowTabs;
globals->_ShowTitleInTitlebar = _ShowTitleInTitlebar;
globals->_ConfirmCloseAllTabs = _ConfirmCloseAllTabs;
globals->_Language = _Language;
globals->_Theme = _Theme;
globals->_TabWidthMode = _TabWidthMode;
globals->_UseAcrylicInTabRow = _UseAcrylicInTabRow;
globals->_ShowTabsInTitlebar = _ShowTabsInTitlebar;
globals->_WordDelimiters = _WordDelimiters;
globals->_InputServiceWarning = _InputServiceWarning;
globals->_CopyOnSelect = _CopyOnSelect;
globals->_CopyFormatting = _CopyFormatting;
globals->_WarnAboutLargePaste = _WarnAboutLargePaste;
globals->_WarnAboutMultiLinePaste = _WarnAboutMultiLinePaste;
globals->_TrimPaste = _TrimPaste;
globals->_InitialPosition = _InitialPosition;
globals->_CenterOnLaunch = _CenterOnLaunch;
globals->_LaunchMode = _LaunchMode;
globals->_SnapToGridOnResize = _SnapToGridOnResize;
globals->_ForceFullRepaintRendering = _ForceFullRepaintRendering;
globals->_SoftwareRendering = _SoftwareRendering;
globals->_ForceVTInput = _ForceVTInput;
globals->_DebugFeaturesEnabled = _DebugFeaturesEnabled;
globals->_StartOnUserLogin = _StartOnUserLogin;
globals->_FirstWindowPreference = _FirstWindowPreference;
globals->_AlwaysOnTop = _AlwaysOnTop;
globals->_TabSwitcherMode = _TabSwitcherMode;
globals->_DisableAnimations = _DisableAnimations;
globals->_StartupActions = _StartupActions;
globals->_FocusFollowMouse = _FocusFollowMouse;
globals->_WindowingBehavior = _WindowingBehavior;
globals->_TrimBlockSelection = _TrimBlockSelection;
globals->_DetectURLs = _DetectURLs;
globals->_MinimizeToNotificationArea = _MinimizeToNotificationArea;
globals->_AlwaysShowNotificationIcon = _AlwaysShowNotificationIcon;
globals->_DisabledProfileSources = _DisabledProfileSources;
globals->_ShowAdminShield = _ShowAdminShield;
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
@ -132,6 +52,11 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
globals->_actionMap = _actionMap->Copy();
globals->_keybindingsWarnings = _keybindingsWarnings;
#define GLOBAL_SETTINGS_COPY(type, name, jsonKey, ...) \
globals->_##name = _##name;
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_COPY)
#undef GLOBAL_SETTINGS_COPY
if (_colorSchemes)
{
for (auto kv : _colorSchemes)
@ -189,51 +114,15 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::FromJson(const Json::Value&
void GlobalAppSettings::LayerJson(const Json::Value& json)
{
JsonUtils::GetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
JsonUtils::GetValueForKey(json, AlwaysShowTabsKey, _AlwaysShowTabs);
JsonUtils::GetValueForKey(json, ConfirmCloseAllKey, _ConfirmCloseAllTabs);
JsonUtils::GetValueForKey(json, InitialRowsKey, _InitialRows);
JsonUtils::GetValueForKey(json, InitialColsKey, _InitialCols);
JsonUtils::GetValueForKey(json, InitialPositionKey, _InitialPosition);
JsonUtils::GetValueForKey(json, CenterOnLaunchKey, _CenterOnLaunch);
JsonUtils::GetValueForKey(json, ShowTitleInTitlebarKey, _ShowTitleInTitlebar);
JsonUtils::GetValueForKey(json, ShowTabsInTitlebarKey, _ShowTabsInTitlebar);
JsonUtils::GetValueForKey(json, WordDelimitersKey, _WordDelimiters);
JsonUtils::GetValueForKey(json, CopyOnSelectKey, _CopyOnSelect);
JsonUtils::GetValueForKey(json, InputServiceWarningKey, _InputServiceWarning);
JsonUtils::GetValueForKey(json, CopyFormattingKey, _CopyFormatting);
JsonUtils::GetValueForKey(json, WarnAboutLargePasteKey, _WarnAboutLargePaste);
JsonUtils::GetValueForKey(json, WarnAboutMultiLinePasteKey, _WarnAboutMultiLinePaste);
JsonUtils::GetValueForKey(json, TrimPasteKey, _TrimPaste);
JsonUtils::GetValueForKey(json, FirstWindowPreferenceKey, _FirstWindowPreference);
JsonUtils::GetValueForKey(json, LaunchModeKey, _LaunchMode);
JsonUtils::GetValueForKey(json, LanguageKey, _Language);
JsonUtils::GetValueForKey(json, ThemeKey, _Theme);
JsonUtils::GetValueForKey(json, TabWidthModeKey, _TabWidthMode);
JsonUtils::GetValueForKey(json, UseAcrylicInTabRowKey, _UseAcrylicInTabRow);
JsonUtils::GetValueForKey(json, SnapToGridOnResizeKey, _SnapToGridOnResize);
// GetValueForKey will only override the current value if the key exists
JsonUtils::GetValueForKey(json, DebugFeaturesKey, _DebugFeaturesEnabled);
JsonUtils::GetValueForKey(json, ForceFullRepaintRenderingKey, _ForceFullRepaintRendering);
JsonUtils::GetValueForKey(json, SoftwareRenderingKey, _SoftwareRendering);
JsonUtils::GetValueForKey(json, ForceVTInputKey, _ForceVTInput);
JsonUtils::GetValueForKey(json, EnableStartupTaskKey, _StartOnUserLogin);
JsonUtils::GetValueForKey(json, AlwaysOnTopKey, _AlwaysOnTop);
// GH#8076 - when adding enum values to this key, we also changed it from
// "useTabSwitcher" to "tabSwitcherMode". Continue supporting
// "useTabSwitcher", but prefer "tabSwitcherMode"
JsonUtils::GetValueForKey(json, LegacyUseTabSwitcherModeKey, _TabSwitcherMode);
JsonUtils::GetValueForKey(json, TabSwitcherModeKey, _TabSwitcherMode);
JsonUtils::GetValueForKey(json, DisableAnimationsKey, _DisableAnimations);
JsonUtils::GetValueForKey(json, StartupActionsKey, _StartupActions);
JsonUtils::GetValueForKey(json, FocusFollowMouseKey, _FocusFollowMouse);
JsonUtils::GetValueForKey(json, WindowingBehaviorKey, _WindowingBehavior);
JsonUtils::GetValueForKey(json, TrimBlockSelectionKey, _TrimBlockSelection);
JsonUtils::GetValueForKey(json, DetectURLsKey, _DetectURLs);
JsonUtils::GetValueForKey(json, MinimizeToNotificationAreaKey, _MinimizeToNotificationArea);
JsonUtils::GetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
JsonUtils::GetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
JsonUtils::GetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield);
#define GLOBAL_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(json, jsonKey, _##name);
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_LAYER_JSON)
#undef GLOBAL_SETTINGS_LAYER_JSON
static constexpr std::array bindingsKeys{ LegacyKeybindingsKey, ActionsKey };
for (const auto& jsonKey : bindingsKeys)
@ -293,48 +182,12 @@ Json::Value GlobalAppSettings::ToJson() const
{
Json::Value json{ Json::ValueType::objectValue };
// clang-format off
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
JsonUtils::SetValueForKey(json, AlwaysShowTabsKey, _AlwaysShowTabs);
JsonUtils::SetValueForKey(json, ConfirmCloseAllKey, _ConfirmCloseAllTabs);
JsonUtils::SetValueForKey(json, InitialRowsKey, _InitialRows);
JsonUtils::SetValueForKey(json, InitialColsKey, _InitialCols);
JsonUtils::SetValueForKey(json, InitialPositionKey, _InitialPosition);
JsonUtils::SetValueForKey(json, CenterOnLaunchKey, _CenterOnLaunch);
JsonUtils::SetValueForKey(json, ShowTitleInTitlebarKey, _ShowTitleInTitlebar);
JsonUtils::SetValueForKey(json, ShowTabsInTitlebarKey, _ShowTabsInTitlebar);
JsonUtils::SetValueForKey(json, WordDelimitersKey, _WordDelimiters);
JsonUtils::SetValueForKey(json, InputServiceWarningKey, _InputServiceWarning);
JsonUtils::SetValueForKey(json, CopyOnSelectKey, _CopyOnSelect);
JsonUtils::SetValueForKey(json, CopyFormattingKey, _CopyFormatting);
JsonUtils::SetValueForKey(json, WarnAboutLargePasteKey, _WarnAboutLargePaste);
JsonUtils::SetValueForKey(json, WarnAboutMultiLinePasteKey, _WarnAboutMultiLinePaste);
JsonUtils::SetValueForKey(json, TrimPasteKey, _TrimPaste);
JsonUtils::SetValueForKey(json, FirstWindowPreferenceKey, _FirstWindowPreference);
JsonUtils::SetValueForKey(json, LaunchModeKey, _LaunchMode);
JsonUtils::SetValueForKey(json, LanguageKey, _Language);
JsonUtils::SetValueForKey(json, ThemeKey, _Theme);
JsonUtils::SetValueForKey(json, TabWidthModeKey, _TabWidthMode);
JsonUtils::SetValueForKey(json, UseAcrylicInTabRowKey, _UseAcrylicInTabRow);
JsonUtils::SetValueForKey(json, SnapToGridOnResizeKey, _SnapToGridOnResize);
JsonUtils::SetValueForKey(json, DebugFeaturesKey, _DebugFeaturesEnabled);
JsonUtils::SetValueForKey(json, ForceFullRepaintRenderingKey, _ForceFullRepaintRendering);
JsonUtils::SetValueForKey(json, SoftwareRenderingKey, _SoftwareRendering);
JsonUtils::SetValueForKey(json, ForceVTInputKey, _ForceVTInput);
JsonUtils::SetValueForKey(json, EnableStartupTaskKey, _StartOnUserLogin);
JsonUtils::SetValueForKey(json, AlwaysOnTopKey, _AlwaysOnTop);
JsonUtils::SetValueForKey(json, TabSwitcherModeKey, _TabSwitcherMode);
JsonUtils::SetValueForKey(json, DisableAnimationsKey, _DisableAnimations);
JsonUtils::SetValueForKey(json, StartupActionsKey, _StartupActions);
JsonUtils::SetValueForKey(json, FocusFollowMouseKey, _FocusFollowMouse);
JsonUtils::SetValueForKey(json, WindowingBehaviorKey, _WindowingBehavior);
JsonUtils::SetValueForKey(json, TrimBlockSelectionKey, _TrimBlockSelection);
JsonUtils::SetValueForKey(json, DetectURLsKey, _DetectURLs);
JsonUtils::SetValueForKey(json, MinimizeToNotificationAreaKey, _MinimizeToNotificationArea);
JsonUtils::SetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
JsonUtils::SetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
JsonUtils::SetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield);
// clang-format on
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
#define GLOBAL_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_TO_JSON)
#undef GLOBAL_SETTINGS_TO_JSON
json[JsonKey(ActionsKey)] = _actionMap->ToJson();
return json;

View file

@ -17,6 +17,7 @@ Author(s):
#include "GlobalAppSettings.g.h"
#include "IInheritable.h"
#include "MTSMSettings.h"
#include "ActionMap.h"
#include "Command.h"
@ -61,46 +62,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
DisableAnimations(!invertedDisableAnimationsValue);
}
INHERITABLE_SETTING(Model::GlobalAppSettings, int32_t, InitialRows, DEFAULT_ROWS);
INHERITABLE_SETTING(Model::GlobalAppSettings, int32_t, InitialCols, DEFAULT_COLS);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowTabs, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowTitleInTitlebar, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ConfirmCloseAllTabs, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, Language);
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Windows::UI::Xaml::ElementTheme, Theme, winrt::Windows::UI::Xaml::ElementTheme::Default);
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, UseAcrylicInTabRow, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowTabsInTitlebar, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, CopyOnSelect, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, InputServiceWarning, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, 0);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, WarnAboutLargePaste, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, WarnAboutMultiLinePaste, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, TrimPaste, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, Model::LaunchPosition, InitialPosition, nullptr, nullptr);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, CenterOnLaunch, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, Model::FirstWindowPreference, FirstWindowPreference, FirstWindowPreference::DefaultProfile);
INHERITABLE_SETTING(Model::GlobalAppSettings, Model::LaunchMode, LaunchMode, LaunchMode::DefaultMode);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, SnapToGridOnResize, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ForceFullRepaintRendering, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, SoftwareRendering, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ForceVTInput, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, DebugFeaturesEnabled, debugFeaturesDefault);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, StartOnUserLogin, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysOnTop, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, Model::TabSwitcherMode, TabSwitcherMode, Model::TabSwitcherMode::InOrder);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, DisableAnimations, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, StartupActions, L"");
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, FocusFollowMouse, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, Model::WindowingMode, WindowingBehavior, Model::WindowingMode::UseNew);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, TrimBlockSelection, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, DetectURLs, true);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, MinimizeToNotificationArea, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowNotificationIcon, false);
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, nullptr);
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowAdminShield, true);
#define GLOBAL_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
INHERITABLE_SETTING(Model::GlobalAppSettings, type, name, ##__VA_ARGS__)
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_INITIALIZE)
#undef GLOBAL_SETTINGS_INITIALIZE
private:
#ifdef NDEBUG

View file

@ -0,0 +1,96 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- MTSMSettings.h
Abstract:
- Contains most of the settings within Terminal Settings Model (global, profile, font, appearance)
- To add a new setting to any one of those classes, simply add it to the respective list below, following the macro format
Author(s):
- Pankaj Bhojwani - October 2021
--*/
#pragma once
// Macro format (defaultArgs are optional):
// (type, name, jsonKey, defaultArgs)
#define MTSM_GLOBAL_SETTINGS(X) \
X(int32_t, InitialRows, "initialRows", 30) \
X(int32_t, InitialCols, "initialCols", 80) \
X(hstring, WordDelimiters, "wordDelimiters", DEFAULT_WORD_DELIMITERS) \
X(bool, CopyOnSelect, "copyOnSelect", false) \
X(bool, FocusFollowMouse, "focusFollowMouse", false) \
X(bool, ForceFullRepaintRendering, "experimental.rendering.forceFullRepaint", false) \
X(bool, SoftwareRendering, "experimental.rendering.software", false) \
X(bool, ForceVTInput, "experimental.input.forceVT", false) \
X(bool, TrimBlockSelection, "trimBlockSelection", false) \
X(bool, DetectURLs, "experimental.detectURLs", true) \
X(bool, AlwaysShowTabs, "alwaysShowTabs", true) \
X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \
X(bool, ConfirmCloseAllTabs, "confirmCloseAllTabs", true) \
X(hstring, Language, "language") \
X(winrt::Windows::UI::Xaml::ElementTheme, Theme, "theme", winrt::Windows::UI::Xaml::ElementTheme::Default) \
X(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, "tabWidthMode", winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal) \
X(bool, UseAcrylicInTabRow, "useAcrylicInTabRow", false) \
X(bool, ShowTabsInTitlebar, "showTabsInTitlebar", true) \
X(bool, InputServiceWarning, "inputServiceWarning", true) \
X(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, "copyFormatting", 0) \
X(bool, WarnAboutLargePaste, "largePasteWarning", true) \
X(bool, WarnAboutMultiLinePaste, "multiLinePasteWarning", true) \
X(Model::LaunchPosition, InitialPosition, "initialPosition", nullptr, nullptr) \
X(bool, CenterOnLaunch, "centerOnLaunch", false) \
X(Model::FirstWindowPreference, FirstWindowPreference, "firstWindowPreference", FirstWindowPreference::DefaultProfile) \
X(Model::LaunchMode, LaunchMode, "launchMode", LaunchMode::DefaultMode) \
X(bool, SnapToGridOnResize, "snapToGridOnResize", true) \
X(bool, DebugFeaturesEnabled, "debugFeatures", debugFeaturesDefault) \
X(bool, StartOnUserLogin, "startOnUserLogin", false) \
X(bool, AlwaysOnTop, "alwaysOnTop", false) \
X(Model::TabSwitcherMode, TabSwitcherMode, "tabSwitcherMode", Model::TabSwitcherMode::InOrder) \
X(bool, DisableAnimations, "disableAnimations", false) \
X(hstring, StartupActions, "startupActions", L"") \
X(Model::WindowingMode, WindowingBehavior, "windowingBehavior", Model::WindowingMode::UseNew) \
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
X(bool, ShowAdminShield, "showAdminShield", true) \
X(bool, TrimPaste, "trimPaste", true)
#define MTSM_PROFILE_SETTINGS(X) \
X(int32_t, HistorySize, "historySize", DEFAULT_HISTORY_SIZE) \
X(bool, SnapOnInput, "snapOnInput", true) \
X(bool, AltGrAliasing, "altGrAliasing", true) \
X(bool, UseAcrylic, "useAcrylic", false) \
X(hstring, Commandline, "commandline", L"%SystemRoot%\\System32\\cmd.exe") \
X(Microsoft::Terminal::Control::ScrollbarState, ScrollState, "scrollbarState", Microsoft::Terminal::Control::ScrollbarState::Visible) \
X(Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode, "antialiasingMode", Microsoft::Terminal::Control::TextAntialiasingMode::Grayscale) \
X(hstring, StartingDirectory, "startingDirectory") \
X(bool, SuppressApplicationTitle, "suppressApplicationTitle", false) \
X(guid, ConnectionType, "connectionType") \
X(hstring, Icon, "icon", L"\uE756") \
X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Graceful) \
X(hstring, TabTitle, "tabTitle") \
X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible)
#define MTSM_FONT_SETTINGS(X) \
X(hstring, FontFace, "face", DEFAULT_FONT_FACE) \
X(int32_t, FontSize, "size", DEFAULT_FONT_SIZE) \
X(winrt::Windows::UI::Text::FontWeight, FontWeight, "weight", DEFAULT_FONT_WEIGHT) \
X(IFontAxesMap, FontAxes, "axes") \
X(IFontFeatureMap, FontFeatures, "features")
#define MTSM_APPEARANCE_SETTINGS(X) \
X(Core::CursorStyle, CursorShape, "cursorShape", Core::CursorStyle::Bar) \
X(uint32_t, CursorHeight, "cursorHeight", DEFAULT_CURSOR_HEIGHT) \
X(double, BackgroundImageOpacity, "backgroundImageOpacity", 1.0) \
X(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, "backgroundImageStretchMode", winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill) \
X(bool, RetroTerminalEffect, "experimental.retroTerminalEffect", false) \
X(hstring, PixelShaderPath, "experimental.pixelShaderPath") \
X(ConvergedAlignment, BackgroundImageAlignment, "backgroundImageAlignment", ConvergedAlignment::Horizontal_Center | ConvergedAlignment::Vertical_Center) \
X(hstring, ColorSchemeName, "colorScheme", L"Campbell") \
X(hstring, BackgroundImagePath, "backgroundImage") \
X(Model::IntenseStyle, IntenseTextStyle, "intenseTextStyle", Model::IntenseStyle::Bright) \
X(bool, AdjustIndistinguishableColors, "adjustIndistinguishableColors", true)

View file

@ -50,6 +50,7 @@
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
</ClInclude>
<ClInclude Include="IInheritable.h" />
<ClInclude Include="MTSMSettings.h" />
<ClInclude Include="IDynamicProfileGenerator.h" />
<ClInclude Include="JsonUtils.h" />
<ClInclude Include="HashUtils.h" />

View file

@ -76,6 +76,7 @@
<Filter>json</Filter>
</ClInclude>
<ClInclude Include="IInheritable.h" />
<ClInclude Include="MTSMSettings.h" />
<ClInclude Include="IconPathConverter.h" />
<ClInclude Include="DefaultTerminal.h" />
<ClInclude Include="FileUtils.h" />

View file

@ -26,24 +26,9 @@ static constexpr std::string_view GuidKey{ "guid" };
static constexpr std::string_view SourceKey{ "source" };
static constexpr std::string_view HiddenKey{ "hidden" };
static constexpr std::string_view TabTitleKey{ "tabTitle" };
static constexpr std::string_view SuppressApplicationTitleKey{ "suppressApplicationTitle" };
static constexpr std::string_view HistorySizeKey{ "historySize" };
static constexpr std::string_view SnapOnInputKey{ "snapOnInput" };
static constexpr std::string_view AltGrAliasingKey{ "altGrAliasing" };
static constexpr std::string_view ConnectionTypeKey{ "connectionType" };
static constexpr std::string_view CommandlineKey{ "commandline" };
static constexpr std::string_view FontInfoKey{ "font" };
static constexpr std::string_view UseAcrylicKey{ "useAcrylic" };
static constexpr std::string_view ScrollbarStateKey{ "scrollbarState" };
static constexpr std::string_view CloseOnExitKey{ "closeOnExit" };
static constexpr std::string_view PaddingKey{ "padding" };
static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" };
static constexpr std::string_view IconKey{ "icon" };
static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" };
static constexpr std::string_view TabColorKey{ "tabColor" };
static constexpr std::string_view BellStyleKey{ "bellStyle" };
static constexpr std::string_view UnfocusedAppearanceKey{ "unfocusedAppearance" };
Profile::Profile(guid guid) noexcept :
@ -117,28 +102,17 @@ winrt::com_ptr<Profile> Profile::CopySettings() const
profile->_Name = _Name;
profile->_Source = _Source;
profile->_Hidden = _Hidden;
profile->_Icon = _Icon;
profile->_CloseOnExit = _CloseOnExit;
profile->_TabTitle = _TabTitle;
profile->_TabColor = _TabColor;
profile->_SuppressApplicationTitle = _SuppressApplicationTitle;
profile->_UseAcrylic = _UseAcrylic;
profile->_ScrollState = _ScrollState;
profile->_Padding = _Padding;
profile->_Commandline = _Commandline;
profile->_StartingDirectory = _StartingDirectory;
profile->_AntialiasingMode = _AntialiasingMode;
profile->_ForceFullRepaintRendering = _ForceFullRepaintRendering;
profile->_SoftwareRendering = _SoftwareRendering;
profile->_HistorySize = _HistorySize;
profile->_SnapOnInput = _SnapOnInput;
profile->_AltGrAliasing = _AltGrAliasing;
profile->_BellStyle = _BellStyle;
profile->_ConnectionType = _ConnectionType;
profile->_Origin = _Origin;
profile->_FontInfo = *fontInfo;
profile->_DefaultAppearance = *defaultAppearance;
#define PROFILE_SETTINGS_COPY(type, name, jsonKey, ...) \
profile->_##name = _##name;
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_COPY)
#undef PROFILE_SETTINGS_COPY
if (_UnfocusedAppearance)
{
Model::AppearanceConfig unfocused{ nullptr };
@ -196,31 +170,16 @@ void Profile::LayerJson(const Json::Value& json)
JsonUtils::GetValueForKey(json, HiddenKey, _Hidden);
JsonUtils::GetValueForKey(json, SourceKey, _Source);
// TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback"
JsonUtils::GetValueForKey(json, HistorySizeKey, _HistorySize);
JsonUtils::GetValueForKey(json, SnapOnInputKey, _SnapOnInput);
JsonUtils::GetValueForKey(json, AltGrAliasingKey, _AltGrAliasing);
JsonUtils::GetValueForKey(json, TabTitleKey, _TabTitle);
// Control Settings
JsonUtils::GetValueForKey(json, ConnectionTypeKey, _ConnectionType);
JsonUtils::GetValueForKey(json, CommandlineKey, _Commandline);
JsonUtils::GetValueForKey(json, UseAcrylicKey, _UseAcrylic);
JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, _SuppressApplicationTitle);
JsonUtils::GetValueForKey(json, CloseOnExitKey, _CloseOnExit);
// Padding was never specified as an integer, but it was a common working mistake.
// Allow it to be permissive.
JsonUtils::GetValueForKey(json, PaddingKey, _Padding, JsonUtils::OptionalConverter<hstring, JsonUtils::PermissiveStringConverter<std::wstring>>{});
JsonUtils::GetValueForKey(json, ScrollbarStateKey, _ScrollState);
JsonUtils::GetValueForKey(json, StartingDirectoryKey, _StartingDirectory);
JsonUtils::GetValueForKey(json, IconKey, _Icon);
JsonUtils::GetValueForKey(json, AntialiasingModeKey, _AntialiasingMode);
JsonUtils::GetValueForKey(json, TabColorKey, _TabColor);
JsonUtils::GetValueForKey(json, BellStyleKey, _BellStyle);
#define PROFILE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(json, jsonKey, _##name);
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_LAYER_JSON)
#undef PROFILE_SETTINGS_LAYER_JSON
if (json.isMember(JsonKey(UnfocusedAppearanceKey)))
{
@ -352,28 +311,15 @@ Json::Value Profile::ToJson() const
JsonUtils::SetValueForKey(json, HiddenKey, writeBasicSettings ? Hidden() : _Hidden);
JsonUtils::SetValueForKey(json, SourceKey, writeBasicSettings ? Source() : _Source);
// TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback"
JsonUtils::SetValueForKey(json, HistorySizeKey, _HistorySize);
JsonUtils::SetValueForKey(json, SnapOnInputKey, _SnapOnInput);
JsonUtils::SetValueForKey(json, AltGrAliasingKey, _AltGrAliasing);
JsonUtils::SetValueForKey(json, TabTitleKey, _TabTitle);
// Control Settings
JsonUtils::SetValueForKey(json, ConnectionTypeKey, _ConnectionType);
JsonUtils::SetValueForKey(json, CommandlineKey, _Commandline);
JsonUtils::SetValueForKey(json, UseAcrylicKey, _UseAcrylic);
JsonUtils::SetValueForKey(json, SuppressApplicationTitleKey, _SuppressApplicationTitle);
JsonUtils::SetValueForKey(json, CloseOnExitKey, _CloseOnExit);
// PermissiveStringConverter is unnecessary for serialization
JsonUtils::SetValueForKey(json, PaddingKey, _Padding);
JsonUtils::SetValueForKey(json, ScrollbarStateKey, _ScrollState);
JsonUtils::SetValueForKey(json, StartingDirectoryKey, _StartingDirectory);
JsonUtils::SetValueForKey(json, IconKey, _Icon);
JsonUtils::SetValueForKey(json, AntialiasingModeKey, _AntialiasingMode);
JsonUtils::SetValueForKey(json, TabColorKey, _TabColor);
JsonUtils::SetValueForKey(json, BellStyleKey, _BellStyle);
#define PROFILE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_TO_JSON)
#undef PROFILE_SETTINGS_TO_JSON
// Font settings
const auto fontInfoImpl = winrt::get_self<FontConfig>(_FontInfo);

View file

@ -46,6 +46,7 @@ Author(s):
#include "Profile.g.h"
#include "IInheritable.h"
#include "MTSMSettings.h"
#include "../inc/cppwinrt_utils.h"
#include "JsonUtils.h"
@ -102,43 +103,26 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void _FinalizeInheritance() override;
// Special fields
WINRT_PROPERTY(bool, Deleted, false);
WINRT_PROPERTY(OriginTag, Origin, OriginTag::None);
WINRT_PROPERTY(guid, Updates);
INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
// Nullable/optional settings
INHERITABLE_NULLABLE_SETTING(Model::Profile, Microsoft::Terminal::Core::Color, TabColor, nullptr);
INHERITABLE_SETTING(Model::Profile, Model::IAppearanceConfig, UnfocusedAppearance, nullptr);
// Settings that cannot be put in the macro because of how they are handled in ToJson/LayerJson
INHERITABLE_SETTING(Model::Profile, hstring, Name, L"Default");
INHERITABLE_SETTING(Model::Profile, hstring, Source);
INHERITABLE_SETTING(Model::Profile, bool, Hidden, false);
INHERITABLE_SETTING(Model::Profile, guid, ConnectionType);
// Default Icon: Segoe MDL2 CommandPrompt icon
INHERITABLE_SETTING(Model::Profile, hstring, Icon, L"\uE756");
INHERITABLE_SETTING(Model::Profile, CloseOnExitMode, CloseOnExit, CloseOnExitMode::Graceful);
INHERITABLE_SETTING(Model::Profile, hstring, TabTitle);
INHERITABLE_NULLABLE_SETTING(Model::Profile, Microsoft::Terminal::Core::Color, TabColor, nullptr);
INHERITABLE_SETTING(Model::Profile, bool, SuppressApplicationTitle, false);
INHERITABLE_SETTING(Model::Profile, bool, UseAcrylic, false);
INHERITABLE_SETTING(Model::Profile, Microsoft::Terminal::Control::ScrollbarState, ScrollState, Microsoft::Terminal::Control::ScrollbarState::Visible);
INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
INHERITABLE_SETTING(Model::Profile, hstring, Padding, DEFAULT_PADDING);
INHERITABLE_SETTING(Model::Profile, hstring, Commandline, L"%SystemRoot%\\System32\\cmd.exe");
INHERITABLE_SETTING(Model::Profile, hstring, StartingDirectory);
INHERITABLE_SETTING(Model::Profile, Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::Control::TextAntialiasingMode::Grayscale);
INHERITABLE_SETTING(Model::Profile, bool, ForceFullRepaintRendering, false);
INHERITABLE_SETTING(Model::Profile, bool, SoftwareRendering, false);
INHERITABLE_SETTING(Model::Profile, int32_t, HistorySize, DEFAULT_HISTORY_SIZE);
INHERITABLE_SETTING(Model::Profile, bool, SnapOnInput, true);
INHERITABLE_SETTING(Model::Profile, bool, AltGrAliasing, true);
INHERITABLE_SETTING(Model::Profile, Model::BellStyle, BellStyle, BellStyle::Audible);
INHERITABLE_SETTING(Model::Profile, Model::IAppearanceConfig, UnfocusedAppearance, nullptr);
#define PROFILE_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
INHERITABLE_SETTING(Model::Profile, type, name, ##__VA_ARGS__)
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_INITIALIZE)
#undef PROFILE_SETTINGS_INITIALIZE
private:
Model::IAppearanceConfig _DefaultAppearance{ winrt::make<AppearanceConfig>(weak_ref<Model::Profile>(*this)) };

View file

@ -74,8 +74,6 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(IAppearanceConfig, UnfocusedAppearance);
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
INHERITABLE_PROFILE_SETTING(Boolean, ForceFullRepaintRendering);
INHERITABLE_PROFILE_SETTING(Boolean, SoftwareRendering);
INHERITABLE_PROFILE_SETTING(Int32, HistorySize);
INHERITABLE_PROFILE_SETTING(Boolean, SnapOnInput);

View file

@ -2901,15 +2901,9 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
auto defaultAttrs = si.GetAttributes();
auto conhostGreenAttrs = TextAttribute();
// Conhost and Terminal store attributes in different bits.
// conhostGreenAttrs.SetIndexedAttributes(std::nullopt,
// { static_cast<BYTE>(FOREGROUND_GREEN) });
conhostGreenAttrs.SetIndexedBackground(FOREGROUND_GREEN);
conhostGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN);
auto terminalGreenAttrs = TextAttribute();
// terminalGreenAttrs.SetIndexedAttributes(std::nullopt,
// { static_cast<BYTE>(XTERM_GREEN_ATTR) });
terminalGreenAttrs.SetIndexedBackground(XTERM_GREEN_ATTR);
terminalGreenAttrs.SetIndexedBackground(TextColor::DARK_GREEN);
// Use an initial ^[[m to start printing with default-on-default
sm.ProcessString(L"\x1b[m");
@ -2942,7 +2936,7 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
auto verifyBuffer = [&](const TextBuffer& tb, const til::rectangle viewport, const bool isTerminal, const bool afterResize) {
const auto width = viewport.width<short>();
// Conhost and Terminal store attributes in different bits.
// Conhost and Terminal attributes are potentially different.
const auto greenAttrs = isTerminal ? terminalGreenAttrs : conhostGreenAttrs;
for (short row = 0; row < tb.GetSize().Height(); row++)
@ -3034,13 +3028,11 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
auto defaultAttrs = si.GetAttributes();
auto conhostBlueAttrs = defaultAttrs;
// Conhost and Terminal store attributes in different bits.
conhostBlueAttrs.SetIndexedForeground(FOREGROUND_GREEN);
conhostBlueAttrs.SetIndexedBackground(FOREGROUND_BLUE);
conhostBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN);
conhostBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE);
auto terminalBlueAttrs = TextAttribute();
terminalBlueAttrs.SetIndexedForeground(XTERM_GREEN_ATTR);
terminalBlueAttrs.SetIndexedBackground(XTERM_BLUE_ATTR);
terminalBlueAttrs.SetIndexedForeground(TextColor::DARK_GREEN);
terminalBlueAttrs.SetIndexedBackground(TextColor::DARK_BLUE);
// We're going to print 4 more rows than the entire height of the viewport,
// causing the buffer to circle 4 times. This is 2 extra iterations of the
@ -3083,7 +3075,7 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
const auto width = viewport.width<short>();
const auto isTerminal = viewport.top() != 0;
// Conhost and Terminal store attributes in different bits.
// Conhost and Terminal attributes are potentially different.
const auto blueAttrs = isTerminal ? terminalBlueAttrs : conhostBlueAttrs;
for (short row = 0; row < viewport.bottom<short>() - 2; row++)

View file

@ -84,6 +84,7 @@ AppHost::AppHost() noexcept :
_window->WindowMoved({ this, &AppHost::_WindowMoved });
_window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed });
_window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop());
_window->ShouldExitFullscreen({ &_logic, &winrt::TerminalApp::AppLogic::RequestExitFullscreen });
_window->MakeWindow();
_GetWindowLayoutRequestedToken = _windowManager.GetWindowLayoutRequested([this](auto&&, const winrt::Microsoft::Terminal::Remoting::GetWindowLayoutArgs& args) {
@ -325,6 +326,7 @@ void AppHost::Initialize()
_logic.FocusModeChanged({ this, &AppHost::_FocusModeChanged });
_logic.AlwaysOnTopChanged({ this, &AppHost::_AlwaysOnTopChanged });
_logic.RaiseVisualBell({ this, &AppHost::_RaiseVisualBell });
_logic.SystemMenuChangeRequested({ this, &AppHost::_SystemMenuChangeRequested });
_logic.Create();
@ -1248,6 +1250,27 @@ void AppHost::_OpenSystemMenu(const winrt::Windows::Foundation::IInspectable&,
_window->OpenSystemMenu(std::nullopt, std::nullopt);
}
void AppHost::_SystemMenuChangeRequested(const winrt::Windows::Foundation::IInspectable&, const winrt::TerminalApp::SystemMenuChangeArgs& args)
{
switch (args.Action())
{
case winrt::TerminalApp::SystemMenuChangeAction::Add:
{
auto handler = args.Handler();
_window->AddToSystemMenu(args.Name(), [handler]() { handler(); });
break;
}
case winrt::TerminalApp::SystemMenuChangeAction::Remove:
{
_window->RemoveFromSystemMenu(args.Name());
break;
}
default:
{
}
}
}
// Method Description:
// - Creates a Notification Icon and hooks up its handlers
// Arguments:

View file

@ -96,6 +96,9 @@ private:
void _OpenSystemMenu(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
void _SystemMenuChangeRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::TerminalApp::SystemMenuChangeArgs& args);
winrt::fire_and_forget _QuitRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);

View file

@ -24,6 +24,7 @@ using namespace ::Microsoft::Console::Types;
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
#define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS"
#define IDM_SYSTEM_MENU_BEGIN 0x1000
const UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
@ -321,6 +322,8 @@ void IslandWindow::Initialize()
}
}
_systemMenuNextItemId = IDM_SYSTEM_MENU_BEGIN;
// Enable vintage opacity by removing the XAML emergency backstop, GH#603.
// We don't really care if this failed or not.
TerminalTrySetTransparentBackground(true);
@ -608,6 +611,20 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize
_NotifyNotificationIconMenuItemSelectedHandlers((HMENU)lparam, (UINT)wparam);
return 0;
}
case WM_SYSCOMMAND:
{
if (wparam == SC_RESTORE && _fullscreen)
{
_ShouldExitFullscreenHandlers();
return 0;
}
auto search = _systemMenuItems.find(LOWORD(wparam));
if (search != _systemMenuItems.end())
{
search->second.callback();
}
break;
}
default:
// We'll want to receive this message when explorer.exe restarts
// so that we can re-add our icon to the notification area.
@ -1717,5 +1734,50 @@ void IslandWindow::OpenSystemMenu(const std::optional<int> mouseX, const std::op
}
}
void IslandWindow::AddToSystemMenu(const winrt::hstring& itemLabel, winrt::delegate<void()> callback)
{
const HMENU systemMenu = GetSystemMenu(_window.get(), FALSE);
UINT wID = _systemMenuNextItemId;
MENUITEMINFOW item;
item.cbSize = sizeof(MENUITEMINFOW);
item.fMask = MIIM_STATE | MIIM_ID | MIIM_STRING;
item.fState = MF_ENABLED;
item.wID = wID;
item.dwTypeData = const_cast<LPWSTR>(itemLabel.c_str());
item.cch = static_cast<UINT>(itemLabel.size());
if (LOG_LAST_ERROR_IF(!InsertMenuItemW(systemMenu, wID, FALSE, &item)))
{
return;
}
_systemMenuItems.insert({ wID, { itemLabel, callback } });
_systemMenuNextItemId++;
}
void IslandWindow::RemoveFromSystemMenu(const winrt::hstring& itemLabel)
{
const HMENU systemMenu = GetSystemMenu(_window.get(), FALSE);
int itemCount = GetMenuItemCount(systemMenu);
if (LOG_LAST_ERROR_IF(itemCount == -1))
{
return;
}
auto it = std::find_if(_systemMenuItems.begin(), _systemMenuItems.end(), [&itemLabel](const std::pair<UINT, SystemMenuItemInfo>& elem) {
return elem.second.label == itemLabel;
});
if (it == _systemMenuItems.end())
{
return;
}
if (LOG_LAST_ERROR_IF(!DeleteMenu(systemMenu, it->first, MF_BYCOMMAND)))
{
return;
}
_systemMenuItems.erase(it->first);
}
DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);
DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>);

View file

@ -8,6 +8,12 @@
void SetWindowLongWHelper(const HWND hWnd, const int nIndex, const LONG dwNewLong) noexcept;
struct SystemMenuItemInfo
{
winrt::hstring label;
winrt::delegate<void()> callback;
};
class IslandWindow :
public BaseWindow<IslandWindow>
{
@ -54,6 +60,8 @@ public:
void SetMinimizeToNotificationAreaBehavior(bool MinimizeToNotificationArea) noexcept;
void OpenSystemMenu(const std::optional<int> mouseX, const std::optional<int> mouseY) const noexcept;
void AddToSystemMenu(const winrt::hstring& itemLabel, winrt::delegate<void()> callback);
void RemoveFromSystemMenu(const winrt::hstring& itemLabel);
DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);
DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>);
@ -65,6 +73,7 @@ public:
WINRT_CALLBACK(NotifyShowNotificationIconContextMenu, winrt::delegate<void(til::point)>);
WINRT_CALLBACK(NotifyNotificationIconMenuItemSelected, winrt::delegate<void(HMENU, UINT)>);
WINRT_CALLBACK(NotifyReAddNotificationIcon, winrt::delegate<void()>);
WINRT_CALLBACK(ShouldExitFullscreen, winrt::delegate<void()>);
WINRT_CALLBACK(WindowMoved, winrt::delegate<void()>);
@ -131,6 +140,9 @@ protected:
bool _minimizeToNotificationArea{ false };
std::unordered_map<UINT, SystemMenuItemInfo> _systemMenuItems;
UINT _systemMenuNextItemId;
private:
// This minimum width allows for width the tabs fit
static constexpr long minimumWidth = 460L;

View file

@ -843,7 +843,11 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept
HPAINTBUFFER buf = BeginBufferedPaint(hdc.get(), &rcRest, BPBF_TOPDOWNDIB, &params, &opaqueDc);
if (!buf || !opaqueDc)
{
winrt::throw_last_error();
// MSFT:34673647 - BeginBufferedPaint can fail, but it probably
// shouldn't bring the whole Terminal down with it. So don't
// throw_last_error here.
LOG_LAST_ERROR();
return 0;
}
::FillRect(opaqueDc, &rcRest, _backgroundBrush.get());

View file

@ -1,52 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- conattrs.cpp
Abstract:
- Defines common operations on console attributes, especially in regards to
finding the nearest color from a color table.
Author(s):
- Mike Griese (migrie) 01-Sept-2017
--*/
#include "precomp.h"
#include "../inc/conattrs.hpp"
#include <cmath>
// Function Description:
// - Converts the value of a xterm color table index to the windows color table equivalent.
// Arguments:
// - xtermTableEntry: the xterm color table index
// Return Value:
// - The windows color table equivalent.
WORD XtermToWindowsIndex(const size_t xtermTableEntry) noexcept
{
const bool fRed = WI_IsFlagSet(xtermTableEntry, XTERM_RED_ATTR);
const bool fGreen = WI_IsFlagSet(xtermTableEntry, XTERM_GREEN_ATTR);
const bool fBlue = WI_IsFlagSet(xtermTableEntry, XTERM_BLUE_ATTR);
const bool fBright = WI_IsFlagSet(xtermTableEntry, XTERM_BRIGHT_ATTR);
return (fRed ? WINDOWS_RED_ATTR : 0x0) +
(fGreen ? WINDOWS_GREEN_ATTR : 0x0) +
(fBlue ? WINDOWS_BLUE_ATTR : 0x0) +
(fBright ? WINDOWS_BRIGHT_ATTR : 0x0);
}
// Function Description:
// - Converts the value of a xterm color table index to the windows color table
// equivalent. The range of values is [0, 255], where the lowest 16 are
// mapped to the equivalent Windows index, and the rest of the values are
// passed through.
// Arguments:
// - xtermTableEntry: the xterm color table index
// Return Value:
// - The windows color table equivalent.
WORD Xterm256ToWindowsIndex(const size_t xtermTableEntry) noexcept
{
return xtermTableEntry < 16 ? XtermToWindowsIndex(xtermTableEntry) :
static_cast<WORD>(xtermTableEntry);
}

View file

@ -231,7 +231,7 @@ InputBuffer* const CONSOLE_INFORMATION::GetActiveInputBuffer() const
COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept
{
const auto fg = GetDefaultForegroundColor();
return fg != INVALID_COLOR ? fg : GetColorTableEntry(LOBYTE(GetFillAttribute()) & FG_ATTRS);
return fg != INVALID_COLOR ? fg : GetLegacyColorTableEntry(LOBYTE(GetFillAttribute()) & FG_ATTRS);
}
// Method Description:
@ -246,23 +246,37 @@ COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept
COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept
{
const auto bg = GetDefaultBackgroundColor();
return bg != INVALID_COLOR ? bg : GetColorTableEntry((LOBYTE(GetFillAttribute()) & BG_ATTRS) >> 4);
return bg != INVALID_COLOR ? bg : GetLegacyColorTableEntry((LOBYTE(GetFillAttribute()) & BG_ATTRS) >> 4);
}
// Method Description:
// - Get the colors of a particular text attribute, using our color table,
// and our configured default attributes.
// Arguments:
// - attr: the TextAttribute to retrieve the foreground color of.
// - attr: the TextAttribute to retrieve the foreground and background color of.
// Return Value:
// - The color values of the attribute's foreground and background.
std::pair<COLORREF, COLORREF> CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr) const noexcept
{
return LookupAttributeColors(attr, GetDefaultForeground(), GetDefaultBackground());
}
// Method Description:
// - Get the colors of a particular text attribute, using our color table,
// and the given default color values.
// Arguments:
// - attr: the TextAttribute to retrieve the foreground and background color of.
// - defaultFg: the COLORREF to use for a default foreground color.
// - defaultBg: the COLORREF to use for a default background color.
// Return Value:
// - The color values of the attribute's foreground and background.
std::pair<COLORREF, COLORREF> CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept
{
_blinkingState.RecordBlinkingUsage(attr);
return attr.CalculateRgbColors(
GetColorTable(),
GetDefaultForeground(),
GetDefaultBackground(),
defaultFg,
defaultBg,
IsScreenReversed(),
_blinkingState.IsBlinkingFaint());
}

View file

@ -30,7 +30,7 @@
// GetConsoleAlias
using namespace WEX::TestExecution;
using namespace WEX::Common;
using WEX::Logging::Log;
using namespace WEX::Logging;
class AliasTests
{

View file

@ -5,7 +5,7 @@
extern "C" IMAGE_DOS_HEADER __ImageBase;
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
// This class is intended to test boundary conditions for:

View file

@ -4,7 +4,7 @@
#include "precomp.h"
using namespace WEX::TestExecution;
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
// This class is intended to test:

View file

@ -7,7 +7,7 @@
#include <future>
using WEX::Logging::Log;
using namespace WEX::Logging;
using WEX::TestExecution::TestData;
using namespace WEX::Common;

View file

@ -5,7 +5,7 @@
using namespace WEX::TestExecution;
using namespace WEX::Common;
using WEX::Logging::Log;
using namespace WEX::Logging;
static const COORD c_coordZero = { 0, 0 };

View file

@ -11,7 +11,7 @@
#define NUMBER_OF_SCENARIO_INPUTS 10
#define READ_BATCH 3
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
// This class is intended to test:

View file

@ -11,7 +11,7 @@
using namespace Microsoft::Console::Types;
using namespace WEX::TestExecution;
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
class OutputTests

View file

@ -3,7 +3,7 @@
#include "precomp.h"
using WEX::Logging::Log;
using namespace WEX::Logging;
// This class is intended to test restrictions placed on APIs from within a UWP application context
class PolicyTests

View file

@ -3,7 +3,7 @@
#include "precomp.h"
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
// This class is intended to test:

View file

@ -10,7 +10,7 @@
#define ENGLISH_US_CP 437u
#define JAPANESE_CP 932u
using WEX::Logging::Log;
using namespace WEX::Logging;
using WEX::TestExecution::TestData;
using namespace WEX::Common;

View file

@ -3,7 +3,7 @@
#include "precomp.h"
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
// This class is intended to provide a canary (simple launch test)

View file

@ -3,7 +3,7 @@
#include "precomp.h"
using WEX::Logging::Log;
using namespace WEX::Logging;
using namespace WEX::Common;
HANDLE Common::_hConsole = INVALID_HANDLE_VALUE;

View file

@ -25,7 +25,7 @@
using namespace WEX::TestExecution;
using namespace WEX::Common;
using WEX::Logging::Log;
using namespace WEX::Logging;
class KeyPressTests
{

View file

@ -605,7 +605,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
for (size_t i = 0; i < std::size(data.ColorTable); i++)
{
gci.SetColorTableEntry(i, data.ColorTable[i]);
gci.SetLegacyColorTableEntry(i, data.ColorTable[i]);
}
context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes });
@ -1978,7 +1978,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo)
Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation();
value = gci.GetColorTableEntry(::Xterm256ToWindowsIndex(index));
value = gci.GetColorTableEntry(index);
return S_OK;
}
@ -2004,7 +2004,7 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo)
Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation();
gci.SetColorTableEntry(::Xterm256ToWindowsIndex(index), value);
gci.SetColorTableEntry(index, value);
// Update the screen colors if we're not a pty
// No need to force a redraw in pty mode.

View file

@ -7,7 +7,6 @@
<ClCompile Include="..\CommandListPopup.cpp" />
<ClCompile Include="..\CopyFromCharPopup.cpp" />
<ClCompile Include="..\CopyToCharPopup.cpp" />
<ClCompile Include="..\conattrs.cpp" />
<ClCompile Include="..\ConsoleArguments.cpp" />
<ClCompile Include="..\CursorBlinker.cpp" />
<ClCompile Include="..\readDataCooked.cpp" />

View file

@ -138,9 +138,6 @@
<ClCompile Include="..\writeData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\conattrs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\VtInputThread.cpp">
<Filter>Source Files</Filter>
</ClCompile>

View file

@ -34,13 +34,13 @@ using Microsoft::Console::Interactivity::ServiceLocator;
// - OriginalCursorPosition -
// - NumberOfVisibleChars
// - CtrlWakeupMask - Special client parameter to interrupt editing, end the wait, and return control to the client application
// - CommandHistory -
// - Echo -
// - InsertMode -
// - Processed -
// - Line -
// - pTempHandle - A handle to the output buffer to prevent it from being destroyed while we're using it to present 'edit line' text.
// - initialData - any text data that should be prepopulated into the buffer
// - pClientProcess - Attached process handle object
// Return Value:
// - THROW: Throws E_INVALIDARG for invalid pointers.
COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
@ -49,9 +49,9 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
_In_ size_t UserBufferSize,
_In_ PWCHAR UserBuffer,
_In_ ULONG CtrlWakeupMask,
_In_ CommandHistory* CommandHistory,
const std::wstring_view exeName,
const std::string_view initialData) :
_In_ const std::wstring_view exeName,
_In_ const std::string_view initialData,
_In_ ConsoleProcessHandle* const pClientProcess) :
ReadData(pInputBuffer, pInputReadHandleData),
_screenInfo{ screenInfo },
_bytesRead{ 0 },
@ -62,7 +62,7 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
_exeName{ exeName },
_pdwNumBytes{ nullptr },
_commandHistory{ CommandHistory },
_commandHistory{ CommandHistory::s_Find((HANDLE)pClientProcess) },
_controlKeyState{ 0 },
_ctrlWakeupMask{ CtrlWakeupMask },
_visibleCharCount{ 0 },
@ -73,7 +73,8 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
_lineInput{ WI_IsFlagSet(pInputBuffer->InputMode, ENABLE_LINE_INPUT) },
_processedInput{ WI_IsFlagSet(pInputBuffer->InputMode, ENABLE_PROCESSED_INPUT) },
_insertMode{ ServiceLocator::LocateGlobals().getConsoleInformation().GetInsertMode() },
_unicode{ false }
_unicode{ false },
_clientProcess{ pClientProcess }
{
#ifndef UNIT_TESTING
THROW_IF_FAILED(screenInfo.GetMainBuffer().AllocateIoHandle(ConsoleHandleData::HandleType::Output,
@ -1008,13 +1009,13 @@ void COOKED_READ_DATA::SavePendingInput(const size_t index, const bool multiline
{
// Figure out where real string ends (at carriage return or end of buffer).
PWCHAR StringPtr = _backupLimit;
size_t StringLength = _bytesRead;
size_t StringLength = _bytesRead / sizeof(WCHAR);
bool FoundCR = false;
for (size_t i = 0; i < (_bytesRead / sizeof(WCHAR)); i++)
for (size_t i = 0; i < StringLength; i++)
{
if (*StringPtr++ == UNICODE_CARRIAGERETURN)
{
StringLength = i * sizeof(WCHAR);
StringLength = i;
FoundCR = true;
break;
}
@ -1026,11 +1027,13 @@ void COOKED_READ_DATA::SavePendingInput(const size_t index, const bool multiline
{
// add to command line recall list if we have a history list.
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
LOG_IF_FAILED(_commandHistory->Add({ _backupLimit, StringLength / sizeof(wchar_t) },
LOG_IF_FAILED(_commandHistory->Add({ _backupLimit, StringLength },
WI_IsFlagSet(gci.Flags, CONSOLE_HISTORY_NODUP)));
}
Tracing::s_TraceCookedRead(_backupLimit);
Tracing::s_TraceCookedRead(_clientProcess,
_backupLimit,
base::saturated_cast<ULONG>(StringLength));
// check for alias
ProcessAliases(LineCount);

View file

@ -39,9 +39,9 @@ public:
_In_ size_t UserBufferSize,
_In_ PWCHAR UserBuffer,
_In_ ULONG CtrlWakeupMask,
_In_ CommandHistory* CommandHistory,
const std::wstring_view exeName,
const std::string_view initialData);
_In_ const std::wstring_view exeName,
_In_ const std::string_view initialData,
_In_ ConsoleProcessHandle* const pClientProcess);
~COOKED_READ_DATA() override;
COOKED_READ_DATA(COOKED_READ_DATA&&) = default;
@ -156,6 +156,8 @@ private:
bool _insertMode;
bool _unicode;
ConsoleProcessHandle* const _clientProcess;
[[nodiscard]] NTSTATUS _readCharInputLoop(const bool isUnicode, size_t& numBytes) noexcept;
[[nodiscard]] NTSTATUS _handlePostCharInputLoop(const bool isUnicode, size_t& numBytes, ULONG& controlKeyState) noexcept;

View file

@ -310,7 +310,7 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle)
nullptr);
if (NT_SUCCESS(Status))
{
_pSettings->SetColorTableEntry(i, dwValue);
_pSettings->SetLegacyColorTableEntry(i, dwValue);
}
}

View file

@ -110,6 +110,8 @@ void RenderData::UnlockConsole() noexcept
const TextAttribute RenderData::GetDefaultBrushColors() noexcept
{
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
_defaultForeground = gci.GetDefaultForeground();
_defaultBackground = gci.GetDefaultBackground();
return gci.GetActiveOutputBuffer().GetAttributes();
}
@ -362,7 +364,7 @@ const std::vector<size_t> RenderData::GetPatternId(const COORD /*location*/) con
std::pair<COLORREF, COLORREF> RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept
{
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.LookupAttributeColors(attr);
return gci.LookupAttributeColors(attr, _defaultForeground, _defaultBackground);
}
#pragma endregion

View file

@ -15,6 +15,7 @@ Author(s):
#pragma once
#include "../renderer/inc/IRenderData.hpp"
#include "../types/inc/colorTable.hpp"
#include "../types/IUiaData.h"
class RenderData final :
@ -71,4 +72,8 @@ public:
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
const bool IsUiaDataInitialized() const noexcept override { return true; }
#pragma endregion
private:
COLORREF _defaultForeground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 7);
COLORREF _defaultBackground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 0);
};

View file

@ -364,7 +364,7 @@ void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize,
// the copy length must be constant for now to keep OACR happy with buffer overruns.
for (size_t i = 0; i < COLOR_TABLE_SIZE; i++)
{
lpColorTable[i] = gci.GetColorTableEntry(i);
lpColorTable[i] = gci.GetLegacyColorTableEntry(i);
}
*pcoordMaximumWindowSize = GetMaxWindowSizeInCharacters();

View file

@ -661,13 +661,15 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
if (fAltPressed || fCtrlPressed)
{
TextAttribute selectionAttr;
const BYTE colorIndex = gsl::narrow_cast<BYTE>(wVirtualKeyCode - '0' + 6);
// The key number corresponds to the Windows color table order, so the value
// need to be transposed to obtain the index in an ANSI-compatible order.
const auto colorIndex = TextColor::TransposeLegacyIndex(wVirtualKeyCode - '0' + 6);
if (fCtrlPressed)
{
// Setting background color. Set fg color to black.
selectionAttr.SetIndexedBackground256(colorIndex);
selectionAttr.SetIndexedForeground256(0);
selectionAttr.SetIndexedForeground256(TextColor::DARK_BLACK);
}
else
{

View file

@ -127,6 +127,7 @@ public:
COLORREF GetDefaultForeground() const noexcept;
COLORREF GetDefaultBackground() const noexcept;
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr) const noexcept;
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept;
void SetTitle(const std::wstring_view newTitle);
void SetTitlePrefix(const std::wstring_view newTitlePrefix);

View file

@ -82,8 +82,7 @@ Settings::Settings() :
_CursorType = CursorType::Legacy;
gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() };
::Microsoft::Console::Utils::Initialize256ColorTable(tableView);
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView);
::Microsoft::Console::Utils::InitializeColorTable(tableView);
}
// Routine Description:
@ -122,8 +121,8 @@ void Settings::ApplyDesktopSpecificDefaults()
_uNumberOfHistoryBuffers = 4;
_bHistoryNoDup = FALSE;
gsl::span<COLORREF> tableView = { _colorTable.data(), _colorTable.size() };
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView);
gsl::span<COLORREF> tableView = { _colorTable.data(), 16 };
::Microsoft::Console::Utils::InitializeColorTable(tableView);
_fTrimLeadingZeros = false;
_fEnableColorSelection = false;
@ -222,7 +221,7 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo)
_uNumberOfHistoryBuffers = pStateInfo->NumberOfHistoryBuffers;
for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++)
{
SetColorTableEntry(i, pStateInfo->ColorTable[i]);
SetLegacyColorTableEntry(i, pStateInfo->ColorTable[i]);
}
_uCodePage = pStateInfo->CodePage;
_bWrapText = !!pStateInfo->fWrapText;
@ -267,7 +266,7 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const
csi.NumberOfHistoryBuffers = _uNumberOfHistoryBuffers;
for (size_t i = 0; i < std::size(csi.ColorTable); i++)
{
csi.ColorTable[i] = GetColorTableEntry(i);
csi.ColorTable[i] = GetLegacyColorTableEntry(i);
}
csi.CodePage = _uCodePage;
csi.fWrapText = !!_bWrapText;
@ -726,11 +725,6 @@ void Settings::SetHistoryNoDup(const bool bHistoryNoDup)
_bHistoryNoDup = bHistoryNoDup;
}
void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue)
{
_colorTable.at(index) = ColorValue;
}
bool Settings::IsStartupTitleIsLinkNameSet() const
{
return WI_IsFlagSet(_dwStartupFlags, STARTF_TITLEISLINKNAME);
@ -746,11 +740,26 @@ void Settings::UnsetStartupFlag(const DWORD dwFlagToUnset)
_dwStartupFlags &= ~dwFlagToUnset;
}
void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue)
{
_colorTable.at(index) = ColorValue;
}
COLORREF Settings::GetColorTableEntry(const size_t index) const
{
return _colorTable.at(index);
}
void Settings::SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue)
{
_colorTable.at(TextColor::TransposeLegacyIndex(index)) = ColorValue;
}
COLORREF Settings::GetLegacyColorTableEntry(const size_t index) const
{
return _colorTable.at(TextColor::TransposeLegacyIndex(index));
}
COLORREF Settings::GetCursorColor() const noexcept
{
return _CursorColor;

View file

@ -167,6 +167,8 @@ public:
void SetColorTableEntry(const size_t index, const COLORREF ColorValue);
COLORREF GetColorTableEntry(const size_t index) const;
void SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue);
COLORREF GetLegacyColorTableEntry(const size_t index) const;
COLORREF GetCursorColor() const noexcept;
CursorType GetCursorType() const noexcept;

View file

@ -89,7 +89,6 @@ SOURCES = \
..\utf8ToWideCharParser.cpp \
..\conareainfo.cpp \
..\conimeinfo.cpp \
..\conattrs.cpp \
..\ConsoleArguments.cpp \
..\CommandNumberPopup.cpp \
..\CommandListPopup.cpp \
@ -134,6 +133,7 @@ CRTLIBS = \
TARGETLIBS = \
$(TARGETLIBS) \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\api-ms-win-core-commandlinetoargv-l1.lib \
$(ONECORE_INTERNAL_SDK_LIB_PATH)\onecoreuuid.lib \
$(ONECOREUAP_INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \
$(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\onecore_internal.lib \

View file

@ -471,7 +471,6 @@ size_t RetrieveNumberOfSpaces(_In_ SHORT sOriginalCursorPositionX,
RETURN_HR_IF(E_FAIL, !gci.HasActiveOutputBuffer());
SCREEN_INFORMATION& screenInfo = gci.GetActiveOutputBuffer();
CommandHistory* const pCommandHistory = CommandHistory::s_Find(processData);
try
{
@ -481,9 +480,9 @@ size_t RetrieveNumberOfSpaces(_In_ SHORT sOriginalCursorPositionX,
buffer.size_bytes(), // UserBufferSize
reinterpret_cast<wchar_t*>(buffer.data()), // UserBuffer
ctrlWakeupMask, // CtrlWakeupMask
pCommandHistory, // CommandHistory
exeName, // exe name
initialData);
initialData,
reinterpret_cast<ConsoleProcessHandle*>(processData)); //pClientProcess
gci.SetCookedReadData(cookedReadData.get());
bytesRead = buffer.size_bytes(); // This parameter on the way in is the size to read, on the way out, it will be updated to what is actually read.

View file

@ -587,3 +587,8 @@ void Telemetry::LogRipMessage(_In_z_ const char* pszMessage, ...) const
TraceLoggingString(szMessageEvaluated, "Message"));
}
}
bool Telemetry::IsUserInteractive()
{
return _fUserInteractiveForTelemetry;
}

View file

@ -51,6 +51,8 @@ public:
void LogRipMessage(_In_z_ const char* pszMessage, ...) const;
bool IsUserInteractive();
// Names are from the external API call names. Note that some names can be different
// than the internal API calls.
// Don't worry about the following APIs, because they are external to our conhost codebase and hard to track through

View file

@ -21,6 +21,7 @@ enum TraceKeywords
API = 0x400,
UIA = 0x800,
CookedRead = 0x1000,
ConsoleAttachDetach = 0x2000,
All = 0x1FFF
};
DEFINE_ENUM_FLAG_OPERATORS(TraceKeywords);
@ -405,14 +406,38 @@ void Tracing::s_TraceInputRecord(const INPUT_RECORD& inputRecord)
}
}
void Tracing::s_TraceCookedRead(_In_z_ const wchar_t* pwszCookedBuffer)
void Tracing::s_TraceCookedRead(_In_ ConsoleProcessHandle* const pConsoleProcessHandle, _In_reads_(cchCookedBufferLength) const wchar_t* pwchCookedBuffer, _In_ ULONG cchCookedBufferLength)
{
TraceLoggingWrite(
g_hConhostV2EventTraceProvider,
"CookedRead",
TraceLoggingWideString(pwszCookedBuffer, "ReadBuffer"),
TraceLoggingKeyword(TIL_KEYWORD_TRACE),
TraceLoggingKeyword(TraceKeywords::CookedRead));
if (TraceLoggingProviderEnabled(g_hConhostV2EventTraceProvider, 0, TraceKeywords::CookedRead))
{
TraceLoggingWrite(
g_hConhostV2EventTraceProvider,
"CookedRead",
TraceLoggingCountedWideString(pwchCookedBuffer, cchCookedBufferLength, "ReadBuffer"),
TraceLoggingULong(cchCookedBufferLength, "ReadBufferLength"),
TraceLoggingUInt32(pConsoleProcessHandle->dwProcessId, "AttachedProcessId"),
TraceLoggingUInt64(pConsoleProcessHandle->GetProcessCreationTime(), "AttachedProcessCreationTime"),
TraceLoggingKeyword(TIL_KEYWORD_TRACE),
TraceLoggingKeyword(TraceKeywords::CookedRead));
}
}
void Tracing::s_TraceConsoleAttachDetach(_In_ ConsoleProcessHandle* const pConsoleProcessHandle, _In_ bool bIsAttach)
{
if (TraceLoggingProviderEnabled(g_hConhostV2EventTraceProvider, 0, TraceKeywords::ConsoleAttachDetach))
{
bool bIsUserInteractive = Telemetry::Instance().IsUserInteractive();
TraceLoggingWrite(
g_hConhostV2EventTraceProvider,
"ConsoleAttachDetach",
TraceLoggingUInt32(pConsoleProcessHandle->dwProcessId, "AttachedProcessId"),
TraceLoggingUInt64(pConsoleProcessHandle->GetProcessCreationTime(), "AttachedProcessCreationTime"),
TraceLoggingBool(bIsAttach, "IsAttach"),
TraceLoggingBool(bIsUserInteractive, "IsUserInteractive"),
TraceLoggingKeyword(TIL_KEYWORD_TRACE),
TraceLoggingKeyword(TraceKeywords::ConsoleAttachDetach));
}
}
void __stdcall Tracing::TraceFailure(const wil::FailureInfo& failure) noexcept

View file

@ -62,7 +62,8 @@ public:
static void s_TraceWindowMessage(const MSG& msg);
static void s_TraceInputRecord(const INPUT_RECORD& inputRecord);
static void s_TraceCookedRead(_In_z_ const wchar_t* pwszCookedBuffer);
static void s_TraceCookedRead(_In_ ConsoleProcessHandle* const pConsoleProcessHandle, _In_reads_(cchCookedBufferLength) const wchar_t* pwchCookedBuffer, _In_ ULONG cchCookedBufferLength);
static void s_TraceConsoleAttachDetach(_In_ ConsoleProcessHandle* const pConsoleProcessHandle, _In_ bool bIsAttach);
static void __stdcall TraceFailure(const wil::FailureInfo& failure) noexcept;

View file

@ -27,6 +27,7 @@ class ApiRoutinesTests
ApiRoutines _Routines;
IApiRoutines* _pApiRoutines = &_Routines;
CommandHistory* m_pHistory;
TEST_METHOD_SETUP(MethodSetup)
{
@ -37,11 +38,20 @@ class ApiRoutinesTests
m_state->PrepareGlobalInputBuffer();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ
return true;
}
TEST_METHOD_CLEANUP(MethodCleanup)
{
CommandHistory::s_Free(nullptr);
m_pHistory = nullptr;
m_state->CleanupGlobalInputBuffer();
m_state->CleanupGlobalScreenBuffer();

View file

@ -43,12 +43,13 @@ class CommandLineTests
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_state->PrepareReadHandle();
m_state->PrepareCookedReadData();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
m_state->PrepareCookedReadData();
return true;
}

View file

@ -49,7 +49,6 @@ class CommandListPopupTests
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_state->PrepareReadHandle();
m_state->PrepareCookedReadData();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
// resize command history storage to 50 items so that we don't cycle on accident
// when PopupTestHelper::InitLongHistory() is called.
@ -58,6 +57,8 @@ class CommandListPopupTests
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
m_state->PrepareCookedReadData();
return true;
}

View file

@ -45,12 +45,13 @@ class CommandNumberPopupTests
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_state->PrepareReadHandle();
m_state->PrepareCookedReadData();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
m_state->PrepareCookedReadData();
return true;
}

View file

@ -24,6 +24,7 @@ class CopyFromCharPopupTests
TEST_CLASS(CopyFromCharPopupTests);
std::unique_ptr<CommonState> m_state;
CommandHistory* m_pHistory;
TEST_CLASS_SETUP(ClassSetup)
{
@ -43,12 +44,20 @@ class CopyFromCharPopupTests
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_state->PrepareReadHandle();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
m_state->PrepareCookedReadData();
return true;
}
TEST_METHOD_CLEANUP(MethodCleanup)
{
CommandHistory::s_Free(nullptr);
m_pHistory = nullptr;
m_state->CleanupCookedReadData();
m_state->CleanupReadHandle();
m_state->CleanupGlobalInputBuffer();

View file

@ -44,12 +44,13 @@ class CopyToCharPopupTests
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_state->PrepareReadHandle();
m_state->PrepareCookedReadData();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
m_state->PrepareCookedReadData();
return true;
}

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
@ -1634,74 +1634,74 @@ void ScreenBufferTests::VtSetColorTable()
L"Process some valid sequences for setting the table"));
stateMachine.ProcessString(L"\x1b]4;0;rgb:1/1/1\x7");
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), gci.GetColorTableEntry(::XtermToWindowsIndex(0)));
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), gci.GetColorTableEntry(0));
stateMachine.ProcessString(L"\x1b]4;1;rgb:1/23/1\x7");
VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x11), gci.GetColorTableEntry(::XtermToWindowsIndex(1)));
VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x11), gci.GetColorTableEntry(1));
stateMachine.ProcessString(L"\x1b]4;2;rgb:1/23/12\x7");
VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(2)));
VERIFY_ARE_EQUAL(RGB(0x11, 0x23, 0x12), gci.GetColorTableEntry(2));
stateMachine.ProcessString(L"\x1b]4;3;rgb:12/23/12\x7");
VERIFY_ARE_EQUAL(RGB(0x12, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(3)));
VERIFY_ARE_EQUAL(RGB(0x12, 0x23, 0x12), gci.GetColorTableEntry(3));
stateMachine.ProcessString(L"\x1b]4;4;rgb:ff/a1/1b\x7");
VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(4)));
VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(4));
stateMachine.ProcessString(L"\x1b]4;5;rgb:ff/a1/1b\x1b\\");
VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"Try a bunch of invalid sequences."));
Log::Comment(NoThrowString().Format(
L"First start by setting an entry to a known value to compare to."));
stateMachine.ProcessString(L"\x1b]4;5;rgb:09/09/09\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: Missing the first component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: too many components"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1/1/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: no second component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1//1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: no components"));
stateMachine.ProcessString(L"\x1b]4;5;rgb://\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: no third component"));
stateMachine.ProcessString(L"\x1b]4;5;rgb:1/11/\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: rgbi is not a supported color space"));
stateMachine.ProcessString(L"\x1b]4;5;rgbi:1/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: cmyk is not a supported color space"));
stateMachine.ProcessString(L"\x1b]4;5;cmyk:1/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: no table index should do nothing"));
stateMachine.ProcessString(L"\x1b]4;;rgb:1/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
Log::Comment(NoThrowString().Format(
L"invalid: need to specify a color space"));
stateMachine.ProcessString(L"\x1b]4;5;1/1/1\x1b\\");
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5)));
VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(5));
}
void ScreenBufferTests::ResizeTraditionalDoesNotDoubleFreeAttrRows()
@ -1912,8 +1912,8 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor()
L"The viewport should be full of dark_red on bright_blue"));
auto expectedAttr = TextAttribute{};
expectedAttr.SetIndexedForeground((BYTE)XtermToWindowsIndex(1));
expectedAttr.SetIndexedBackground((BYTE)XtermToWindowsIndex(12));
expectedAttr.SetIndexedForeground(TextColor::DARK_RED);
expectedAttr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
stateMachine.ProcessString(L"\x1b[31;104m");
VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes());
@ -2256,8 +2256,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
COLORREF magenta = RGB(255, 0, 255);
COLORREF yellow = RGB(255, 255, 0);
COLORREF brightGreen = gci.GetColorTableEntry(::XtermToWindowsIndex(10));
COLORREF darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4));
COLORREF brightGreen = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
COLORREF darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
gci.SetDefaultForegroundColor(yellow);
gci.SetDefaultBackgroundColor(magenta);
@ -2292,8 +2292,8 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
// See the log comment above for description of these values.
TextAttribute expectedDefaults{};
TextAttribute expectedTwo;
expectedTwo.SetIndexedForeground((BYTE)XtermToWindowsIndex(10));
expectedTwo.SetIndexedBackground((BYTE)XtermToWindowsIndex(4));
expectedTwo.SetIndexedForeground(TextColor::BRIGHT_GREEN);
expectedTwo.SetIndexedBackground(TextColor::DARK_BLUE);
TextAttribute expectedThree = expectedTwo;
expectedThree.SetDefaultForeground();
// Four is the same as Defaults
@ -2705,7 +2705,7 @@ void ScreenBufferTests::SetGlobalColorTable()
VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true));
mainCursor.SetPosition({ 0, 0 });
const COLORREF originalRed = gci.GetColorTableEntry(4);
const COLORREF originalRed = gci.GetColorTableEntry(TextColor::DARK_RED);
const COLORREF testColor = RGB(0x11, 0x22, 0x33);
VERIFY_ARE_NOT_EQUAL(originalRed, testColor);
@ -3209,10 +3209,10 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
Log::Comment(NoThrowString().Format(
L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
const auto darkRed = gci.GetColorTableEntry(::XtermToWindowsIndex(1));
const auto darkBlue = gci.GetColorTableEntry(::XtermToWindowsIndex(4));
const auto darkBlack = gci.GetColorTableEntry(::XtermToWindowsIndex(0));
const auto darkWhite = gci.GetColorTableEntry(::XtermToWindowsIndex(7));
const auto darkRed = gci.GetColorTableEntry(TextColor::DARK_RED);
const auto darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
const auto darkBlack = gci.GetColorTableEntry(TextColor::DARK_BLACK);
const auto darkWhite = gci.GetColorTableEntry(TextColor::DARK_WHITE);
stateMachine.ProcessString(L"\x1b[31;44m");
stateMachine.ProcessString(L"X");
stateMachine.ProcessString(L"\x1b[m");
@ -6168,8 +6168,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode()
/* Write red on blue, verify that it comes through */
{
TextAttribute vtRedOnBlueAttribute{};
vtRedOnBlueAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(1)), false });
vtRedOnBlueAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(4)), false });
vtRedOnBlueAttribute.SetForeground(TextColor{ TextColor::DARK_RED, false });
vtRedOnBlueAttribute.SetBackground(TextColor{ TextColor::DARK_BLUE, false });
seq = L"\x1b[31;44m";
seqCb = 2 * seq.size();
@ -6187,8 +6187,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode()
/* Write white on black, verify that it acts as expected for the quirk mode */
{
TextAttribute vtWhiteOnBlackAttribute{};
vtWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), false });
vtWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), false });
vtWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false });
vtWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false });
const TextAttribute quirkExpectedAttribute{ useQuirk ? defaultAttribute : vtWhiteOnBlackAttribute };
@ -6208,8 +6208,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode()
/* Write bright white on black, verify that it acts as expected for the quirk mode */
{
TextAttribute vtBrightWhiteOnBlackAttribute{};
vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), false });
vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), false });
vtBrightWhiteOnBlackAttribute.SetForeground(TextColor{ TextColor::DARK_WHITE, false });
vtBrightWhiteOnBlackAttribute.SetBackground(TextColor{ TextColor::DARK_BLACK, false });
vtBrightWhiteOnBlackAttribute.SetBold(true);
TextAttribute vtBrightWhiteOnDefaultAttribute{ vtBrightWhiteOnBlackAttribute }; // copy the above attribute
@ -6233,8 +6233,8 @@ void ScreenBufferTests::TestWriteConsoleVTQuirkMode()
/* Write a 256-color white on a 256-color black, make sure the quirk does not suppress it */
{
TextAttribute vtWhiteOnBlack256Attribute{};
vtWhiteOnBlack256Attribute.SetForeground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(7)), true });
vtWhiteOnBlack256Attribute.SetBackground(TextColor{ gsl::narrow_cast<BYTE>(XtermToWindowsIndex(0)), true });
vtWhiteOnBlack256Attribute.SetForeground(TextColor{ TextColor::DARK_WHITE, true });
vtWhiteOnBlack256Attribute.SetBackground(TextColor{ TextColor::DARK_BLACK, true });
// reset (disable bold from the last test) before setting both colors
seq = L"\x1b[m\x1b[38;5;7;48;5;0m"; // the quirk should *not* suppress this (!)

View file

@ -412,6 +412,7 @@ class SelectionInputTests
TEST_CLASS(SelectionInputTests);
CommonState* m_state;
CommandHistory* m_pHistory;
TEST_CLASS_SETUP(ClassSetup)
{
@ -420,12 +421,20 @@ class SelectionInputTests
m_state->PrepareGlobalFont();
m_state->PrepareGlobalScreenBuffer();
m_state->PrepareGlobalInputBuffer();
m_pHistory = CommandHistory::s_Allocate(L"cmd.exe", nullptr);
if (!m_pHistory)
{
return false;
}
// History must be prepared before COOKED_READ (as it uses s_Find to get at it)
return true;
}
TEST_CLASS_CLEANUP(ClassCleanup)
{
CommandHistory::s_Free(nullptr);
m_pHistory = nullptr;
m_state->CleanupGlobalScreenBuffer();
m_state->CleanupGlobalFont();
m_state->CleanupGlobalInputBuffer();

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
@ -779,8 +779,8 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness()
// '\E[m\E[32mX\E[1mX'
// Make sure that the second X is a BRIGHT green, not white.
Log::Comment(L"Case 4 ;\"\\E[m\\E[32mX\\E[1mX\"");
const auto dark_green = gci.GetColorTableEntry(2);
const auto bright_green = gci.GetColorTableEntry(10);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
VERIFY_ARE_NOT_EQUAL(dark_green, bright_green);
wchar_t* sequence = L"\x1b[m\x1b[32mX\x1b[1mX";
@ -887,8 +887,8 @@ void TextBufferTests::TestUnBold()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2);
const auto bright_green = gci.GetColorTableEntry(10);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}",
@ -938,8 +938,8 @@ void TextBufferTests::TestUnBoldRgb()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2);
const auto bright_green = gci.GetColorTableEntry(10);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}",
@ -997,8 +997,8 @@ void TextBufferTests::TestComplexUnBold()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2);
const auto bright_green = gci.GetColorTableEntry(10);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}",
@ -1079,8 +1079,8 @@ void TextBufferTests::CopyAttrs()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const auto dark_blue = gci.GetColorTableEntry(1);
const auto dark_magenta = gci.GetColorTableEntry(5);
const auto dark_blue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
const auto dark_magenta = gci.GetColorTableEntry(TextColor::DARK_MAGENTA);
Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}",
@ -1133,7 +1133,7 @@ void TextBufferTests::EmptySgrTest()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const COLORREF darkRed = gci.GetColorTableEntry(4);
const COLORREF darkRed = gci.GetColorTableEntry(TextColor::DARK_RED);
Log::Comment(NoThrowString().Format(
L"cursor={X:%d,Y:%d}",
x,
@ -1192,7 +1192,7 @@ void TextBufferTests::TestReverseReset()
const auto x = cursor.GetPosition().X;
const auto y = cursor.GetPosition().Y;
const auto dark_green = gci.GetColorTableEntry(2);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const COLORREF rgbColor = RGB(128, 5, 255);
Log::Comment(NoThrowString().Format(
@ -1258,9 +1258,9 @@ void TextBufferTests::CopyLastAttr()
const COLORREF defaultBrightYellow = RGB(249, 241, 165);
const COLORREF defaultBrightCyan = RGB(97, 214, 214);
gci.SetColorTableEntry(8, defaultBrightBlack);
gci.SetColorTableEntry(14, defaultBrightYellow);
gci.SetColorTableEntry(11, defaultBrightCyan);
gci.SetColorTableEntry(TextColor::BRIGHT_BLACK, defaultBrightBlack);
gci.SetColorTableEntry(TextColor::BRIGHT_YELLOW, defaultBrightYellow);
gci.SetColorTableEntry(TextColor::BRIGHT_CYAN, defaultBrightCyan);
// Write (solFg, solBG) X \n
// (solFg, solBG) X (solCyan, solBG) X \n
@ -1405,8 +1405,8 @@ void TextBufferTests::TestResetClearsBoldness()
si.SetAttributes(defaultAttribute);
const auto [defaultFg, defaultBg] = gci.LookupAttributeColors(si.GetAttributes());
const auto dark_green = gci.GetColorTableEntry(2);
const auto bright_green = gci.GetColorTableEntry(10);
const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN);
const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN);
wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD";
Log::Comment(NoThrowString().Format(sequence));

View file

@ -470,7 +470,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the BG----"));
textAttributes.SetIndexedBackground(FOREGROUND_RED);
textAttributes.SetIndexedBackground(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -479,7 +479,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the FG----"));
textAttributes.SetIndexedForeground(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
textAttributes.SetIndexedForeground(TextColor::DARK_WHITE);
qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -515,7 +515,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the FG to a 256-color index----"));
textAttributes.SetIndexedForeground256(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE);
qExpectedInput.push_back("\x1b[38;5;7m"); // Foreground DARK_WHITE (256-Color Index)
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -524,7 +524,7 @@ void VtRendererTest::Xterm256TestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the BG to a 256-color index----"));
textAttributes.SetIndexedBackground256(FOREGROUND_RED);
textAttributes.SetIndexedBackground256(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[48;5;1m"); // Background DARK_RED (256-Color Index)
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -859,7 +859,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Foreground----");
textAttributes.SetIndexedForeground(FOREGROUND_GREEN);
textAttributes.SetIndexedForeground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[32m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -870,7 +870,7 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Background----");
textAttributes.SetIndexedBackground(FOREGROUND_GREEN);
textAttributes.SetIndexedBackground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[42m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -1104,7 +1104,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the BG----"));
textAttributes.SetIndexedBackground(FOREGROUND_RED);
textAttributes.SetIndexedBackground(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -1113,7 +1113,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the FG----"));
textAttributes.SetIndexedForeground(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
textAttributes.SetIndexedForeground(TextColor::DARK_WHITE);
qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -1150,7 +1150,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the FG to a 256-color index----"));
textAttributes.SetIndexedForeground256(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
textAttributes.SetIndexedForeground256(TextColor::DARK_WHITE);
qExpectedInput.push_back("\x1b[37m"); // Foreground DARK_WHITE
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -1159,7 +1159,7 @@ void VtRendererTest::XtermTestColors()
Log::Comment(NoThrowString().Format(
L"----Change only the BG to a 256-color index----"));
textAttributes.SetIndexedBackground256(FOREGROUND_RED);
textAttributes.SetIndexedBackground256(TextColor::DARK_RED);
qExpectedInput.push_back("\x1b[41m"); // Background DARK_RED
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes,
&renderData,
@ -1351,7 +1351,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Foreground----");
textAttributes.SetIndexedForeground(FOREGROUND_GREEN);
textAttributes.SetIndexedForeground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[32m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
@ -1362,7 +1362,7 @@ void VtRendererTest::XtermTestAttributesAcrossReset()
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));
Log::Comment(L"----Set Green Background----");
textAttributes.SetIndexedBackground(FOREGROUND_GREEN);
textAttributes.SetIndexedBackground(TextColor::DARK_GREEN);
qExpectedInput.push_back("\x1b[42m");
VERIFY_SUCCEEDED(engine->UpdateDrawingBrushes(textAttributes, &renderData, false, false));

View file

@ -22,20 +22,6 @@ enum class ExtendedAttributes : BYTE
};
DEFINE_ENUM_FLAG_OPERATORS(ExtendedAttributes);
WORD XtermToWindowsIndex(const size_t index) noexcept;
WORD Xterm256ToWindowsIndex(const size_t index) noexcept;
WORD XtermToLegacy(const size_t xtermForeground, const size_t xtermBackground);
constexpr WORD WINDOWS_RED_ATTR = FOREGROUND_RED;
constexpr WORD WINDOWS_GREEN_ATTR = FOREGROUND_GREEN;
constexpr WORD WINDOWS_BLUE_ATTR = FOREGROUND_BLUE;
constexpr WORD WINDOWS_BRIGHT_ATTR = FOREGROUND_INTENSITY;
constexpr WORD XTERM_RED_ATTR = 0x01;
constexpr WORD XTERM_GREEN_ATTR = 0x02;
constexpr WORD XTERM_BLUE_ATTR = 0x04;
constexpr WORD XTERM_BRIGHT_ATTR = 0x08;
enum class CursorType : unsigned int
{
Legacy = 0x0, // uses the cursor's height value to range from underscore-like to full box

View file

@ -132,9 +132,9 @@ public:
0,
nullptr,
0,
nullptr,
L"",
initialData);
initialData,
nullptr);
gci.SetCookedReadData(readData);
}

View file

@ -208,7 +208,11 @@ void Clipboard::StoreSelectionToClipboard(bool const copyFormatting)
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
const auto& buffer = gci.GetActiveOutputBuffer().GetTextBuffer();
const auto GetAttributeColors = std::bind(&CONSOLE_INFORMATION::LookupAttributeColors, &gci, std::placeholders::_1);
const auto defaultForeground = gci.GetDefaultForeground();
const auto defaultBackground = gci.GetDefaultBackground();
const auto GetAttributeColors = [=, &gci](const auto& attr) {
return gci.LookupAttributeColors(attr, defaultForeground, defaultBackground);
};
bool includeCRLF, trimTrailingWhitespace;
if (WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED))

View file

@ -337,7 +337,7 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults)
for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++)
{
pStateInfo->ColorTable[i] = gci.GetColorTableEntry(i);
pStateInfo->ColorTable[i] = gci.GetLegacyColorTableEntry(i);
}
// Create mutable copies of the titles so the propsheet can do something with them.
@ -566,7 +566,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++)
{
gci.SetColorTableEntry(i, pStateInfo->ColorTable[i]);
gci.SetLegacyColorTableEntry(i, pStateInfo->ColorTable[i]);
}
// Ensure that attributes only contain color specification.

View file

@ -49,6 +49,7 @@ INCLUDES= \
$(CONSOLE_SRC_PATH)\..\oss\fmt\include; \
$(CONSOLE_SRC_PATH)\..\oss\interval_tree; \
$(CONSOLE_SRC_PATH)\..\oss\boost\boost_1_73_0; \
$(CONSOLE_SRC_PATH)\..\oss\pcg\include; \
$(MINWIN_INTERNAL_PRIV_SDK_INC_PATH_L); \
$(MINWIN_RESTRICTED_PRIV_SDK_INC_PATH_L); \
$(MINCORE_INTERNAL_PRIV_SDK_INC_PATH_L); \

View file

@ -199,13 +199,14 @@ using namespace Microsoft::Console::Render;
}
// Method Description:
// - Formats and writes a sequence to change the current text attributes.
// - Formats and writes a sequence to change the current text attributes to an
// indexed color from the 16-color table.
// Arguments:
// - wAttr: Windows color table index to emit as a VT sequence
// - index: color table index to emit as a VT sequence
// - fIsForeground: true if we should emit the foreground sequence, false for background
// Return Value:
// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition16Color(const WORD wAttr,
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition16Color(const BYTE index,
const bool fIsForeground) noexcept
{
// Always check using the foreground flags, because the bg flags constants
@ -220,28 +221,22 @@ using namespace Microsoft::Console::Render;
// terminals display the bright color when displaying bolded text.
// By specifying the boldness and brightness separately, we'll make sure the
// terminal has an accurate representation of our buffer.
const int vtIndex = 30 +
(fIsForeground ? 0 : 10) +
((WI_IsFlagSet(wAttr, FOREGROUND_INTENSITY)) ? 60 : 0) +
(WI_IsFlagSet(wAttr, FOREGROUND_RED) ? 1 : 0) +
(WI_IsFlagSet(wAttr, FOREGROUND_GREEN) ? 2 : 0) +
(WI_IsFlagSet(wAttr, FOREGROUND_BLUE) ? 4 : 0);
return _WriteFormatted(FMT_COMPILE("\x1b[{}m"), vtIndex);
const auto prefix = WI_IsFlagSet(index, FOREGROUND_INTENSITY) ? (fIsForeground ? 90 : 100) : (fIsForeground ? 30 : 40);
return _WriteFormatted(FMT_COMPILE("\x1b[{}m"), prefix + (index & 7));
}
// Method Description:
// - Formats and writes a sequence to change the current text attributes to an
// indexed color from the 256-color table.
// Arguments:
// - wAttr: Windows color table index to emit as a VT sequence
// - index: color table index to emit as a VT sequence
// - fIsForeground: true if we should emit the foreground sequence, false for background
// Return Value:
// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition256Color(const WORD index,
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition256Color(const BYTE index,
const bool fIsForeground) noexcept
{
return _WriteFormatted(FMT_COMPILE("\x1b[{}8;5;{}m"), fIsForeground ? '3' : '4', ::Xterm256ToWindowsIndex(index));
return _WriteFormatted(FMT_COMPILE("\x1b[{}8;5;{}m"), fIsForeground ? '3' : '4', index);
}
// Method Description:

View file

@ -287,9 +287,10 @@ using namespace Microsoft::Console::Types;
}
// We use the legacy color calculations to generate an approximation of the
// colors in the 16-color table.
auto fgIndex = fg.GetLegacyIndex(0);
auto bgIndex = bg.GetLegacyIndex(0);
// colors in the Windows 16-color table, but we need to transpose those
// values to obtain an index in an ANSI-compatible order.
auto fgIndex = TextColor::TransposeLegacyIndex(fg.GetLegacyIndex(0));
auto bgIndex = TextColor::TransposeLegacyIndex(bg.GetLegacyIndex(0));
// If the bold attribute is set, and the foreground can be brightened, then do so.
const bool brighten = textAttributes.IsBold() && fg.CanBeBrightened();

View file

@ -185,9 +185,9 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT _ClearScreen() noexcept;
[[nodiscard]] HRESULT _ClearScrollback() noexcept;
[[nodiscard]] HRESULT _ChangeTitle(const std::string& title) noexcept;
[[nodiscard]] HRESULT _SetGraphicsRendition16Color(const WORD wAttr,
[[nodiscard]] HRESULT _SetGraphicsRendition16Color(const BYTE index,
const bool fIsForeground) noexcept;
[[nodiscard]] HRESULT _SetGraphicsRendition256Color(const WORD index,
[[nodiscard]] HRESULT _SetGraphicsRendition256Color(const BYTE index,
const bool fIsForeground) noexcept;
[[nodiscard]] HRESULT _SetGraphicsRenditionRGBColor(const COLORREF color,
const bool fIsForeground) noexcept;

View file

@ -312,7 +312,7 @@
}
CATCH_RETURN();
// ReadConsole needs this to get the command history list associated with an attached process, but it can be an opaque value.
// ReadConsole needs this to get details associated with an attached process (such as the command history list, telemetry metadata).
HANDLE const hConsoleClient = (HANDLE)m->GetProcessHandle();
// ReadConsole needs this to store context information across "processed reads" e.g. reads on the same handle

View file

@ -432,6 +432,8 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API
gci.ProcessHandleList.FreeProcessData(ProcessData);
}
Tracing::s_TraceConsoleAttachDetach(ProcessData, true);
UnlockConsole();
return nullptr;
@ -470,6 +472,8 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleClientDisconnectRoutine(_In_ PCONSOLE_API
pNotifier->NotifyConsoleEndApplicationEvent(pProcessData->dwProcessId);
}
Tracing::s_TraceConsoleAttachDetach(pProcessData, false);
LOG_IF_FAILED(RemoveConsole(pProcessData));
pMessage->SetReplyStatus(STATUS_SUCCESS);

Some files were not shown because too many files have changed in this diff Show more