microsoft / microsoft/terminal

ENABLE_VIRTUAL_TERMINAL_INPUT is sometimes ignored when key is held down

Open
#14,320 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Windows Terminal version

1.15.2874.0

Windows build number

10.0.19045.2130

Other Software

No response

Steps to reproduce

Compile and run the following C program. When the program is running, hold down the F1 key.

#include <Windows.h>

int main(int argc, char* argv[])
{
    HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(handle, &mode);
    SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_INPUT);

    while (1)
    {
        // If there are characters in the console input buffer...
        if (_kbhit())
        {
            // ... read the whole buffer and print its contents.
            while (_kbhit())
            {
                printf("%d ", _getch());
            }
            printf("\n");
        }
        Sleep(100);
    }

    return 0;
}
Expected Behavior

The program prints the character values that are inserted in the console input buffer. Because ENABLE_VIRTUAL_TERMINAL_INPUT was set, I would expect the number sequence 27 79 80 to be printed repeatedly when the F1 key is held down.

(The numeric values 27 79 80 correspond to the character input sequence ESC O P, which is the sequence for F1 as documented on https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#input-sequences)

Actual Behavior

Here's a snippet of actual output that was produced when I held down F1:

27 79 80
27 79 80
27 79 80 27 79 80 27 79 80 27 79 80
27 79 80 27 79 80 27 79 80
27 79 80 27 79 80 27 79 80 0 59
27 79 80 27 79 80
27 79 80 27 79 80 27 79 80 27 79 80

Most of the output consists of repeats of the sequence for F1, which is 27 79 80 -- as expected.
But look at line 5: there's another sequence 0 59 in there as well! I didn't press any other keys, but occasionally a spurious 0 59 sequence is apparently thrown into the console input buffer.

What's interesting about the numbers 0 59 specifically is that that's the exact sequence that would be printed if ENABLE_VIRTUAL_TERMINAL_INPUT was not enabled. After all, according to the documentation for _getch() (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch):

The _getch and _getwch functions read a single character from the console without echoing the character. None of these functions can be used to read CTRL+C. To read a function key or arrow key, each function must be called twice. The first call returns 0 or 0xE0. The second call returns the key scan code.

(Side note: When you comment out the setup code in the provided example program where ENABLE_VIRTUAL_TERMINAL_INPUT is set, you can see that the program repeatedly prints 0 59 in conhost.exe, confirming that 0 59 is indeed what _getch() usually reports when F1 is pressed. But in Windows Terminal you'll still see the same output as before -- looks like Windows Terminal always sends VT100-style input sequences regardless of the ENABLE_VIRTUAL_TERMINAL_INPUT flag).

The described problem also occurs when you hold down other keys that produce special input sequences, such as other function keys, the arrow keys, or insert/delete/home/end/page up/page down.

Finally, note that the call to Sleep() at the end of the loop is very important to reproduce this issue! If you remove the Sleep(), or if you sleep for a short enough time such as 10ms instead of 100ms, the problem goes away: there won't be any spurious input sequences in the program's output!

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 compiling and running the provided C reproduction in Windows Terminal, with ENABLE_VIRTUAL_TERMINAL_INPUT enabled and the 100ms Sleep call retained. Compare the input produced while holding F1 and the other listed special keys, and trace how the terminal handles those input sequences. Done means no spurious 0 59 sequences appear when VT input is enabled.

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
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.