From b92138f742e1011ba3afed2ced0b9feffe955cd6 Mon Sep 17 00:00:00 2001 From: msftrncs Date: Fri, 8 Nov 2019 23:27:03 -0600 Subject: [PATCH] Don't SetCursorPosition when not Rendered. Block the setting of the console cursor when the buffer hasn't been completely rendered due to an input queue waiting to be processed. Fixes #1081. --- PSReadLine/Render.cs | 60 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/PSReadLine/Render.cs b/PSReadLine/Render.cs index 48feb583a..6f0c49275 100644 --- a/PSReadLine/Render.cs +++ b/PSReadLine/Render.cs @@ -61,6 +61,7 @@ class RenderData }; private int _initialX; private int _initialY; + private bool _waitingToRender; private ConsoleColor _initialForeground; private ConsoleColor _initialBackground; @@ -112,6 +113,7 @@ private void Render() _tokens = null; _ast = null; _parseErrors = null; + _waitingToRender = true; return; } @@ -816,6 +818,7 @@ void UpdateColorsIfNecessary(string newColor) // TODO: set WindowTop if necessary _lastRenderTime.Restart(); + _waitingToRender = false; } private static string Spaces(int cnt) @@ -980,37 +983,44 @@ private void RecomputeInitialCoords() private void MoveCursor(int newCursor) { - // In case the buffer was resized - RecomputeInitialCoords(); - _previousRender.bufferWidth = _console.BufferWidth; - _previousRender.bufferHeight = _console.BufferHeight; - - var point = ConvertOffsetToPoint(newCursor); - if (point.Y < 0) + // Only update screen cursor if the buffer is fully rendered. + if (!_waitingToRender) { - Ding(); - return; - } + // In case the buffer was resized + RecomputeInitialCoords(); + _previousRender.bufferWidth = _console.BufferWidth; + _previousRender.bufferHeight = _console.BufferHeight; - if (point.Y == _console.BufferHeight) - { - // The cursor top exceeds the buffer height, so adjust the initial cursor - // position and the to-be-set cursor position for scrolling up the buffer. - _initialY -= 1; - point.Y -= 1; + var point = ConvertOffsetToPoint(newCursor); + if (point.Y < 0) + { + Ding(); + return; + } - // Insure the cursor is on the last line of the buffer prior - // to issuing a newline to scroll the buffer. - _console.SetCursorPosition(point.X, point.Y); + if (point.Y == _console.BufferHeight) + { + // The cursor top exceeds the buffer height, so adjust the initial cursor + // position and the to-be-set cursor position for scrolling up the buffer. + _initialY -= 1; + point.Y -= 1; - // Scroll up the buffer by 1 line. - _console.Write("\n"); - } - else - { - _console.SetCursorPosition(point.X, point.Y); + // Insure the cursor is on the last line of the buffer prior + // to issuing a newline to scroll the buffer. + _console.SetCursorPosition(point.X, point.Y); + + // Scroll up the buffer by 1 line. + _console.Write("\n"); + } + else + { + _console.SetCursorPosition(point.X, point.Y); + } } + // While waiting to render, and a keybinding has occured that is moving the cursor, + // converting offset to point could potentially result in an invalid screen position, + // but the insertion point should reflect the move. _current = newCursor; }