-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
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 with 0x1b
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).
update: added results from osx (practically identical to wsl)
Windows Terminal version 1.11.3471.0
win (cmd.exe)
> ver
Microsoft Windows [Version 10.0.19042.1466]
> dart --version
Dart SDK version: 2.16.0 (stable) (Mon Jan 31 15:28:59 2022 +0100) on "windows_x64"
wsl (ubuntu bash)
$ lsb_release --description
Description: Ubuntu 18.04.5 LTS
$ dart --version
Dart SDK version: 2.16.0 (stable) (Mon Jan 31 15:28:59 2022 +0100) on "linux_x64"
OSX Terminal version 2.12 (443)
osx (darwin bash)
$ sw_vers
ProductName: macOS
ProductVersion: 12.2
BuildVersion: 21D49
$ dart --version
Dart SDK version: 2.16.0 (stable) (Mon Jan 31 15:28:59 2022 +0100) on "macos_x64"
Test code
stdin.dart
import 'dart:io';
void main() {
stderr.write('\n');
stderr.write('type to echo the code sequence read by stdin.\n');
stderr.write("type 'q' to exit.\n");
stdin
..echoMode = false // for windows sake, echoMode must be disabled first
..lineMode = false; // see https://github.com/dart-lang/sdk/issues/28599#issuecomment-615940833
var codeRead, codePrint;
while (true) {
codeRead = 0;
codePrint = 0;
while (codeRead <= 0) {
codeRead = stdin.readByteSync();
}
if (codeRead == 0x7F) {
codePrint = 0x2421; // unicode control picture for delete (U+2421)
} else if (codeRead <= 0x20) {
codePrint = 0x2400 + codeRead; // replace with matching control picture (U+2400 - U+2420)
} else {
codePrint = codeRead; // printable string, so use as is
}
stderr.write(
"0x${codeRead.toRadixString(16).padLeft(2, '0')} '${String.fromCharCode(codePrint)}'\n");
if (String.fromCharCode(codeRead) == 'q') {
exit(0);
}
}
}
Results
table of characters reported by dart:io.stdin.readByteSync()
:
all same:
0x09
(␉), and printable chars0x20
-0x7e
Backspace0x08
(␈) and Delete0x7f
(␡) are reported on all three OSes, but sometimes from different keys
Enter is reported as line feed0x0a
(␊) on linux and osx, and as carriage return0x0d
(␍) on win
F11 is skipped in the table, because the terminal apps consume it first to toggle full-screen or mission control, and it doesn't get passed along.
key | wsl & osx | win |
---|---|---|
ESC | 0x1b '␛' |
|
F1 | 0x1b '␛' |
|
0x4f 'O' |
||
0x50 'P' |
||
F2 | 0x1b '␛' |
|
0x4f 'O' |
||
0x51 'Q' |
||
F3 | 0x1b '␛' |
|
0x4f 'O' |
||
0x52 'R' |
||
F4 | 0x1b '␛' |
|
0x4f 'O' |
||
0x53 'S' |
||
F5 | 0x1b '␛' |
|
0x5b '[' |
||
0x31 '1' |
||
0x35 '5' |
||
0x7e '~' |
||
F6 | 0x1b '␛' |
|
0x5b '[' |
||
0x31 '1' |
||
0x37 '7' |
||
0x7e '~' |
||
F7 | 0x1b '␛' |
|
0x5b '[' |
||
0x31 '1' |
||
0x39 '8' |
||
0x7e '~' |
||
F8 | 0x1b '␛' |
|
0x5b '[' |
||
0x31 '1' |
||
0x39 '9' |
||
0x7e '~' |
||
F9 | 0x1b '␛' |
|
0x5b '[' |
||
0x32 '2' |
||
0x30 '0' |
||
0x7e '~' |
||
F10 | 0x1b '␛' |
|
0x5b '[' |
||
0x32 '2' |
||
0x31 '1' |
||
0x7e '~' |
||
F12 | 0x1b '␛' |
|
0x5b '[' |
||
0x32 '2' |
||
0x34 '4' |
||
0x7e '~' |
||
Insert | 0x1b '␛' |
|
0x5b '[' |
||
0x32 '2' |
||
0x7e '~' |
||
Delete | 0x1b '␛' |
|
0x5b '[' |
||
0x33 '3' |
||
0x7e '~' |
||
Arrow ↑ | 0x1b '␛' |
|
0x5b '[' |
||
0x41 'A' |
||
Arrow ↓ | 0x1b '␛' |
|
0x5b '[' |
||
0x42 'B' |
||
Arrow → | 0x1b '␛' |
|
0x5b '[' |
||
0x43 'C' |
||
Arrow ← | 0x1b '␛' |
|
0x5b '[' |
||
0x44 'D' |
||
PgUp | 0x1b '␛' |
|
0x5b '[' |
||
0x35 '5' |
||
0x7e '~' |
||
PgDn | 0x1b '␛' |
|
0x5b '[' |
||
0x36 '6' |
||
0x7e '~' |
||
End | 0x1b '␛' |
|
0x5b '[' |
||
0x46 'F' |
||
Home | 0x1b '␛' |
|
0x5b '[' |
||
0x48 'H' |