Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for solid cursor blinking style #2892

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/cascadia/TerminalApp/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static constexpr std::string_view HistorySizeKey{ "historySize" };
static constexpr std::string_view SnapOnInputKey{ "snapOnInput" };
static constexpr std::string_view CursorColorKey{ "cursorColor" };
static constexpr std::string_view CursorShapeKey{ "cursorShape" };
static constexpr std::string_view CursorBlinkingKey{ "cursorBlinking" };
static constexpr std::string_view CursorHeightKey{ "cursorHeight" };

static constexpr std::string_view ConnectionTypeKey{ "connectionType" };
Expand Down Expand Up @@ -59,6 +60,10 @@ static constexpr std::wstring_view CursorShapeUnderscore{ L"underscore" };
static constexpr std::wstring_view CursorShapeFilledbox{ L"filledBox" };
static constexpr std::wstring_view CursorShapeEmptybox{ L"emptyBox" };

// Possible values for Cursor Blinking Style
static constexpr std::wstring_view CursorBlinkingStyleBlink{ L"blink" };
static constexpr std::wstring_view CursorBlinkingStyleSolid{ L"solid" };

// Possible values for Image Stretch Mode
static constexpr std::string_view ImageStretchModeNone{ "none" };
static constexpr std::string_view ImageStretchModeFill{ "fill" };
Expand Down Expand Up @@ -184,6 +189,7 @@ TerminalSettings Profile::CreateTerminalSettings(const std::vector<ColorScheme>&
terminalSettings.CursorColor(_cursorColor);
terminalSettings.CursorHeight(_cursorHeight);
terminalSettings.CursorShape(_cursorShape);
terminalSettings.CursorBlinking(_cursorBlinking);

// Fill in the remaining properties from the profile
terminalSettings.UseAcrylic(_useAcrylic);
Expand Down Expand Up @@ -302,6 +308,7 @@ Json::Value Profile::ToJson() const
root[JsonKey(CursorHeightKey)] = _cursorHeight;
}
root[JsonKey(CursorShapeKey)] = winrt::to_string(_SerializeCursorStyle(_cursorShape));
root[JsonKey(CursorBlinkingKey)] = winrt::to_string(_SerializeCursorBlinkingStyle(_cursorBlinking));

///// Control Settings /////
root[JsonKey(CommandlineKey)] = winrt::to_string(_commandline);
Expand Down Expand Up @@ -648,6 +655,12 @@ void Profile::LayerJson(const Json::Value& json)
auto cursorShape{ json[JsonKey(CursorShapeKey)] };
_cursorShape = _ParseCursorShape(GetWstringFromJson(cursorShape));
}
if (json.isMember(JsonKey(CursorBlinkingKey)))
{
auto cursorBlinking{ json[JsonKey(CursorBlinkingKey)] };
_cursorBlinking = _ParseCursorBlinkingStyle(GetWstringFromJson(cursorBlinking));
}

JsonUtils::GetOptionalString(json, TabTitleKey, _tabTitle);

// Control Settings
Expand Down Expand Up @@ -1109,6 +1122,47 @@ std::wstring_view Profile::_SerializeCursorStyle(const CursorStyle cursorShape)
}
}

// Method Description:
// - Helper function for converting a user-specified cursor blinking style corresponding
// CursorBlinkingStyle enum value
// Arguments:
// - cursorBlinkingStyleString: The string value from the settings file to parse
// Return Value:
// - The corresponding enum value which maps to the string provided by the user
CursorBlinkingStyle Profile::_ParseCursorBlinkingStyle(const std::wstring& cursorBlinkingStyleString)
{
if (cursorBlinkingStyleString == CursorBlinkingStyleBlink)
{
return CursorBlinkingStyle::Blink;
}
else if (cursorBlinkingStyleString == CursorBlinkingStyleSolid)
{
return CursorBlinkingStyle::Solid;
}

// default behavior for invalid data
return CursorBlinkingStyle::Blink;
}

