microsoft / microsoft/terminal

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

Open
#19,644 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area-Server Issue-Bug Priority-3 Product-Conpty
Dominant language
C++
Stars
105k
Forks
9.6k
Avg merge
3d 17h
Merged PRs (30d)
29

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied C++ program with an inactive console screen buffer under ConPTY and compare cursor positions for text containing a newline or wrapping line. Compare the results with conhost; done when ConPTY updates the inactive buffer's cursor position consistently for newlines and wrapped output.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
cli, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.