Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs keydown/keyup events

I'm interested in seeing if it's possible to bind functions to a user pressing/releasing a key on the keyboard.

So far, I've been able to get key press events with the keypress module and process.stdin's raw mode:

var keypress = require('keypress');
keypress(process.stdin);
process.stdin.on('keypress', function(ch, key) {
    console.log('got "keypress"', key);
    if (key && key.ctrl && key.name == 'c') {
        process.exit();
    }
});
process.stdin.setRawMode(true);
process.stdin.resume();

Are capturing keyboard press and release events even possible in a terminal?

It should be worth noting that I am not interested in any browser implementations; I am looking for something that runs in NodeJS in a terminal.

Thanks, all.

like image 731
Michael Tang Avatar asked Apr 26 '14 23:04

Michael Tang


People also ask

What is the difference between the Keydown and Keyup events?

Occur in sequence when a user presses and releases a key. KeyDown occurs when the user presses a key. KeyUp occurs when the user releases a key.

How do you get the value of a Keydown event?

The simple solution: just use the keyup event (and not the keydown event). This will give you the latest value after the user typed the latest character. That resolves the issue.

What is the Keyup event?

The keyup event is sent to an element when the user releases a key on the keyboard. It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.


1 Answers

So I figured a workaround the limitations of stdin to get this to work.

Basically I use the SDL library (along with its node bindings) to run a program in the background that listens on the keyboard for input.

To do this:

  • Ensure you are running Node version ~0.10. (Apparently the way C bindings on node work a little differently in 0.11?)
  • Install sdl, sdl_ttf, and sdl_image through homebrew (on a mac)
  • npm install --save https://github.com/creationix/node-sdl/tarball/master

And then something along the lines of:

var sdl = require('sdl');

sdl.init(sdl.INIT.VIDEO);

while (true) {
    var e;
    while (e = sdl.pollEvent()) {
        console.log(e);
    }
}

SDL_PollEvent requires SDL be initialized with SDL_INIT_VIDEO, which in the script above (on a mac) starts a separate application in the dock that draws nothing, but needs to be focused to accept input.

While it's technically true that ANSI terminals simply do not support keyup events, this workaround totally lets one grab keyup events in Node (albeit requiring some GUI-based system to function, i.e. most likely will not work over ssh).

like image 72
Michael Tang Avatar answered Oct 01 '22 03:10

Michael Tang