Skip to content

Invalid cached console cursor position on Unix #77995

Description

@qt-kaneko

Description

Console cursor moves incorrectly from the end of the line to its beginning.

Reproduction Steps

Console.CursorLeft = Console.BufferWidth - 1;
Console.Write("2");

Console.CursorLeft = 0;
Console.Write("1");

Expected behavior

1 should be printed at the beginning of the line

Actual behavior

1 is printed after 2 (resize terminal to see this, 1 may be wrapped to the next line)

Regression?

No response

Known Workarounds

Reset cached cursor position, either with moving cursor to [0, 0], or using reflection to invalidate ConsolePal.s_cursorLeft

Configuration

  • .NET 6 macOS 12.6 ARM64
  • .NET 7 macOS 12.6 ARM64
  • .NET 7 Arco Linux x64

Other information

Somewhere in ConsolePal, in things related to the cached cursor position and its calculation.

I think this is due to cached cursor position is computed like on windows (when cursor reaches end of line, and last char is printed, it moves to the next line), while on my tested configuration this is not.

Check ConsolePal.s_cursorLeft and ConsolePal.s_cursorTop with provided example. Cached position is on 0 row instead of Console.WindowWidth row, so it "thinks" that cursor is already at the beginning of the line and there is no need to move it.

Test code:

using System.Diagnostics;
using System.Reflection;

var ConsolePal = Assembly.Load("System.Console").GetType("System.ConsolePal")!;
var s_cursorLeft = ConsolePal.GetField("s_cursorLeft", BindingFlags.NonPublic | BindingFlags.Static)!;
var s_cursorTop = ConsolePal.GetField("s_cursorTop", BindingFlags.NonPublic | BindingFlags.Static)!;

Console.CursorLeft = Console.BufferWidth - 1;
Console.Write("2");

Debug.WriteLine("[X: " + s_cursorLeft.GetValue(null) + "], [Y: " + s_cursorTop.GetValue(null) + "]");

Console.CursorLeft = 0;
Console.Write("1"); // 1 will be printed after 2 instead of at the beginning of the line (resize terminal to see this, 1 may be wrapped to the next line)

Task.Delay(Timeout.Infinite).Wait();

image

image

(On the 2nd image terminal is made wider by 1 symbol)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions