Skip to content

ENABLE_VIRTUAL_TERMINAL_INPUT is sometimes ignored when key is held down #14320

@NightPixel

Description

@NightPixel

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-VTVirtual Terminal sequence supportIssue-BugIt either shouldn't be doing this or needs an investigation.Product-TerminalThe new Windows Terminal.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions