-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Move all blink handling into Renderer #19330
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
base: main
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
4de989d to
8d17e85
Compare
8d17e85 to
8390d60
Compare
Goal: Remove `CursorBlinker`. Problem: Spooky action at a distance via `Cursor::HasMoved`. Solution: Moved all the a11y event raising into `_stream.cpp` and pray for the best. Goal: Prevent node.js from tanking conhost performance via MSAA (WHY). Problem: `ServiceLocator`. Solution: Unserviced the locator. Debounced event raising. Performance increased by >10x. Problem 2: Lots of files changed. This PR is a prerequisite for #19330 ## Validation Steps Performed Ran NVDA with and without UIA enabled and with different delays. ✅
8390d60 to
5742c64
Compare
5742c64 to
1c23430
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
50/56
| // - <none> | ||
| // Return Value: | ||
| // - <none> | ||
| void Window::_UpdateSystemMetrics() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Make sure nobody else called this who cares about the cursor metrics (probably not)
| cursor.SetSize(_d->ulSavedCursorSize); | ||
| cursor.SetIsVisible(_d->fSavedCursorVisible); | ||
| cursor.SetType(_d->savedCursorType); | ||
| cursor.SetIsOn(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 make sure selection has the same cursor behavior
| { | ||
| // Enter Mark Mode | ||
| // NOTE: directly set cursor state. We already should have locked before calling this function. | ||
| _activeBuffer().GetCursor().SetIsOn(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to inhibit the cursor?
|
|
||
| void Terminal::BlinkCursor() noexcept | ||
| { | ||
| if (_selectionMode != SelectionInteractionMode::Mark) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to inhibit the cursor for mark mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed that we let the cursor blink during selections. Why do we inhibit it for mark mode then, even though mark mode is essentially just keyboard-selection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my mind, we want the cursor to blink during mark mode to know which endpoint is currently focused. That way, you'll know if you're moving the start or end before you press on an arrow key.
| // Return Value: | ||
| // - <none> | ||
| void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept | ||
| void Cursor::CopyProperties(const Cursor& other) noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to update _parentBuffer too?
|
|
||
| void TermControl::CursorVisibility(Control::CursorDisplayState cursorVisibility) | ||
| { | ||
| _cursorVisibility = cursorVisibility; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like cursor visibility is stored across 3 variables:
TermControl::_cursorVisibilityControlCore::_forceCursorVisibleRenderer::_cursorVisibilityInhibitors
Could we remove the one in TermControl and just query the one in ControlCore? Or, even better, just pipe the value from Renderer all the way up, rather than having a separate boolean member on each layer?
|
|
||
| void Terminal::BlinkCursor() noexcept | ||
| { | ||
| if (_selectionMode != SelectionInteractionMode::Mark) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my mind, we want the cursor to blink during mark mode to know which endpoint is currently focused. That way, you'll know if you're moving the start or end before you press on an arrow key.
| _previewControl = Control::TermControl(settings, settings, *_previewConnection); | ||
| _previewControl.IsEnabled(false); | ||
| _previewControl.AllowFocusWhenDisabled(false); | ||
| _previewControl.CursorVisibility(Microsoft::Terminal::Control::CursorDisplayState::Shown); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Verified that the cursor still blinks
| static DWORD _timerToMillis(TimerRepr t) noexcept; | ||
|
|
||
| // Actual rendering | ||
| [[nodiscard]] HRESULT PaintFrame(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit weird that this one is marked private, but doesn't have the _ prefix. Plus there's also _PaintFrame() just below it.
| pWindow->UpdateWindowText(); | ||
|
|
||
| auto& an = ServiceLocator::LocateGlobals().accessibilityNotifier; | ||
| an.SelectionChanged(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we still need this?
| // Fire off an event to let accessibility apps know the selection has changed. | ||
| auto& an = ServiceLocator::LocateGlobals().accessibilityNotifier; | ||
| an.CursorChanged(coordBufferPos, true); | ||
| an.SelectionChanged(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
|
Oh, and you probably want to update the PR body too. |
Note that this PR is not quite finished (~90%?). Missing:
This PR moves the cursor blinker and VT blink rendition timer into
Renderer. To do so, this PR introduces a generic timer system with which you can schedule arbitrary timer jobs. Thanks to this, this PR removes a crapton of code, particularly throughout conhost, and improves throughput by another ~10%. On my PC it can now churn through >400MB/s while rendering at 240FPS. Fun fact: Processing 100kB of text and rendering it in conhost now takes less time than MSCTF (TSF) needs to process 1 keyboard character. When I look at our shell code.Validation Steps Performed