From d7061ebfaa85ccf94fabaeddc8e5a216a09dcb3c Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 20 May 2020 15:39:29 -0700 Subject: [PATCH 1/7] naive implementation (but it works) --- src/cascadia/TerminalApp/Profile.cpp | 85 +++++++++++++++++++ src/cascadia/TerminalApp/Profile.h | 12 +++ src/cascadia/TerminalCore/Terminal.cpp | 46 ++++++++++ src/cascadia/TerminalCore/Terminal.hpp | 10 +++ .../TerminalSettings/ICoreSettings.idl | 9 ++ .../TerminalSettings/TerminalSettings.cpp | 10 +++ .../TerminalSettings/terminalsettings.h | 3 + .../UnitTests_TerminalCore/MockTermSettings.h | 2 + src/inc/DefaultSettings.h | 1 + 9 files changed, 178 insertions(+) diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index 736a35d3dfc..cc84b06b05e 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -28,6 +28,7 @@ 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 SnapOnOutputKey{ "snapOnOutput" }; static constexpr std::string_view CursorColorKey{ "cursorColor" }; static constexpr std::string_view CursorShapeKey{ "cursorShape" }; static constexpr std::string_view CursorHeightKey{ "cursorHeight" }; @@ -88,6 +89,12 @@ static constexpr std::wstring_view AntialiasingModeGrayscale{ L"grayscale" }; static constexpr std::wstring_view AntialiasingModeCleartype{ L"cleartype" }; static constexpr std::wstring_view AntialiasingModeAliased{ L"aliased" }; +// Possible values for TextAntialiasingMode +static constexpr std::string_view SnapOnOutputNever{ "never" }; +static constexpr std::string_view SnapOnOutputNoSelection{ "noSelection" }; +static constexpr std::string_view SnapOnOutputAtBottom{ "atBottom" }; +static constexpr std::string_view SnapOnOutputAlways{ "always" }; + Profile::Profile() : Profile(std::nullopt) { @@ -170,6 +177,7 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map(SnapOnOutputFlag::AtBottom) | static_cast(SnapOnOutputFlag::NoSelection); + + if (json.isString()) + { + auto snapOnOutput = json.asString(); + if (snapOnOutput == SnapOnOutputNever) + { + return static_cast(SnapOnOutputFlag::Never); + } + else if (snapOnOutput == SnapOnOutputNoSelection) + { + return static_cast(SnapOnOutputFlag::NoSelection); + } + else if (snapOnOutput == SnapOnOutputAtBottom) + { + return static_cast(SnapOnOutputFlag::AtBottom); + } + else if (snapOnOutput == SnapOnOutputAlways) + { + return static_cast(SnapOnOutputFlag::Always); + } + } + else if (json.isArray()) + { + int32_t result = 0; + for (const auto value : json) + { + const auto snapOnOutput = value.asString(); + if (snapOnOutput == SnapOnOutputNever || snapOnOutput == SnapOnOutputAlways) + { + // these values are not accepted + // this is considered a failure to parse and we fallback to the default value instead + return defaultValue; + } + else if (snapOnOutput == SnapOnOutputNoSelection) + { + result |= static_cast(SnapOnOutputFlag::NoSelection); + } + else if (snapOnOutput == SnapOnOutputAtBottom) + { + result |= static_cast(SnapOnOutputFlag::AtBottom); + } + } + } + + return defaultValue; +} + +std::string_view Profile::_SerializeSnapOnOutput(SnapOnOutputFlag snapOnOutput) +{ + if (snapOnOutput == SnapOnOutputFlag::Never) + { + return SnapOnOutputNever; + } + else if (snapOnOutput == SnapOnOutputFlag::Always) + { + return SnapOnOutputAlways; + } + else if (snapOnOutput == SnapOnOutputFlag::AtBottom) + { + return SnapOnOutputAtBottom; + } + else if (snapOnOutput == SnapOnOutputFlag::NoSelection) + { + return SnapOnOutputNoSelection; + } + return ""; +} + // Method Description: // - Helper function for converting a user-specified scrollbar state to its corresponding enum // Arguments: diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index b6f422c52c5..34421a112d9 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -42,6 +42,14 @@ namespace TerminalApp Graceful, Always }; + + enum class SnapOnOutputFlag + { + Never = -1, + NoSelection = 0x1, + AtBottom = 0x2, + Always = 0x4 + }; }; class TerminalApp::Profile final @@ -117,6 +125,9 @@ class TerminalApp::Profile final static CloseOnExitMode ParseCloseOnExitMode(const Json::Value& json); static std::string_view _SerializeCloseOnExitMode(const CloseOnExitMode closeOnExitMode); + static int32_t ParseSnapOnOutput(const Json::Value& json); + static std::string_view _SerializeSnapOnOutput(SnapOnOutputFlag snapOnOutput); + static std::string_view SerializeImageAlignment(const std::tuple imageAlignment); static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString); static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape); @@ -145,6 +156,7 @@ class TerminalApp::Profile final bool _suppressApplicationTitle; int32_t _historySize; bool _snapOnInput; + int32_t _snapOnOutput; uint32_t _cursorHeight; winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 5b6452f88b0..38606db4315 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -44,6 +44,7 @@ Terminal::Terminal() : _pfnWriteInput{ nullptr }, _scrollOffset{ 0 }, _snapOnInput{ true }, + _snapOnOutput{ SnapOnOutput::NoSelection | SnapOnOutput::AtBottom }, _blockSelection{ false }, _selection{ std::nullopt } { @@ -141,6 +142,8 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting _snapOnInput = settings.SnapOnInput(); + _snapOnOutput = settings.SnapOnOutput(); + _wordDelimiters = settings.WordDelimiters(); _suppressApplicationTitle = settings.SuppressApplicationTitle(); @@ -772,10 +775,19 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) notifyScroll = true; } + // detect if viewport was already at the bottom of the scroll history + // This is used for SnapOnOutput::AtBottom + bool viewportAtBottom = false; + if (cursor.GetPosition().Y <= _mutableViewport.BottomInclusive() - _scrollOffset) + { + viewportAtBottom = true; + } + // Update Cursor Position cursor.SetPosition(proposedCursorPosition); const COORD cursorPosAfter = cursor.GetPosition(); + const auto scrollAmount = std::max(0, cursorPosAfter.Y - _mutableViewport.BottomInclusive()); // Move the viewport down if the cursor moved below the viewport. if (cursorPosAfter.Y > _mutableViewport.BottomInclusive()) @@ -791,11 +803,45 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) if (notifyScroll) { + // modify scrollOffset based on SnapOnOutput value + if (_snapOnOutput == SnapOnOutput::Always) + { + _scrollOffset = 0; + } + else if (_snapOnOutput == SnapOnOutput::Never) + { + _scrollOffset += scrollAmount; + } + + if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::NoSelection)) + { + if (IsSelectionActive()) + { + _scrollOffset += scrollAmount; + } + else + { + _scrollOffset = 0; + } + } + if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::AtBottom)) + { + if (!viewportAtBottom) + { + _scrollOffset += scrollAmount; + } + else + { + _scrollOffset = 0; + } + } + // We have to report the delta here because we might have circled the text buffer. // That didn't change the viewport and therefore the TriggerScroll(void) // method can't detect the delta on its own. COORD delta{ 0, -gsl::narrow(newRows) }; _buffer->GetRenderTarget().TriggerScroll(&delta); + _NotifyScrollEvent(); } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index fd0e70e4db3..7c73bfb0a57 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -209,7 +209,17 @@ class Microsoft::Terminal::Core::Terminal final : COLORREF _defaultFg; COLORREF _defaultBg; + // TODO CARLOS: right now, this is just copied over from ICoreSettings. + // This is to make my life easier. + enum SnapOnOutput + { + Never = -1, + NoSelection = 0x1, + AtBottom = 0x2, + Always = 0x4 + }; bool _snapOnInput; + int _snapOnOutput; bool _suppressApplicationTitle; #pragma region Text Selection diff --git a/src/cascadia/TerminalSettings/ICoreSettings.idl b/src/cascadia/TerminalSettings/ICoreSettings.idl index 305d85adb55..4763ad4050e 100644 --- a/src/cascadia/TerminalSettings/ICoreSettings.idl +++ b/src/cascadia/TerminalSettings/ICoreSettings.idl @@ -12,6 +12,14 @@ namespace Microsoft.Terminal.Settings EmptyBox }; + enum SnapOnOutputFlag + { + Never = -1, + NoSelection = 0x1, + AtBottom = 0x2, + Always = 0x4 + }; + interface ICoreSettings { UInt32 DefaultForeground; @@ -25,6 +33,7 @@ namespace Microsoft.Terminal.Settings Int32 RowsToScroll; Boolean SnapOnInput; + Int32 SnapOnOutput; UInt32 CursorColor; CursorStyle CursorShape; diff --git a/src/cascadia/TerminalSettings/TerminalSettings.cpp b/src/cascadia/TerminalSettings/TerminalSettings.cpp index 45174a5c85b..3147916c6a4 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettings/TerminalSettings.cpp @@ -148,6 +148,16 @@ namespace winrt::Microsoft::Terminal::Settings::implementation _snapOnInput = value; } + int32_t TerminalSettings::SnapOnOutput() noexcept + { + return _snapOnOutput; + } + + void TerminalSettings::SnapOnOutput(int32_t value) noexcept + { + _snapOnOutput = value; + } + uint32_t TerminalSettings::CursorColor() noexcept { return _cursorColor; diff --git a/src/cascadia/TerminalSettings/terminalsettings.h b/src/cascadia/TerminalSettings/terminalsettings.h index 6fa5c16dc9f..bc738e0d870 100644 --- a/src/cascadia/TerminalSettings/terminalsettings.h +++ b/src/cascadia/TerminalSettings/terminalsettings.h @@ -43,6 +43,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation void RowsToScroll(int32_t value) noexcept; bool SnapOnInput() noexcept; void SnapOnInput(bool value) noexcept; + int32_t SnapOnOutput() noexcept; + void SnapOnOutput(int32_t value) noexcept; uint32_t CursorColor() noexcept; void CursorColor(uint32_t value) noexcept; CursorStyle CursorShape() const noexcept; @@ -123,6 +125,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation int32_t _initialCols; int32_t _rowsToScroll; bool _snapOnInput; + int32_t _snapOnOutput; uint32_t _cursorColor; Settings::CursorStyle _cursorShape; uint32_t _cursorHeight; diff --git a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h index 6866caea39a..4c34ce45715 100644 --- a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h +++ b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h @@ -29,6 +29,7 @@ namespace TerminalCoreUnitTests uint32_t DefaultForeground() { return COLOR_WHITE; } uint32_t DefaultBackground() { return COLOR_BLACK; } bool SnapOnInput() { return false; } + int32_t SnapOnOutput() { return DEFAULT_SNAP_ON_OUTPUT; } uint32_t CursorColor() { return COLOR_WHITE; } CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; } uint32_t CursorHeight() { return 42UL; } @@ -49,6 +50,7 @@ namespace TerminalCoreUnitTests void DefaultForeground(uint32_t) {} void DefaultBackground(uint32_t) {} void SnapOnInput(bool) {} + void SnapOnOutput(int32_t) {} void CursorColor(uint32_t) {} void CursorShape(CursorStyle const&) noexcept {} void CursorHeight(uint32_t) {} diff --git a/src/inc/DefaultSettings.h b/src/inc/DefaultSettings.h index 71946cc072d..2841d821d00 100644 --- a/src/inc/DefaultSettings.h +++ b/src/inc/DefaultSettings.h @@ -42,4 +42,5 @@ constexpr COLORREF DEFAULT_CURSOR_COLOR = COLOR_WHITE; constexpr COLORREF DEFAULT_CURSOR_HEIGHT = 25; const std::wstring DEFAULT_WORD_DELIMITERS{ L" ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502" }; +constexpr int32_t DEFAULT_SNAP_ON_OUTPUT = 0x1 | 0x2; #pragma warning(pop) From 89bc4d53cd41ab872c487547e5bf6a653e278ee5 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 20 May 2020 16:03:06 -0700 Subject: [PATCH 2/7] add behavior for multiple flags --- src/cascadia/TerminalApp/Profile.cpp | 1 + src/cascadia/TerminalCore/Terminal.cpp | 32 +++++++++++--------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index cc84b06b05e..a7722ea09b7 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -114,6 +114,7 @@ Profile::Profile(const std::optional& guid) : _suppressApplicationTitle{}, _historySize{ DEFAULT_HISTORY_SIZE }, _snapOnInput{ true }, + _snapOnOutput{ DEFAULT_SNAP_ON_OUTPUT }, _cursorShape{ CursorStyle::Bar }, _cursorHeight{ DEFAULT_CURSOR_HEIGHT }, diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 38606db4315..5e0d18ea0e7 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -803,39 +803,35 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) if (notifyScroll) { + // scrollToOutput: + // - true: we want the visible viewport to show the new output + // - false: keep the visible viewport in its current position + bool scrollToOutput = true; + // modify scrollOffset based on SnapOnOutput value if (_snapOnOutput == SnapOnOutput::Always) { - _scrollOffset = 0; + scrollToOutput = true; } else if (_snapOnOutput == SnapOnOutput::Never) { - _scrollOffset += scrollAmount; + scrollToOutput = false; } + // IMPORTANT: we need to use && below. This allows multiple of these flags to be set if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::NoSelection)) { - if (IsSelectionActive()) - { - _scrollOffset += scrollAmount; - } - else - { - _scrollOffset = 0; - } + // scroll if no selection is active + scrollToOutput = scrollToOutput && !IsSelectionActive(); } if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::AtBottom)) { - if (!viewportAtBottom) - { - _scrollOffset += scrollAmount; - } - else - { - _scrollOffset = 0; - } + scrollToOutput = scrollToOutput && viewportAtBottom; } + // use scrollToOutput to enforce SnapOnInput + _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount; + // We have to report the delta here because we might have circled the text buffer. // That didn't change the viewport and therefore the TriggerScroll(void) // method can't detect the delta on its own. From 287dd6b4edc0f43d65b6ad9410a17a5f08bfacaf Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 20 May 2020 16:43:19 -0700 Subject: [PATCH 3/7] now this works with the circling buffer! --- src/cascadia/TerminalCore/Terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 5e0d18ea0e7..9c5c42aa2b7 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -830,7 +830,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) } // use scrollToOutput to enforce SnapOnInput - _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount; + _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount + newRows; // We have to report the delta here because we might have circled the text buffer. // That didn't change the viewport and therefore the TriggerScroll(void) From 6a4c4e3f2c2bc45376965577a271cce6a8d16c19 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 20 May 2020 17:01:27 -0700 Subject: [PATCH 4/7] remove my lazy enum approach --- src/cascadia/TerminalApp/Profile.h | 10 +--------- src/cascadia/TerminalCore/Terminal.cpp | 10 +++++----- src/cascadia/TerminalCore/Terminal.hpp | 9 --------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 34421a112d9..e331494a2fc 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -42,14 +42,6 @@ namespace TerminalApp Graceful, Always }; - - enum class SnapOnOutputFlag - { - Never = -1, - NoSelection = 0x1, - AtBottom = 0x2, - Always = 0x4 - }; }; class TerminalApp::Profile final @@ -126,7 +118,7 @@ class TerminalApp::Profile final static std::string_view _SerializeCloseOnExitMode(const CloseOnExitMode closeOnExitMode); static int32_t ParseSnapOnOutput(const Json::Value& json); - static std::string_view _SerializeSnapOnOutput(SnapOnOutputFlag snapOnOutput); + static std::string_view _SerializeSnapOnOutput(winrt::Microsoft::Terminal::Settings::SnapOnOutputFlag snapOnOutput); static std::string_view SerializeImageAlignment(const std::tuple imageAlignment); static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString); diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 9c5c42aa2b7..bb0c25e0395 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -44,7 +44,7 @@ Terminal::Terminal() : _pfnWriteInput{ nullptr }, _scrollOffset{ 0 }, _snapOnInput{ true }, - _snapOnOutput{ SnapOnOutput::NoSelection | SnapOnOutput::AtBottom }, + _snapOnOutput{ static_cast(SnapOnOutputFlag::NoSelection) | static_cast(SnapOnOutputFlag::AtBottom) }, _blockSelection{ false }, _selection{ std::nullopt } { @@ -809,22 +809,22 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) bool scrollToOutput = true; // modify scrollOffset based on SnapOnOutput value - if (_snapOnOutput == SnapOnOutput::Always) + if (_snapOnOutput == static_cast(SnapOnOutputFlag::Always)) { scrollToOutput = true; } - else if (_snapOnOutput == SnapOnOutput::Never) + else if (_snapOnOutput == static_cast(SnapOnOutputFlag::Never)) { scrollToOutput = false; } // IMPORTANT: we need to use && below. This allows multiple of these flags to be set - if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::NoSelection)) + if (WI_IsFlagSet(_snapOnOutput, static_cast(SnapOnOutputFlag::NoSelection))) { // scroll if no selection is active scrollToOutput = scrollToOutput && !IsSelectionActive(); } - if (WI_IsFlagSet(_snapOnOutput, SnapOnOutput::AtBottom)) + if (WI_IsFlagSet(_snapOnOutput, static_cast(SnapOnOutputFlag::AtBottom))) { scrollToOutput = scrollToOutput && viewportAtBottom; } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 7c73bfb0a57..12a602f1311 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -209,15 +209,6 @@ class Microsoft::Terminal::Core::Terminal final : COLORREF _defaultFg; COLORREF _defaultBg; - // TODO CARLOS: right now, this is just copied over from ICoreSettings. - // This is to make my life easier. - enum SnapOnOutput - { - Never = -1, - NoSelection = 0x1, - AtBottom = 0x2, - Always = 0x4 - }; bool _snapOnInput; int _snapOnOutput; bool _suppressApplicationTitle; From d092e39b1d7be1a46f42a7510eb605c1538422eb Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 20 May 2020 17:12:34 -0700 Subject: [PATCH 5/7] update the schema --- doc/cascadia/profiles.schema.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 8ebcb9746e4..bd4f02eb80f 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -588,6 +588,33 @@ "description": "When set to true, the window will scroll to the command input line when typing. When set to false, the window will not scroll when you start typing.", "type": "boolean" }, + "snapOnOutput": { + "default": [ "noSelection", "atBottom"], + "description": "Controls the terminal's scroll response to new output. Possible values include:\n -\"always\"\n -\"atBottom\"\n -\"noSelection\"\n -\"never\"\nMultiple can be enforced in an array format.", + "oneOf": [ + { + "type": "string", + "enum": [ + "always", + "atBottom", + "noSelection", + "never" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "always", + "atBottom", + "noSelection", + "never" + ] + } + } + ] + }, "source": { "description": "Stores the name of the profile generator that originated this profile.", "type": ["string", "null"] From f7ba29bfca32490c47ab9dfc19dcd5be5f59a8d4 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 7 Jul 2020 13:49:49 -0700 Subject: [PATCH 6/7] remove configurability --- doc/cascadia/profiles.schema.json | 27 ------ src/cascadia/TerminalApp/Profile.cpp | 86 ------------------- src/cascadia/TerminalApp/Profile.h | 4 - src/cascadia/TerminalCore/Terminal.cpp | 34 +------- src/cascadia/TerminalCore/Terminal.hpp | 1 - .../TerminalSettings/ICoreSettings.idl | 9 -- .../TerminalSettings/TerminalSettings.cpp | 10 --- .../TerminalSettings/terminalsettings.h | 3 - .../UnitTests_TerminalCore/MockTermSettings.h | 2 - src/inc/DefaultSettings.h | 1 - 10 files changed, 4 insertions(+), 173 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index bd4f02eb80f..8ebcb9746e4 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -588,33 +588,6 @@ "description": "When set to true, the window will scroll to the command input line when typing. When set to false, the window will not scroll when you start typing.", "type": "boolean" }, - "snapOnOutput": { - "default": [ "noSelection", "atBottom"], - "description": "Controls the terminal's scroll response to new output. Possible values include:\n -\"always\"\n -\"atBottom\"\n -\"noSelection\"\n -\"never\"\nMultiple can be enforced in an array format.", - "oneOf": [ - { - "type": "string", - "enum": [ - "always", - "atBottom", - "noSelection", - "never" - ] - }, - { - "type": "array", - "items": { - "type": "string", - "enum": [ - "always", - "atBottom", - "noSelection", - "never" - ] - } - } - ] - }, "source": { "description": "Stores the name of the profile generator that originated this profile.", "type": ["string", "null"] diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index a7722ea09b7..736a35d3dfc 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -28,7 +28,6 @@ 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 SnapOnOutputKey{ "snapOnOutput" }; static constexpr std::string_view CursorColorKey{ "cursorColor" }; static constexpr std::string_view CursorShapeKey{ "cursorShape" }; static constexpr std::string_view CursorHeightKey{ "cursorHeight" }; @@ -89,12 +88,6 @@ static constexpr std::wstring_view AntialiasingModeGrayscale{ L"grayscale" }; static constexpr std::wstring_view AntialiasingModeCleartype{ L"cleartype" }; static constexpr std::wstring_view AntialiasingModeAliased{ L"aliased" }; -// Possible values for TextAntialiasingMode -static constexpr std::string_view SnapOnOutputNever{ "never" }; -static constexpr std::string_view SnapOnOutputNoSelection{ "noSelection" }; -static constexpr std::string_view SnapOnOutputAtBottom{ "atBottom" }; -static constexpr std::string_view SnapOnOutputAlways{ "always" }; - Profile::Profile() : Profile(std::nullopt) { @@ -114,7 +107,6 @@ Profile::Profile(const std::optional& guid) : _suppressApplicationTitle{}, _historySize{ DEFAULT_HISTORY_SIZE }, _snapOnInput{ true }, - _snapOnOutput{ DEFAULT_SNAP_ON_OUTPUT }, _cursorShape{ CursorStyle::Bar }, _cursorHeight{ DEFAULT_CURSOR_HEIGHT }, @@ -178,7 +170,6 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map(SnapOnOutputFlag::AtBottom) | static_cast(SnapOnOutputFlag::NoSelection); - - if (json.isString()) - { - auto snapOnOutput = json.asString(); - if (snapOnOutput == SnapOnOutputNever) - { - return static_cast(SnapOnOutputFlag::Never); - } - else if (snapOnOutput == SnapOnOutputNoSelection) - { - return static_cast(SnapOnOutputFlag::NoSelection); - } - else if (snapOnOutput == SnapOnOutputAtBottom) - { - return static_cast(SnapOnOutputFlag::AtBottom); - } - else if (snapOnOutput == SnapOnOutputAlways) - { - return static_cast(SnapOnOutputFlag::Always); - } - } - else if (json.isArray()) - { - int32_t result = 0; - for (const auto value : json) - { - const auto snapOnOutput = value.asString(); - if (snapOnOutput == SnapOnOutputNever || snapOnOutput == SnapOnOutputAlways) - { - // these values are not accepted - // this is considered a failure to parse and we fallback to the default value instead - return defaultValue; - } - else if (snapOnOutput == SnapOnOutputNoSelection) - { - result |= static_cast(SnapOnOutputFlag::NoSelection); - } - else if (snapOnOutput == SnapOnOutputAtBottom) - { - result |= static_cast(SnapOnOutputFlag::AtBottom); - } - } - } - - return defaultValue; -} - -std::string_view Profile::_SerializeSnapOnOutput(SnapOnOutputFlag snapOnOutput) -{ - if (snapOnOutput == SnapOnOutputFlag::Never) - { - return SnapOnOutputNever; - } - else if (snapOnOutput == SnapOnOutputFlag::Always) - { - return SnapOnOutputAlways; - } - else if (snapOnOutput == SnapOnOutputFlag::AtBottom) - { - return SnapOnOutputAtBottom; - } - else if (snapOnOutput == SnapOnOutputFlag::NoSelection) - { - return SnapOnOutputNoSelection; - } - return ""; -} - // Method Description: // - Helper function for converting a user-specified scrollbar state to its corresponding enum // Arguments: diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index e331494a2fc..b6f422c52c5 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -117,9 +117,6 @@ class TerminalApp::Profile final static CloseOnExitMode ParseCloseOnExitMode(const Json::Value& json); static std::string_view _SerializeCloseOnExitMode(const CloseOnExitMode closeOnExitMode); - static int32_t ParseSnapOnOutput(const Json::Value& json); - static std::string_view _SerializeSnapOnOutput(winrt::Microsoft::Terminal::Settings::SnapOnOutputFlag snapOnOutput); - static std::string_view SerializeImageAlignment(const std::tuple imageAlignment); static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString); static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape); @@ -148,7 +145,6 @@ class TerminalApp::Profile final bool _suppressApplicationTitle; int32_t _historySize; bool _snapOnInput; - int32_t _snapOnOutput; uint32_t _cursorHeight; winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index bb0c25e0395..996b7a92dee 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -44,7 +44,6 @@ Terminal::Terminal() : _pfnWriteInput{ nullptr }, _scrollOffset{ 0 }, _snapOnInput{ true }, - _snapOnOutput{ static_cast(SnapOnOutputFlag::NoSelection) | static_cast(SnapOnOutputFlag::AtBottom) }, _blockSelection{ false }, _selection{ std::nullopt } { @@ -142,8 +141,6 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting _snapOnInput = settings.SnapOnInput(); - _snapOnOutput = settings.SnapOnOutput(); - _wordDelimiters = settings.WordDelimiters(); _suppressApplicationTitle = settings.SuppressApplicationTitle(); @@ -776,7 +773,6 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) } // detect if viewport was already at the bottom of the scroll history - // This is used for SnapOnOutput::AtBottom bool viewportAtBottom = false; if (cursor.GetPosition().Y <= _mutableViewport.BottomInclusive() - _scrollOffset) { @@ -803,33 +799,11 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) if (notifyScroll) { - // scrollToOutput: - // - true: we want the visible viewport to show the new output - // - false: keep the visible viewport in its current position - bool scrollToOutput = true; - - // modify scrollOffset based on SnapOnOutput value - if (_snapOnOutput == static_cast(SnapOnOutputFlag::Always)) - { - scrollToOutput = true; - } - else if (_snapOnOutput == static_cast(SnapOnOutputFlag::Never)) - { - scrollToOutput = false; - } - - // IMPORTANT: we need to use && below. This allows multiple of these flags to be set - if (WI_IsFlagSet(_snapOnOutput, static_cast(SnapOnOutputFlag::NoSelection))) - { - // scroll if no selection is active - scrollToOutput = scrollToOutput && !IsSelectionActive(); - } - if (WI_IsFlagSet(_snapOnOutput, static_cast(SnapOnOutputFlag::AtBottom))) - { - scrollToOutput = scrollToOutput && viewportAtBottom; - } + // scroll if... + // - no selection is active + // - viewport is already at the bottom + const bool scrollToOutput = !IsSelectionActive() && viewportAtBottom; - // use scrollToOutput to enforce SnapOnInput _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount + newRows; // We have to report the delta here because we might have circled the text buffer. diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 12a602f1311..fd0e70e4db3 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -210,7 +210,6 @@ class Microsoft::Terminal::Core::Terminal final : COLORREF _defaultBg; bool _snapOnInput; - int _snapOnOutput; bool _suppressApplicationTitle; #pragma region Text Selection diff --git a/src/cascadia/TerminalSettings/ICoreSettings.idl b/src/cascadia/TerminalSettings/ICoreSettings.idl index 4763ad4050e..305d85adb55 100644 --- a/src/cascadia/TerminalSettings/ICoreSettings.idl +++ b/src/cascadia/TerminalSettings/ICoreSettings.idl @@ -12,14 +12,6 @@ namespace Microsoft.Terminal.Settings EmptyBox }; - enum SnapOnOutputFlag - { - Never = -1, - NoSelection = 0x1, - AtBottom = 0x2, - Always = 0x4 - }; - interface ICoreSettings { UInt32 DefaultForeground; @@ -33,7 +25,6 @@ namespace Microsoft.Terminal.Settings Int32 RowsToScroll; Boolean SnapOnInput; - Int32 SnapOnOutput; UInt32 CursorColor; CursorStyle CursorShape; diff --git a/src/cascadia/TerminalSettings/TerminalSettings.cpp b/src/cascadia/TerminalSettings/TerminalSettings.cpp index 3147916c6a4..45174a5c85b 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettings/TerminalSettings.cpp @@ -148,16 +148,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation _snapOnInput = value; } - int32_t TerminalSettings::SnapOnOutput() noexcept - { - return _snapOnOutput; - } - - void TerminalSettings::SnapOnOutput(int32_t value) noexcept - { - _snapOnOutput = value; - } - uint32_t TerminalSettings::CursorColor() noexcept { return _cursorColor; diff --git a/src/cascadia/TerminalSettings/terminalsettings.h b/src/cascadia/TerminalSettings/terminalsettings.h index bc738e0d870..6fa5c16dc9f 100644 --- a/src/cascadia/TerminalSettings/terminalsettings.h +++ b/src/cascadia/TerminalSettings/terminalsettings.h @@ -43,8 +43,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation void RowsToScroll(int32_t value) noexcept; bool SnapOnInput() noexcept; void SnapOnInput(bool value) noexcept; - int32_t SnapOnOutput() noexcept; - void SnapOnOutput(int32_t value) noexcept; uint32_t CursorColor() noexcept; void CursorColor(uint32_t value) noexcept; CursorStyle CursorShape() const noexcept; @@ -125,7 +123,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation int32_t _initialCols; int32_t _rowsToScroll; bool _snapOnInput; - int32_t _snapOnOutput; uint32_t _cursorColor; Settings::CursorStyle _cursorShape; uint32_t _cursorHeight; diff --git a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h index 4c34ce45715..6866caea39a 100644 --- a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h +++ b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h @@ -29,7 +29,6 @@ namespace TerminalCoreUnitTests uint32_t DefaultForeground() { return COLOR_WHITE; } uint32_t DefaultBackground() { return COLOR_BLACK; } bool SnapOnInput() { return false; } - int32_t SnapOnOutput() { return DEFAULT_SNAP_ON_OUTPUT; } uint32_t CursorColor() { return COLOR_WHITE; } CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; } uint32_t CursorHeight() { return 42UL; } @@ -50,7 +49,6 @@ namespace TerminalCoreUnitTests void DefaultForeground(uint32_t) {} void DefaultBackground(uint32_t) {} void SnapOnInput(bool) {} - void SnapOnOutput(int32_t) {} void CursorColor(uint32_t) {} void CursorShape(CursorStyle const&) noexcept {} void CursorHeight(uint32_t) {} diff --git a/src/inc/DefaultSettings.h b/src/inc/DefaultSettings.h index 2841d821d00..71946cc072d 100644 --- a/src/inc/DefaultSettings.h +++ b/src/inc/DefaultSettings.h @@ -42,5 +42,4 @@ constexpr COLORREF DEFAULT_CURSOR_COLOR = COLOR_WHITE; constexpr COLORREF DEFAULT_CURSOR_HEIGHT = 25; const std::wstring DEFAULT_WORD_DELIMITERS{ L" ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502" }; -constexpr int32_t DEFAULT_SNAP_ON_OUTPUT = 0x1 | 0x2; #pragma warning(pop) From 2b8c38068c64bd04f5330fa851b31279d16df20d Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 7 Jul 2020 16:35:28 -0700 Subject: [PATCH 7/7] just use scrollOffset to detect if 'at bottom' --- src/cascadia/TerminalCore/Terminal.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index d7608750c34..4bf52299801 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -799,13 +799,6 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) } } - // detect if viewport was already at the bottom of the scroll history - bool viewportAtBottom = false; - if (cursor.GetPosition().Y <= _mutableViewport.BottomInclusive() - _scrollOffset) - { - viewportAtBottom = true; - } - // Update Cursor Position cursor.SetPosition(proposedCursorPosition); @@ -828,7 +821,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) // scroll if... // - no selection is active // - viewport is already at the bottom - const bool scrollToOutput = !IsSelectionActive() && viewportAtBottom; + const bool scrollToOutput = !IsSelectionActive() && _scrollOffset == 0; _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount + newRows;