Windows Terminal does not set CAPSLOCK_ON in KEY_EVENT_RECORD.dwControlKeyState #17149

Open
opened 2026-01-31 05:33:31 +00:00 by claunia · 0 comments
Owner

Originally created by @matkaas on GitHub (Apr 4, 2022).

Windows Terminal version

1.11.3471.0

Windows build number

10.0.19044.1586

Other Software

No response

Steps to reproduce

Run the following code in Windows Terminal and Conhost respectively. Compile with /std:c++latest for std::format.
Strike some keys with capslock off and on.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <format>

void write_key_event(HANDLE console_out, KEY_EVENT_RECORD& key_event) {
    auto unicode = key_event.uChar.UnicodeChar;
    auto unicode_str = unicode < 32 ? std::wstring(L" ") : std::wstring(1, unicode);
    auto key_state = (key_event.bKeyDown ? L"Down" : L"Up");
    auto msg = std::format(
        L"KeyState: {:>4}, KeyCode: {:#04x}, ScanCode: {:#04x}, Unicode: {} ({:#06x}), Modifiers: {:#06x}\n",
        key_state, key_event.wVirtualKeyCode, key_event.wVirtualScanCode,
        unicode_str, unicode, key_event.dwControlKeyState);
    WriteConsoleW(console_out, msg.data(), msg.length(), nullptr, nullptr);
}

int main() {
    HANDLE console_in = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE console_out = GetStdHandle(STD_OUTPUT_HANDLE);

    // Enable raw mode.
    SetConsoleMode(console_in, 0);

    while (true) {
        INPUT_RECORD input_record;
        DWORD num_records_read = 0;
        auto result = ReadConsoleInputW(console_in, &input_record, 1, &num_records_read);
        if (input_record.EventType != KEY_EVENT) {
            continue;
        }

        KEY_EVENT_RECORD& key_event = input_record.Event.KeyEvent;
        write_key_event(console_out, key_event);

        if (key_event.uChar.UnicodeChar == 'q') {
            break;
        }
    }

    return EXIT_SUCCESS;
}

Expected Behavior

When capslock is off, the "Modifiers: ..." does not include 0x80. With capslock on, it does include 0x80.

For example, I get this output in Conhost.exe:

C:\Users\Kaas\source\Playground\x64\Debug>Playground.exe
KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0080
KeyState:   Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0080
KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080
KeyState:   Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080
KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080
KeyState:   Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080
KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080
KeyState:   Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080
KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x51, ScanCode: 0x10, Unicode: q (0x0071), Modifiers: 0x0000

Actual Behavior

Works as expected in Conhost.

In Windows Terminal, the "Modifiers: ..." doesn't include 0x80 regardless of the state of capslock.

For example, I get this output in wt.exe:

C:\Users\Kaas\source\Playground\x64\Debug>Playground.exe
KeyState:   Up, KeyCode: 0x0d, ScanCode: 0x1c, Unicode:   (0x000d), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState:   Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode:   (0x0000), Modifiers: 0x0000
KeyState: Down, KeyCode: 0x51, ScanCode: 0x10, Unicode: q (0x0071), Modifiers: 0x0000

I haven't tested other keyboard modalities, since I don't have keys for those on my keyboard, but perhaps they're also affected?

Originally created by @matkaas on GitHub (Apr 4, 2022). ### Windows Terminal version 1.11.3471.0 ### Windows build number 10.0.19044.1586 ### Other Software _No response_ ### Steps to reproduce Run the following code in Windows Terminal and Conhost respectively. Compile with `/std:c++latest` for `std::format`. Strike some keys with capslock off and on. ``` #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <format> void write_key_event(HANDLE console_out, KEY_EVENT_RECORD& key_event) { auto unicode = key_event.uChar.UnicodeChar; auto unicode_str = unicode < 32 ? std::wstring(L" ") : std::wstring(1, unicode); auto key_state = (key_event.bKeyDown ? L"Down" : L"Up"); auto msg = std::format( L"KeyState: {:>4}, KeyCode: {:#04x}, ScanCode: {:#04x}, Unicode: {} ({:#06x}), Modifiers: {:#06x}\n", key_state, key_event.wVirtualKeyCode, key_event.wVirtualScanCode, unicode_str, unicode, key_event.dwControlKeyState); WriteConsoleW(console_out, msg.data(), msg.length(), nullptr, nullptr); } int main() { HANDLE console_in = GetStdHandle(STD_INPUT_HANDLE); HANDLE console_out = GetStdHandle(STD_OUTPUT_HANDLE); // Enable raw mode. SetConsoleMode(console_in, 0); while (true) { INPUT_RECORD input_record; DWORD num_records_read = 0; auto result = ReadConsoleInputW(console_in, &input_record, 1, &num_records_read); if (input_record.EventType != KEY_EVENT) { continue; } KEY_EVENT_RECORD& key_event = input_record.Event.KeyEvent; write_key_event(console_out, key_event); if (key_event.uChar.UnicodeChar == 'q') { break; } } return EXIT_SUCCESS; } ``` ### Expected Behavior When capslock is off, the "Modifiers: ..." does not include 0x80. With capslock on, it does include 0x80. For example, I get this output in Conhost.exe: ``` C:\Users\Kaas\source\Playground\x64\Debug>Playground.exe KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x51, ScanCode: 0x10, Unicode: q (0x0071), Modifiers: 0x0000 ``` ### Actual Behavior Works as expected in Conhost. In Windows Terminal, the "Modifiers: ..." doesn't include 0x80 regardless of the state of capslock. For example, I get this output in wt.exe: ``` C:\Users\Kaas\source\Playground\x64\Debug>Playground.exe KeyState: Up, KeyCode: 0x0d, ScanCode: 0x1c, Unicode: (0x000d), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x51, ScanCode: 0x10, Unicode: q (0x0071), Modifiers: 0x0000 ``` I haven't tested other keyboard modalities, since I don't have keys for those on my keyboard, but perhaps they're also affected?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#17149