diff --git a/src/OpenTheBox.Web/WebGameHost.cs b/src/OpenTheBox.Web/WebGameHost.cs index db5a2e1..9e7fef3 100644 --- a/src/OpenTheBox.Web/WebGameHost.cs +++ b/src/OpenTheBox.Web/WebGameHost.cs @@ -615,12 +615,15 @@ public sealed class WebGameHost } string rendered = writer.ToString().Replace("\n", "\r\n"); - int renderedLines = rendered.Split('\n').Length; + int renderedLines = rendered.Count(c => c == '\n'); - // Clear previous render and write new one + // Overwrite in place: move cursor up, write new content over old lines, + // then clear any leftover lines if new render is shorter. No clear-before-write = no flicker. if (previousRenderedLines > 0) - await _terminal.WriteAsync($"\x1b[{previousRenderedLines}A\x1b[J"); + await _terminal.WriteAsync($"\x1b[{previousRenderedLines}A\r"); await _terminal.WriteAsync(rendered); + if (previousRenderedLines > renderedLines) + await _terminal.WriteAsync("\x1b[J"); previousRenderedLines = renderedLines; var key = await _terminal.ReadKeyAsync(); diff --git a/src/OpenTheBox.Web/WebTerminal.cs b/src/OpenTheBox.Web/WebTerminal.cs index 86c9757..e2ea27b 100644 --- a/src/OpenTheBox.Web/WebTerminal.cs +++ b/src/OpenTheBox.Web/WebTerminal.cs @@ -235,10 +235,10 @@ public sealed class WebTerminal { int selected = 0; int pageSize = Math.Min(10, options.Count); + int previousLineCount = 0; while (true) { - int scrollOffset = 0; if (selected >= pageSize) scrollOffset = selected - pageSize + 1; @@ -276,7 +276,14 @@ public sealed class WebTerminal string rendered = writer.ToString().Replace("\n", "\r\n"); int lineCount = rendered.Count(c => c == '\n'); + // Overwrite in place: move cursor up, write over old lines (no flicker). + // Only clear leftover lines if the new render is shorter than previous. + if (previousLineCount > 0) + await WriteAsync($"\x1b[{previousLineCount}A\r"); await WriteAsync(rendered); + if (previousLineCount > lineCount) + await WriteAsync("\x1b[J"); + previousLineCount = lineCount; var key = await ReadKeyAsync(); @@ -301,9 +308,6 @@ public sealed class WebTerminal case ConsoleKey.D8 or ConsoleKey.NumPad8: if (options.Count >= 8) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 7; } break; case ConsoleKey.D9 or ConsoleKey.NumPad9: if (options.Count >= 9) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 8; } break; } - - // Clear menu before re-rendering - await WriteAsync($"\x1b[{lineCount}A\x1b[J"); } }