Muffle updates to the cursor position to 1/~100ms (#5289)
This stops us from dispatching back-to-back terminal cursor position updates to the TSF control before it has a chance to get back to us. Fixes #5288.
This commit is contained in:
parent
6fabc4abb7
commit
1299a839bd
|
@ -1851,6 +1851,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// - N/A
|
||||
winrt::fire_and_forget TermControl::_TerminalCursorPositionChanged()
|
||||
{
|
||||
bool expectedFalse{ false };
|
||||
if (!_coroutineDispatchStateUpdateInProgress.compare_exchange_weak(expectedFalse, true))
|
||||
{
|
||||
// somebody's already in here.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_closing.load())
|
||||
{
|
||||
return;
|
||||
|
@ -1858,6 +1865,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Muffle 2: Muffle Harder
|
||||
// If we're the lucky coroutine who gets through, we'll still wait 100ms to clog
|
||||
// the atomic above so we don't service the cursor update too fast. If we get through
|
||||
// and finish processing the update quickly but similar requests are still beating
|
||||
// down the door above in the atomic, we may still update the cursor way more than
|
||||
// is visible to anyone's eye, which is a waste of effort.
|
||||
static constexpr auto CursorUpdateQuiesceTime{ std::chrono::milliseconds(100) };
|
||||
co_await winrt::resume_after(CursorUpdateQuiesceTime);
|
||||
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
||||
if (auto control{ weakThis.get() })
|
||||
|
@ -1866,6 +1882,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
{
|
||||
TSFInputControl().TryRedrawCanvas();
|
||||
}
|
||||
_coroutineDispatchStateUpdateInProgress.store(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
void _CompositionCompleted(winrt::hstring text);
|
||||
void _CurrentCursorPositionHandler(const IInspectable& sender, const CursorPositionEventArgs& eventArgs);
|
||||
void _FontInfoHandler(const IInspectable& sender, const FontInfoEventArgs& eventArgs);
|
||||
|
||||
// this atomic is to be used as a guard against dispatching billions of coroutines for
|
||||
// routine state changes that might happen millions of times a second.
|
||||
// Unbounded main dispatcher use leads to massive memory leaks and intense slowdowns
|
||||
// on the UI thread.
|
||||
std::atomic<bool> _coroutineDispatchStateUpdateInProgress{ false };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue