Repository navigation
Allow ThrottledFunc to work on different types of dispatcher
#10187
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
Changes from all commits
e4478ee
400b35f
42b970b
4578c13
d8cc047
21a97b6
2e861d8
e20caae
d667f3b
62cbf30
445bdf6
1376721
a1ce7cb
03fb764
5e7d270
6e031e5
47410c9
0869456
dace0c4
12b78f5
e340fe9
b7b23a8
086710a
21a6370
4efdf39
59e911d
6f07004
ff3b808
559d1de
804a114
0f0af03
95300d4
1de9485
1bc27d0
3cace60
265bd9f
c8a2957
074f67c
5a0840a
b8158d4
4e7a500
f5665c5
056c354
e643885
33653e0
326cf08
a765769
3d59a67
a4be792
cf15df7
bcce581
a6099fb
f9b4216
f43f897
122b9a3
a7ff38f
3dbac4a
b8fa11a
a93b10b
8baa4f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,16 @@ using namespace winrt::Windows::Graphics::Display; | |
| using namespace winrt::Windows::System; | ||
| using namespace winrt::Windows::ApplicationModel::DataTransfer; | ||
|
|
||
| // The minimum delay between updates to the scroll bar's values. | ||
| // The updates are throttled to limit power usage. | ||
| constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8); | ||
|
|
||
| // The minimum delay between updating the TSF input control. | ||
| constexpr const auto TsfRedrawInterval = std::chrono::milliseconds(100); | ||
|
|
||
| // The minimum delay between updating the locations of regex patterns | ||
| constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(500); | ||
|
|
||
| namespace winrt::Microsoft::Terminal::Control::implementation | ||
| { | ||
| // Helper static function to ensure that all ambiguous-width glyphs are reported as narrow. | ||
|
|
@@ -94,6 +104,61 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
| auto pfnTerminalTaskbarProgressChanged = std::bind(&ControlCore::_terminalTaskbarProgressChanged, this); | ||
| _terminal->TaskbarProgressChangedCallback(pfnTerminalTaskbarProgressChanged); | ||
|
|
||
| // Get our dispatcher. If we're hosted in-proc with XAML, this will get | ||
| // us the same dispatcher as TermControl::Dispatcher(). If we're out of | ||
| // proc, this'll return null. We'll need to instead make a new | ||
| // DispatcherQueue (on a new thread), so we can use that for throttled | ||
| // functions. | ||
| _dispatcher = winrt::Windows::System::DispatcherQueue::GetForCurrentThread(); | ||
| if (!_dispatcher) | ||
| { | ||
| auto controller{ winrt::Windows::System::DispatcherQueueController::CreateOnDedicatedThread() }; | ||
| _dispatcher = controller.DispatcherQueue(); | ||
| } | ||
|
|
||
| // A few different events should be throttled, so they don't fire absolutely all the time: | ||
| // * _tsfTryRedrawCanvas: When the cursor position moves, we need to | ||
| // inform TSF, so it can move the canvas for the composition. We | ||
| // throttle this so that we're not hopping across the process boundary | ||
| // every time that the cursor moves. | ||
| // * _updatePatternLocations: When there's new output, or we scroll the | ||
| // viewport, we should re-check if there are any visible hyperlinks. | ||
| // But we don't really need to do this every single time text is | ||
| // output, we can limit this update to once every 500ms. | ||
| // * _updateScrollBar: Same idea as the TSF update - we don't _really_ | ||
| // need to hop across the process boundary every time text is output. | ||
| // We can throttle this to once every 8ms, which will get us out of | ||
| // the way of the main output & rendering threads. | ||
| _tsfTryRedrawCanvas = std::make_shared<ThrottledFuncTrailing<>>( | ||
| _dispatcher, | ||
| TsfRedrawInterval, | ||
| [weakThis = get_weak()]() { | ||
| if (auto core{ weakThis.get() }; !core->_IsClosing()) | ||
| { | ||
| core->_CursorPositionChangedHandlers(*core, nullptr); | ||
| } | ||
| }); | ||
|
|
||
| _updatePatternLocations = std::make_shared<ThrottledFuncTrailing<>>( | ||
| _dispatcher, | ||
| UpdatePatternLocationsInterval, | ||
| [weakThis = get_weak()]() { | ||
| if (auto core{ weakThis.get() }; !core->_IsClosing()) | ||
| { | ||
| core->UpdatePatternLocations(); | ||
| } | ||
| }); | ||
|
|
||
| _updateScrollBar = std::make_shared<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>>( | ||
| _dispatcher, | ||
| ScrollBarUpdateInterval, | ||
| [weakThis = get_weak()](const auto& update) { | ||
| if (auto core{ weakThis.get() }; !core->_IsClosing()) | ||
| { | ||
| core->_ScrollPositionChangedHandlers(*core, update); | ||
| } | ||
| }); | ||
|
|
||
| UpdateSettings(settings); | ||
| } | ||
|
|
||
|
|
@@ -1103,15 +1168,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
| // TODO GH#9617: refine locking around pattern tree | ||
| _terminal->ClearPatternTree(); | ||
|
|
||
| _ScrollPositionChangedHandlers(*this, | ||
| winrt::make<ScrollPositionChangedArgs>(viewTop, | ||
| viewHeight, | ||
| bufferSize)); | ||
| // Start the throttled update of our scrollbar. | ||
| auto update{ winrt::make<ScrollPositionChangedArgs>(viewTop, | ||
| viewHeight, | ||
| bufferSize) }; | ||
| if (!_inUnitTests) | ||
| { | ||
| _updateScrollBar->Run(update); | ||
| } | ||
| else | ||
| { | ||
| _ScrollPositionChangedHandlers(*this, update); | ||
| } | ||
|
|
||
| // Additionally, start the throttled update of where our links are. | ||
| _updatePatternLocations->Run(); | ||
| } | ||
|
|
||
| void ControlCore::_terminalCursorPositionChanged() | ||
| { | ||
| _CursorPositionChangedHandlers(*this, nullptr); | ||
| // When the buffer's cursor moves, start the throttled func to | ||
| // eventually dispatch a CursorPositionChanged event. | ||
| _tsfTryRedrawCanvas->Run(); | ||
|
Comment on lines
+1190
to
+1192
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if I understand it correctly, this starts a throttled func to throw an
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay so you have a point here. I'm gonna keep the throttling on the core side, not the control side. The Core will want to throttle how often it hops across the COM boundary to tell the UI to update. The UI doesn't care so much - it should just update whenever the Core tells it to. |
||
| } | ||
|
|
||
| void ControlCore::_terminalTaskbarProgressChanged() | ||
|
|
@@ -1221,8 +1299,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
|
|
||
| void ControlCore::Close() | ||
| { | ||
| if (!_closing.exchange(true)) | ||
| if (!_IsClosing()) | ||
| { | ||
| _closing = true; | ||
|
|
||
| // Stop accepting new output and state changes before we disconnect everything. | ||
| _connection.TerminalOutput(_connectionOutputEventToken); | ||
| _connectionStateChangedRevoker.revoke(); | ||
|
|
@@ -1400,18 +1480,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
| { | ||
| _terminal->Write(hstr); | ||
|
|
||
| // NOTE: We're raising an event here to inform the TermControl that | ||
| // output has been received, so it can queue up a throttled | ||
| // UpdatePatternLocations call. In the future, we should have the | ||
| // _updatePatternLocations ThrottledFunc internal to this class, and | ||
| // run on this object's dispatcher queue. | ||
| // | ||
| // We're not doing that quite yet, because the Core will eventually | ||
| // be out-of-proc from the UI thread, and won't be able to just use | ||
| // the UI thread as the dispatcher queue thread. | ||
| // | ||
| // See TODO: https://github.com/microsoft/terminal/projects/5#card-50760282 | ||
| _ReceivedOutputHandlers(*this, nullptr); | ||
| // Start the throttled update of where our hyperlinks are. | ||
| _updatePatternLocations->Run(); | ||
| } | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.