# KeyEvent

This Event subclass represents keyboard events. These events let you know when the user presses and releases keys on the keyboard, and when keys auto-repeat when being held down. These are essentially the unfiltered keyboard events directly from Windows, and they're passed to the Javascript event listeners before PinballY itself processes the keystrokes, so you can use these events to change the way PinballY sees and responds to key presses.

The basic keyboard event type comes in the following subtypes:

- keydown: Fires when the user presses a key while the program is running in the foreground. Also fires each time a key "auto-repeats" while the user is holding it down.
- keyup: Fires when the user releases a key while the application is in the foreground.
- keybgdown: Fires when the user presses a key while the program is running in the background, and fires again each time the key auto-repeats while the user holds the key down.
- keybgup: Fires when the user releases a key while the application is in the background.

Keyboard events are always fired on the mainWindow object.

Note that key events are specifically for keyboard keys. Joystick button presses generate a similar but separate set of events, since joystick buttons are described by somewhat different metadata from that used for keyboard keys. See JoystickButtonEvent for details on the joystick events.

## Properties

This event type has all of the standard event properties and methods (see the Event class), plus the following:

- background: true if the application was in the background when the event occurred, false if not. PinballY processes key presses that occur while it's in the background so that it can monitor "Exit Game" and "Pause Game" command keys while a game is running.
- code: A string representing the key pressed, using the same naming as in standard Web browser keydown messages. See, for example, Key Values (MDN). Key codes are not affected by any modifier key status (Shift, Ctrl, CapsLock, etc), so this tells you the actual key pressed, independently of what modifier keys might also be pressed. For example, pressing the "2" key (on the main keyboard) always yields a code value of "Digit2", even when the Shift key is pressed.
- key: A string representing the key pressed, using the same format used in Web browser keydown messages. For printable characters, this is the character itself, with the modifier key state (Shift, CapsLock, NumLock) applied. For example, holding down the Shift key and pressing the "2" key (on the main keyboard) produces a keydown event with key set to "@". For special characters (cursor keys, F-keys, etc), this uses the standard browser name for the key, usually the same name as in code.
- location: A keyboard location code for the key:
  - KEY_LOCATION_STANDARD (0), standard location used by most keys
  - KEY_LOCATION_LEFT (1), the left key of a paired modifier key (Shift, Control, Alt, Meta)
  - KEY_LOCATION_RIGHT (2), the right key of a pair modifier key
  - KEY_LOCATION_NUMPAD (3), the numeric keypad
- repeat: true if this is an auto-repeat key event from a key being held down, false if not
- vkey: A number representing the Windows "virtual key code" value for the key

Note that the common Web browser "which", "keyCode", and "charCode" properties are all missing. That's because these were always problematic and poorly defined. I didn't want to add to that mess with yet another ad hoc variation. All modern browsers have moved to the better-defined "code" and "key" system, which provides more complete and consistent information. The PinballY-specific "vkey" value is provided in case you need the low-level Windows event information for some reason, such as for directly calling a Windows API function.

## Background key events

The "bg" key events are used when the application is running in the background, meaning that some other application's window is activated (that is, the other application's window in the foreground and has keyboard focus). PinballY monitors the keyboard while it's in the background so that it can carry out commands that operate on a running game, such as "End Game" and "Pause Game".

We use separate Javascript events for foreground and background key presses for two reasons. The first is to simplify your event handlers. In most cases, you won't want to do anything at all with background key events, so using separate event types for the two cases lets you skip extra checks for the foreground or background status. You can simply write all of your foreground key handler code in a foreground key handler function, knowing that that function will only be called for foreground keys. The second reason is that it reduces the performance overhead for processing the background events, by entirely skipping user-written event handler code that only needs to run for foreground keys. It's especially important to minimize PinballY's performance impact while it's in the background so that it doesn't slow down a running game. (The performance impact when no event handler is present is negligible: in the absence of a user-written event handler, the basic processing to fire a background keyboard event takes on the order of 100μs.)

If you want to write a single handler that operates on both foreground and background key events, the Event Target on() method makes that easy: just specify both event types when adding the handler:

mainWindow.on("keydown keybgdown", (ev) => { /* common handler */ });

It's not possible to use the background key event handlers to change or block keystrokes that the foreground application receives. PinballY receives background keys via the Windows RAW INPUT mechanism, which only monitors the keys. It's essentially a passive wire-tap. Windows sends the keystrokes to the foreground application regardless of what PinballY does with the events from its background handler.