diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index bffa0ed9156..b434a808387 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -40,6 +40,7 @@ static constexpr std::string_view IconKey{ "icon" }; static constexpr std::string_view BackgroundImageKey{ "backgroundImage" }; static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" }; static constexpr std::string_view BackgroundimageStretchModeKey{ "backgroundImageStretchMode" }; +static constexpr std::string_view TripleClickSelectionModeKey{ "tripleClickSelectionMode" }; // Possible values for Scrollbar state static constexpr std::wstring_view AlwaysVisible{ L"visible" }; @@ -58,6 +59,11 @@ static constexpr std::string_view ImageStretchModeFill{ "fill" }; static constexpr std::string_view ImageStretchModeUniform{ "uniform" }; static constexpr std::string_view ImageStretchModeUniformTofill{ "uniformToFill" }; +// Possible values for Triple Click Selection Mode +static constexpr std::wstring_view TripleClickSelectionModeDisabled{ L"disabled" }; +static constexpr std::wstring_view TripleClickSelectionModeLine{ L"line" }; +static constexpr std::wstring_view TripleClickSelectionModeViewport{ L"viewport" }; + Profile::Profile() : Profile(Utils::CreateGuid()) { @@ -76,6 +82,7 @@ Profile::Profile(const winrt::guid& guid) : _cursorColor{ DEFAULT_CURSOR_COLOR }, _cursorShape{ CursorStyle::Bar }, _cursorHeight{ DEFAULT_CURSOR_HEIGHT }, + _tripleClickSelectionMode{ TripleClickSelectionMode::Line }, _commandline{ L"cmd.exe" }, _startingDirectory{}, @@ -144,6 +151,7 @@ TerminalSettings Profile::CreateTerminalSettings(const std::vector& terminalSettings.CursorColor(_cursorColor); terminalSettings.CursorHeight(_cursorHeight); terminalSettings.CursorShape(_cursorShape); + terminalSettings.TripleClickSelectionMode(_tripleClickSelectionMode); // Fill in the remaining properties from the profile terminalSettings.UseAcrylic(_useAcrylic); @@ -249,6 +257,7 @@ Json::Value Profile::ToJson() const root[JsonKey(CursorHeightKey)] = _cursorHeight; } root[JsonKey(CursorShapeKey)] = winrt::to_string(_SerializeCursorStyle(_cursorShape)); + root[JsonKey(TripleClickSelectionModeKey)] = winrt::to_string(_SerializeTripleClickSelectionMode(_tripleClickSelectionMode)); ///// Control Settings ///// root[JsonKey(CommandlineKey)] = winrt::to_string(_commandline); @@ -369,6 +378,10 @@ Profile Profile::FromJson(const Json::Value& json) { result._cursorShape = _ParseCursorShape(GetWstringFromJson(cursorShape)); } + if (auto tripleClickSelectionMode{ json[JsonKey(TripleClickSelectionModeKey)] }) + { + result._tripleClickSelectionMode = _ParseTripleClickSelectionMode(GetWstringFromJson(tripleClickSelectionMode)); + } // Control Settings if (auto commandline{ json[JsonKey(CommandlineKey)] }) @@ -673,3 +686,44 @@ std::wstring_view Profile::_SerializeCursorStyle(const CursorStyle cursorShape) return CursorShapeBar; } } + +// Method Description: +// - Helper function for converting a user-specified triple click selection mode to the corresponding +// TripleClickSelectionMode enum value +// Arguments: +// - selectionModeString: The string value from the settings file to parse +// Return Value: +// - The corresponding enum value which maps to the string provided by the user +winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode Profile::_ParseTripleClickSelectionMode(const std::wstring& selectionModeString) +{ + if (selectionModeString == TripleClickSelectionModeDisabled) + { + return winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::Disabled; + } + else if (selectionModeString == TripleClickSelectionModeViewport) + { + return winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::VisibleViewport; + } + return winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::Line; +} + +// Method Description: +// - Helper function for converting a TripleClickSelectionMode to its corresponding string +// value. +// Arguments: +// - selectionMode: The enum value to convert to a string. +// Return Value: +// - The string value for the given TripleClickSelectionMode +std::wstring_view Profile::_SerializeTripleClickSelectionMode(const winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode selectionMode) +{ + switch (selectionMode) + { + case winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::Disabled: + return TripleClickSelectionModeDisabled; + case winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::VisibleViewport: + return TripleClickSelectionModeViewport; + case winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode::Line: + default: + return TripleClickSelectionModeLine; + } +} diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 938bbf7fa36..dcdfa0ca966 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -61,6 +61,8 @@ class TerminalApp::Profile final static std::string_view SerializeImageStretchMode(const winrt::Windows::UI::Xaml::Media::Stretch imageStretchMode); static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString); static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape); + static winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode _ParseTripleClickSelectionMode(const std::wstring& selectionModeString); + static std::wstring_view _SerializeTripleClickSelectionMode(const winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode selectionMode); GUID _guid; std::wstring _name; @@ -76,6 +78,7 @@ class TerminalApp::Profile final uint32_t _cursorColor; uint32_t _cursorHeight; winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape; + winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode _tripleClickSelectionMode; std::wstring _commandline; std::wstring _fontFace; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index c4fecfeca37..9591fd5bd16 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -133,6 +133,8 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting _snapOnInput = settings.SnapOnInput(); + _tripleClickMode = settings.TripleClickSelectionMode(); + // TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we // have a smaller scrollback. We should do this carefully - if the new buffer // size is smaller than where the mutable viewport currently is, we'll want @@ -517,15 +519,44 @@ void Terminal::DoubleClickSelection(const COORD position) } // Method Description: -// - Select the entire row of the position clicked +// - Performs a triple click selection based on the setting // Arguments: // - position: the (x,y) coordinate on the visible viewport void Terminal::TripleClickSelection(const COORD position) +{ + switch (_tripleClickMode) + { + case TripleClickSelectionMode::VisibleViewport: + _SelectViewport(); + break; + case TripleClickSelectionMode::Line: + _SelectRow(position); + break; + case TripleClickSelectionMode::Disabled: + default: + SetSelectionAnchor(position); + break; + } +} + +// Method Description: +// - Create a selection of the entire row of the position clicked +// Arguments: +// - position: the (x,y) coordinate on the visible viewport +void Terminal::_SelectRow(const COORD position) { SetSelectionAnchor({ 0, position.Y }); SetEndSelectionPosition({ _buffer->GetSize().RightInclusive(), position.Y }); } +// Method Description: +// - Create a selection of the entire visible viewport present +void Terminal::_SelectViewport() +{ + SetSelectionAnchor({ 0, 0 }); + SetEndSelectionPosition(_mutableViewport.Dimensions()); +} + // Method Description: // - expand the double click selection to the left (stopped by delimiter) // Arguments: diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 8ca40597a44..aac3c08395a 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -20,6 +20,7 @@ namespace winrt::Microsoft::Terminal::Settings { struct ICoreSettings; + enum class TripleClickSelectionMode; } namespace Microsoft::Terminal::Core @@ -151,9 +152,12 @@ class Microsoft::Terminal::Core::Terminal final : bool _selectionActive; SHORT _selectionAnchor_YOffset; SHORT _endSelectionPosition_YOffset; + winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode _tripleClickMode; void _ExpandDoubleClickSelectionLeft(const COORD position); void _ExpandDoubleClickSelectionRight(const COORD position); const bool _DoubleClickDelimiterCheck(std::wstring_view cellChar) const; + void _SelectRow(const COORD position); + void _SelectViewport(); const COORD _ConvertToBufferCell(const COORD viewportPos) const; std::shared_mutex _readWriteLock; diff --git a/src/cascadia/TerminalSettings/ICoreSettings.idl b/src/cascadia/TerminalSettings/ICoreSettings.idl index ecf14cb3c3d..8ce068211a3 100644 --- a/src/cascadia/TerminalSettings/ICoreSettings.idl +++ b/src/cascadia/TerminalSettings/ICoreSettings.idl @@ -12,6 +12,13 @@ namespace Microsoft.Terminal.Settings EmptyBox }; + enum TripleClickSelectionMode + { + Disabled, + Line, + VisibleViewport + }; + interface ICoreSettings { UInt32 DefaultForeground; @@ -27,6 +34,7 @@ namespace Microsoft.Terminal.Settings UInt32 CursorColor; CursorStyle CursorShape; UInt32 CursorHeight; + TripleClickSelectionMode TripleClickSelectionMode; }; } diff --git a/src/cascadia/TerminalSettings/TerminalSettings.cpp b/src/cascadia/TerminalSettings/TerminalSettings.cpp index 938a489f8ae..119d91ac773 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettings/TerminalSettings.cpp @@ -20,6 +20,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation _cursorColor{ DEFAULT_CURSOR_COLOR }, _cursorShape{ CursorStyle::Vintage }, _cursorHeight{ DEFAULT_CURSOR_HEIGHT }, + _tripleClickSelectionMode{ Settings::TripleClickSelectionMode::Line }, _useAcrylic{ false }, _closeOnExit{ true }, _tintOpacity{ 0.5 }, @@ -135,6 +136,16 @@ namespace winrt::Microsoft::Terminal::Settings::implementation _cursorHeight = value; } + Settings::TripleClickSelectionMode TerminalSettings::TripleClickSelectionMode() const noexcept + { + return _tripleClickSelectionMode; + } + + void TerminalSettings::TripleClickSelectionMode(winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode const& value) noexcept + { + _tripleClickSelectionMode = value; + } + bool TerminalSettings::UseAcrylic() { return _useAcrylic; diff --git a/src/cascadia/TerminalSettings/terminalsettings.h b/src/cascadia/TerminalSettings/terminalsettings.h index 49b0d3dd852..a551610c79f 100644 --- a/src/cascadia/TerminalSettings/terminalsettings.h +++ b/src/cascadia/TerminalSettings/terminalsettings.h @@ -45,6 +45,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept; uint32_t CursorHeight(); void CursorHeight(uint32_t value); + Settings::TripleClickSelectionMode TripleClickSelectionMode() const noexcept; + void TripleClickSelectionMode(winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode const& value) noexcept; // ------------------------ End of Core Settings ----------------------- bool UseAcrylic(); @@ -94,6 +96,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation uint32_t _cursorColor; Settings::CursorStyle _cursorShape; uint32_t _cursorHeight; + Settings::TripleClickSelectionMode _tripleClickSelectionMode; bool _useAcrylic; bool _closeOnExit; diff --git a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp index ead5fe95346..3c9899c5df0 100644 --- a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp @@ -36,6 +36,7 @@ namespace TerminalCoreUnitTests uint32_t CursorColor() { return COLOR_WHITE; } CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; } uint32_t CursorHeight() { return 42UL; } + TripleClickSelectionMode TripleClickSelectionMode() { return TripleClickSelectionMode::Line; } // other implemented methods uint32_t GetColorTableEntry(int32_t) const { return 123; } @@ -50,6 +51,7 @@ namespace TerminalCoreUnitTests void CursorColor(uint32_t) {} void CursorShape(CursorStyle const&) noexcept {} void CursorHeight(uint32_t) {} + void TripleClickSelectionMode(winrt::Microsoft::Terminal::Settings::TripleClickSelectionMode) {} // other unimplemented methods void SetColorTableEntry(int32_t /* index */, uint32_t /* value */) {}