Skip to content

dart:io - stdin does not report bytes for many keys on windows #48329

@ellemenno

Description

@ellemenno

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 chars 0x20 - 0x7e
Backspace 0x08 (␈) and Delete 0x7f (␡) are reported on all three OSes, but sometimes from different keys
Enter is reported as line feed 0x0a (␊) on linux and osx, and as carriage return 0x0d (␍) 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'

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-io

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions