-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dart:io - stdin does not report bytes for many keys on windows #48329
Comments
hi, @kevmoo it's been a year, and this issue still exists on the latest stable dart (3.3.2): > dart --version
Dart SDK version: 3.3.2 (stable) (Tue Mar 19 20:44:48 2024 +0000) on "windows_x64" Esc ( any chance this can be addressed in a near-term release? |
Maybe @brianquinlan has some ideas? |
hi @brianquinlan & @kevmoo, i'm out of my depth here, but i'd like to help move this forward if i can (please let me know if there is something specifically helpful that I could do..) i've found that the ConEmu project has a handy demo utility called KeyEvents that shows what data is received on Windows when various keys are pressed. it demonstrates reacting to all the keys that Dart is missing in this issue. comparing implementations, Dart's looking at the Windows API docs, the limitations noted in this issue seem to be expected when using the
bool Stdin::ReadByte(intptr_t fd, int* byte) {
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
uint8_t buffer[1];
DWORD read = 0;
BOOL success = ReadFile(h, buffer, 1, &read, nullptr);
if (!success && (GetLastError() != ERROR_BROKEN_PIPE)) {
return false;
}
*byte = (read == 1) ? buffer[0] : -1;
return true;
} ..whereas the // ..
INPUT_RECORD r, rl = {};
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
BOOL lbEscPressed = FALSE;
wchar_t szFormat[1024];
// ..
while (TRUE)
{
memset(&r, 0, sizeof(r)); dw = 0;
if (ReadConsoleInput(h, &r, 1, &dw))
{
// ..
__INPUT_RECORD_Dump(&r, szFormat);
DWORD nLen = wcslen(szFormat);
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szFormat, nLen, &nLen, NULL);
// ..
}
} so, can the Windows ReadByte implementation be updated to use the ReadConsoleInput API and gain parity with the Mac and Linux implementations? |
Just to note; mason_logger uses package win32 to enable raw mode. I use this in my own code to read arrow keys, backspace, and more from stdin: ///----- Arrow keys -----\\\
case 0x41:
// \1b[A
final modifiers = rolling.length == 1
? Modifiers.lut[rolling[0] - 1]!
: Modifiers.lut[0]!;
_events.add(KeycodeEvent('↑', Keycode.up, modifiers: modifiers));
return;
case 0x42:
// \1b[B
final modifiers = rolling.length == 1
? Modifiers.lut[rolling[0] - 1]!
: Modifiers.lut[0]!;
_events.add(KeycodeEvent('↓', Keycode.down, modifiers: modifiers));
return;
case 0x43:
// \1b[C
final modifiers = rolling.length == 1
? Modifiers.lut[rolling[0] - 1]!
: Modifiers.lut[0]!;
_events.add(KeycodeEvent('→', Keycode.right, modifiers: modifiers));
return;
case 0x44:
// \1b[D
final modifiers = rolling.length == 1
? Modifiers.lut[rolling[0] - 1]!
: Modifiers.lut[0]!;
_events.add(KeycodeEvent('←', Keycode.left, modifiers: modifiers));
return; |
Experience
i'm working on a cross-platform commandline app, testing with a simple stdin echo program in dart 2.16 (see below), and am noticing missing key codes when running in windows (but not in linux).
it seems like the silent keys on windows are Esc (
0x1b
), and the multi-byte code sequences that start with0x1b
on linux.Expectation
i expect to see some key code for every non-modifier key on my keyboard. i recognize some code values may differ across platforms.
Notes
so far, i'm testing windows cmd and wsl ubuntu on the same windows 10 machine, using the same Terminal app, and i see character codes from linux for all non-modifier keys (except PrtScr and the Windows ⊞ key), but am getting no value for a number of important keys from windows (ESC, function keys, arrow keys, and Insert,Delete,Home,End,PgUp,PgDn).
Windows Terminal version
1.11.3471.0
win (cmd.exe)
wsl (ubuntu bash)
OSX Terminal version
2.12 (443)
osx (darwin bash)
Test code
stdin.dart
Results
table of characters reported by
dart:io.stdin.readByteSync()
:0x1b
'␛'
0x1b
'␛'
0x4f
'O'
0x50
'P'
0x1b
'␛'
0x4f
'O'
0x51
'Q'
0x1b
'␛'
0x4f
'O'
0x52
'R'
0x1b
'␛'
0x4f
'O'
0x53
'S'
0x1b
'␛'
0x5b
'['
0x31
'1'
0x35
'5'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x31
'1'
0x37
'7'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x31
'1'
0x39
'8'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x31
'1'
0x39
'9'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x32
'2'
0x30
'0'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x32
'2'
0x31
'1'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x32
'2'
0x34
'4'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x32
'2'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x33
'3'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x41
'A'
0x1b
'␛'
0x5b
'['
0x42
'B'
0x1b
'␛'
0x5b
'['
0x43
'C'
0x1b
'␛'
0x5b
'['
0x44
'D'
0x1b
'␛'
0x5b
'['
0x35
'5'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x36
'6'
0x7e
'~'
0x1b
'␛'
0x5b
'['
0x46
'F'
0x1b
'␛'
0x5b
'['
0x48
'H'
The text was updated successfully, but these errors were encountered: