Add cursor blinking (#686)
It even respects the user's cursor blink speed setting!
This commit is contained in:
parent
2c1ab620bf
commit
8c177fab4f
|
@ -7,6 +7,7 @@
|
|||
#include <DefaultSettings.h>
|
||||
#include <unicode.hpp>
|
||||
#include <Utf16Parser.hpp>
|
||||
#include <WinUser.h>
|
||||
#include "..\..\types\inc\GlyphWidth.hpp"
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
|
@ -36,7 +37,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
_desiredFont{ DEFAULT_FONT_FACE.c_str(), 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8 },
|
||||
_actualFont{ DEFAULT_FONT_FACE.c_str(), 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
|
||||
_touchAnchor{ std::nullopt },
|
||||
_leadingSurrogate{}
|
||||
_leadingSurrogate{},
|
||||
_cursorTimer{}
|
||||
{
|
||||
_Create();
|
||||
}
|
||||
|
@ -405,6 +407,24 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
auto pfnScrollPositionChanged = std::bind(&TermControl::_TerminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
_terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged);
|
||||
|
||||
// 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 });
|
||||
|
||||
_controlRoot.GotFocus({ this, &TermControl::_GotFocusHandler });
|
||||
_controlRoot.LostFocus({ this, &TermControl::_LostFocusHandler });
|
||||
}
|
||||
else
|
||||
{
|
||||
// The user has disabled cursor blinking
|
||||
_cursorTimer = std::nullopt;
|
||||
}
|
||||
|
||||
// Focus the control here. If we do it up above (in _Create_), then the
|
||||
// focus won't actually get passed to us. I believe this is because
|
||||
// we're not technically a part of the UI tree yet, so focusing us
|
||||
|
@ -503,6 +523,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
WI_IsFlagSet(modifiers, KeyModifiers::Ctrl),
|
||||
WI_IsFlagSet(modifiers, KeyModifiers::Alt),
|
||||
WI_IsFlagSet(modifiers, KeyModifiers::Shift));
|
||||
|
||||
if (_cursorTimer.has_value())
|
||||
{
|
||||
// Manually show the cursor when a key is pressed. Restarting
|
||||
// the timer prevents flickering.
|
||||
_terminal->SetCursorVisible(true);
|
||||
_cursorTimer.value().Start();
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled(handled);
|
||||
|
@ -794,6 +822,29 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Event handler for the GotFocus event. This is used to start
|
||||
// blinking the cursor when the window is focused.
|
||||
void TermControl::_GotFocusHandler(Windows::Foundation::IInspectable const& /* sender */,
|
||||
RoutedEventArgs const& /* args */)
|
||||
{
|
||||
if (_cursorTimer.has_value())
|
||||
_cursorTimer.value().Start();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Event handler for the LostFocus event. This is used to hide
|
||||
// and stop blinking the cursor when the window loses focus.
|
||||
void TermControl::_LostFocusHandler(Windows::Foundation::IInspectable const& /* sender */,
|
||||
RoutedEventArgs const& /* args */)
|
||||
{
|
||||
if (_cursorTimer.has_value())
|
||||
{
|
||||
_cursorTimer.value().Stop();
|
||||
_terminal->SetCursorVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TermControl::_SendInputToConnection(const std::wstring& wstr)
|
||||
{
|
||||
_connection.WriteInput(wstr);
|
||||
|
@ -848,6 +899,17 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
_renderer->TriggerRedrawAll();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Toggle the cursor on and off when called by the cursor blink timer.
|
||||
// Arguments:
|
||||
// - sender: not used
|
||||
// - e: not used
|
||||
void TermControl::_BlinkCursor(Windows::Foundation::IInspectable const& /* sender */,
|
||||
Windows::Foundation::IInspectable const& /* e */)
|
||||
{
|
||||
_terminal->SetCursorVisible(!_terminal->IsCursorVisible());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Process a resize event that was initiated by the user. This can either be due to the user resizing the window (causing the swapchain to resize) or due to the DPI changing (causing us to need to resize the buffer to match)
|
||||
// Arguments:
|
||||
|
|
|
@ -84,6 +84,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// storage location for the leading surrogate of a utf-16 surrogate pair
|
||||
std::optional<wchar_t> _leadingSurrogate;
|
||||
|
||||
std::optional<Windows::UI::Xaml::DispatcherTimer> _cursorTimer;
|
||||
|
||||
// If this is set, then we assume we are in the middle of panning the
|
||||
// viewport via touch input.
|
||||
std::optional<winrt::Windows::Foundation::Point> _touchAnchor;
|
||||
|
@ -100,7 +102,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
void _PointerReleasedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
void _MouseWheelHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
void _ScrollbarChangeHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs const& e);
|
||||
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 _BlinkCursor(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
|
||||
void _SendInputToConnection(const std::wstring& wstr);
|
||||
void _SwapChainSizeChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
|
||||
void _SwapChainScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel const& sender, Windows::Foundation::IInspectable const& args);
|
||||
|
|
|
@ -590,3 +590,13 @@ const std::wstring Terminal::RetrieveSelectedTextFromBuffer(bool trimTrailingWhi
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the visibility of the text cursor.
|
||||
// Arguments:
|
||||
// - isVisible: whether the cursor should be visible
|
||||
void Terminal::SetCursorVisible(const bool isVisible) noexcept
|
||||
{
|
||||
auto& cursor = _buffer->GetCursor();
|
||||
cursor.SetIsVisible(isVisible);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ public:
|
|||
void SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept;
|
||||
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
|
||||
|
||||
void SetCursorVisible(const bool isVisible) noexcept;
|
||||
|
||||
#pragma region TextSelection
|
||||
const bool IsSelectionActive() const noexcept;
|
||||
void SetSelectionAnchor(const COORD position);
|
||||
|
|
Loading…
Reference in a new issue