// Method Description:
// - Helper function for converting a CursorBlinkingStyle to its corresponding string
// value.
// Arguments:
// - cursorBlinkingStyle: The enum value to convert to a string.
// Return Value:
// - The string value for the given CursorBlinkingStyle
std::wstring_view Profile::_SerializeCursorBlinkingStyle(const CursorBlinkingStyle cursorBlinkingStyle)
{
switch (cursorBlinkingStyle)
{
case CursorBlinkingStyle::Solid:
return CursorBlinkingStyleSolid;
default:
case CursorBlinkingStyle::Blink:
return CursorBlinkingStyleBlink;
}
}

// Method Description:
// - If this profile never had a GUID set for it, generate a runtime GUID for
// the profile. If a profile had their guid manually set to {0}, this method
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class TerminalApp::Profile final
static std::string_view SerializeImageAlignment(const std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> imageAlignment);
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::CursorBlinkingStyle _ParseCursorBlinkingStyle(const std::wstring& cursorBlinkingStyleString);
static std::wstring_view _SerializeCursorBlinkingStyle(const winrt::Microsoft::Terminal::Settings::CursorBlinkingStyle cursorBlinkingStyle);

static GUID _GenerateGuidForProfile(const std::wstring& name, const std::optional<std::wstring>& source) noexcept;

Expand All @@ -121,6 +123,7 @@ class TerminalApp::Profile final
uint32_t _cursorColor;
uint32_t _cursorHeight;
winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape;
winrt::Microsoft::Terminal::Settings::CursorBlinkingStyle _cursorBlinking;

std::wstring _commandline;
std::wstring _fontFace;
Expand Down
69 changes: 53 additions & 16 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation

// Refresh our font with the renderer
_UpdateFont();

// Refresh cursor blinking style
_UpdateCursorBlinking();
const auto width = _swapChainPanel.ActualWidth();
const auto height = _swapChainPanel.ActualHeight();
if (width != 0 && height != 0)
Expand Down Expand Up @@ -536,21 +537,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
_autoScrollTimer.Tick({ this, &TermControl::_UpdateAutoScroll });

// Set up blinking cursor
int blinkTime = GetCaretBlinkTime();
if (blinkTime != INFINITE)
{
// Create a timer
_cursorTimer = std::make_optional(DispatcherTimer());
_cursorTimer.value().Interval(std::chrono::milliseconds(blinkTime));
_cursorTimer.value().Tick({ this, &TermControl::_BlinkCursor });
_cursorTimer.value().Start();
}
else
{
// The user has disabled cursor blinking
_cursorTimer = std::nullopt;
}
// Set up cursor blinking
_UpdateCursorBlinking();

// import value from WinUser (convert from milli-seconds to micro-seconds)
_multiClickTimer = GetDoubleClickTime() * 1000;
Expand Down Expand Up @@ -1244,6 +1232,30 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
}

// Method Description:
// - Update cursor blinking style. This will create or stop cursor timer as needed.
void TermControl::_UpdateCursorBlinking()
{
auto blinkingStyle = _settings.CursorBlinking();
switch (blinkingStyle)
{
case CursorBlinkingStyle::Solid:
if (_cursorTimer.has_value())
{
_cursorTimer.value().Stop();
}

_cursorTimer = std::nullopt;

_terminal->SetCursorVisible(true);
break;
case CursorBlinkingStyle::Blink:
default:
_CreateBlinkTimer();
break;
}
}

// Method Description:
// - Triggered when the swapchain changes size. We use this to resize the
// terminal buffers to match the new visible size.
Expand Down Expand Up @@ -1275,6 +1287,31 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_renderer->TriggerRedrawAll();
}

