Skip to content

ConPTY does not move cursor to new line when writing to inactive screen buffer #19644

@trexxet

Description

@trexxet

Windows Terminal version

1.23.12811.0

Windows build number

10.0.19045.0

Other Software

No response

Steps to reproduce

I'm trying to measure the size that a text (which may contain tabs, newlines etc.) would take in a console without printing it. For this purpose, I created a console screen buffer that does not become active (so let's call it "virtual screen buffer"). The idea is simple: sync virtual buffer settings and cursor position with a "real" screen buffer; write text to it; get new cursor position.

The code (compiled with gcc 15.1.0, MinGW64 / MSYS2):

    hOut = CreateConsoleScreenBuffer (GENERIC_WRITE | GENERIC_READ, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    if (hOut == INVALID_HANDLE_VALUE) [[unlikely]]
        throw std::runtime_error ("Can't create hOut for VHandle");

    ... // sync CSBI srWindow, dwSize and dwCursorPosition

    COORD curPosSave = csbi(hOut).dwCursorPosition;

    DWORD written;
    if (!WriteConsole (hOut, s.c_str(), s.length(), &written, NULL)) [[unlikely]]
        throw std::runtime_error (std::format ("Can't WriteConsole for hOut {}", hOut));
    Debug::print (std::format ("WriteConsole hOut {} written {}\n", hOut, written));
    // Debug::print writes to file not to mess with console

    COORD curPos = csbi(hOut).dwCursorPosition;
    Debug::print (std::format ("hOut {} cursor [{} {}] -> [{} {}]\n", hOut, curPosSave.X, curPosSave.Y, curPos.X, curPos.Y));

I've tested this code with:

  • cmd.exe (conhost)
  • powershell (conhost)
  • powershell (windows terminal, conpty)
  • bash (mintty mingw64, conpty)
  • bash (mintty mingw64 --pcon off) - fails on GetConsoleMode()
  • bash (VS Code terminal, conpty)

As I want the program to work with older Windows versions, I'm not using virtual terminal sequences.

Expected Behavior

No response

Actual Behavior

For all test cases, WriteConsole() did not fail and wrote the correct value to written.

For each shell/console, I tested writing a "test string" and "test string\n" (as I'm building with mingw, I don't need to care about '\r').

Shell/console Without \n With \n
cmd.exe (conhost) ✔️[0 130] -> [11 130] ✔️[0 127] -> [0 128]
powershell (conhost) ✔️[0 51] -> [11 51] ✔️[0 7] -> [0 8]
powershell (windows terminal, conpty) ✔️[0 29] -> [11 29] ❌[0 29] -> [0 29]
bash (mintty, conpty) ✔️[0 26] -> [11 26] ❌[0 26] -> [0 26]
bash (VS Code terminal, conpty) ✔️[0 13] -> [11 13] ❌[0 13] -> [0 13]

If the text is long enough to cause line wrap, ConPTY does not move the cursor in Y axis as well, while conhost does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIt either shouldn't be doing this or needs an investigation.Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions