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
|
// - N/A
|
||||||
winrt::fire_and_forget TermControl::_TerminalCursorPositionChanged()
|
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())
|
if (_closing.load())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1858,6 +1865,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
|
|
||||||
auto weakThis{ get_weak() };
|
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());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
|
@ -1866,6 +1882,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
TSFInputControl().TryRedrawCanvas();
|
TSFInputControl().TryRedrawCanvas();
|
||||||
}
|
}
|
||||||
|
_coroutineDispatchStateUpdateInProgress.store(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
void _CompositionCompleted(winrt::hstring text);
|
void _CompositionCompleted(winrt::hstring text);
|
||||||
void _CurrentCursorPositionHandler(const IInspectable& sender, const CursorPositionEventArgs& eventArgs);
|
void _CurrentCursorPositionHandler(const IInspectable& sender, const CursorPositionEventArgs& eventArgs);
|
||||||
void _FontInfoHandler(const IInspectable& sender, const FontInfoEventArgs& 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