// Method Description:
// - Create cursor blink timer if there is none.
void TermControl::_CreateBlinkTimer()
{
if (_cursorTimer.has_value())
{
return;
}

int blinkTime = GetCaretBlinkTime();
if (blinkTime != INFINITE)
{
// Create a timer
_cursorTimer = std::make_optional(DispatcherTimer());
_cursorTimer.value().Interval(std::chrono::milliseconds(blinkTime));
_cursorTimer.value().Tick({ this, &TermControl::_BlinkCursor });
_cursorTimer.value().Start();
}
else
{
// The user has disabled cursor blinking
_cursorTimer = std::nullopt;
}
}

// Method Description:
// - Toggle the cursor on and off when called by the cursor blink timer.
// Arguments:
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _BackgroundColorChanged(const uint32_t color);
void _InitializeTerminal();
void _UpdateFont();
void _UpdateCursorBlinking();
void _KeyDownHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
void _CharacterHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::CharacterReceivedRoutedEventArgs const& e);
void _PointerPressedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
Expand All @@ -160,6 +161,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _GotFocusHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
void _LostFocusHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);

void _CreateBlinkTimer();
void _BlinkCursor(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition);
void _SendInputToConnection(const std::wstring& wstr);
Expand Down
7 changes: 7 additions & 0 deletions src/cascadia/TerminalSettings/ICoreSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ namespace Microsoft.Terminal.Settings
EmptyBox
};

enum CursorBlinkingStyle
{
Blink = 0,
Solid = 1,
};

interface ICoreSettings
{
UInt32 DefaultForeground;
Expand All @@ -26,6 +32,7 @@ namespace Microsoft.Terminal.Settings

UInt32 CursorColor;
CursorStyle CursorShape;
CursorBlinkingStyle CursorBlinking;
UInt32 CursorHeight;
String WordDelimiters;
Boolean CopyOnSelect;
Expand Down
10 changes: 10 additions & 0 deletions src/cascadia/TerminalSettings/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorShape = value;
}

Settings::CursorBlinkingStyle TerminalSettings::CursorBlinking() const noexcept
{
return _cursorBlinking;
}

void TerminalSettings::CursorBlinking(Settings::CursorBlinkingStyle const& value) noexcept
{
_cursorBlinking = value;
}

uint32_t TerminalSettings::CursorHeight()
{
return _cursorHeight;
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalSettings/terminalsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
void CursorColor(uint32_t value);
CursorStyle CursorShape() const noexcept;
void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept;
CursorBlinkingStyle CursorBlinking() const noexcept;
void CursorBlinking(winrt::Microsoft::Terminal::Settings::CursorBlinkingStyle const& value) noexcept;
uint32_t CursorHeight();
void CursorHeight(uint32_t value);
hstring WordDelimiters();
Expand Down Expand Up @@ -104,6 +106,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
bool _snapOnInput;
uint32_t _cursorColor;
Settings::CursorStyle _cursorShape;
Settings::CursorBlinkingStyle _cursorBlinking;
uint32_t _cursorHeight;
hstring _wordDelimiters;

Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/UnitTests_TerminalCore/MockTermSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace TerminalCoreUnitTests
bool SnapOnInput() { return false; }
uint32_t CursorColor() { return COLOR_WHITE; }
CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; }
CursorBlinkingStyle CursorBlinking() const noexcept { return CursorBlinkingStyle::Blink; }
uint32_t CursorHeight() { return 42UL; }
winrt::hstring WordDelimiters() { return winrt::to_hstring(DEFAULT_WORD_DELIMITERS.c_str()); }
bool CopyOnSelect() { return _copyOnSelect; }
Expand All @@ -46,6 +47,7 @@ namespace TerminalCoreUnitTests
void SnapOnInput(bool) {}
void CursorColor(uint32_t) {}
void CursorShape(CursorStyle const&) noexcept {}
void CursorBlinking(CursorBlinkingStyle const&) noexcept {}
void CursorHeight(uint32_t) {}
void WordDelimiters(winrt::hstring) {}
void CopyOnSelect(bool copyOnSelect) { _copyOnSelect = copyOnSelect; }
Expand Down