2 releases

0.1.1 Jun 7, 2021
0.1.0 Jun 7, 2021

#683 in Hardware support



chord2key Chorded gamepad input on Linux


chord2key is a chorded input converter for any linux evdev device. It allows for the control of a virtual keyboard and mouse using your gamepad. Other gamepad input converters can only emulate a subset of the keyboard -- each gamepad button is mapped to a single keyboard button. chord2key is different because it allows for the mapping of combinations of gamepad buttons to a single keyboard+mouse action. This allows for a single gamepad to have user inputs that map to the entire keyboard while also controlling the mouse.

Table of contents:


The current installation method is to compile the source code.

Install the Rust compiler:

See https://www.rust-lang.org/tools/install

Download this repository and compile:

In your preferred terminal:

git clone https://github.com/nascheinkman/chord2key.git && cd chord2key
cargo build --release


The program can now be run in the terminal through the following command:

sudo YOUR_INSTALL_DIR/chord2key/target/release/chord2key YOUR_CONFIG_FILE


The repo comes with configurations for two devices: the Nintendo Switch Pro Controller and Nintendo Switch Combined Joy-Cons. Both require the dkms-hid-nintendo kernel module, and the joysticks require the joycond daemon. You could then run the program using the provided configuration file. For instance, if you have the Pro controller, you would run

cd YOUR_INSTALL_DIR/chord2key
sudo target/release/chord2key configs/nintendo_pro_controller/pro_keyboard.json

It's currently difficult to make your own configuration file. If you're tech-savvy, you can look at the source code and see how the Pro controller configuration was generated here, and edit it to your own needs. You can then save the configuration to a config file through the config.save_to_file(FILE_PATH) function. See the commented lines here to see how the Pro controller configuration was saved.


Currently, input is separated into three different mappings.

It's recommended to keep the input sets for each input mapping unique. For instance, if you use the buttons A,B,X,Y to created chorded input, you should avoid using the button X, or any other one of those buttons, in modifier input.


Chords are a multiple to multiple mapping of button(s) and/or (multiple) thresholded axes to an output Action(s). Chords are "primed" when a chorded input is added to the current chord, "unprimed" when a chord action is emitted, and "reprimed" with any subsequent chord input. This means that if your chord takes 3 buttons, you can hold 2 down and spam the 3rd one to repeatedly emit that Action, without unintended side-effects.


Modifiers are a one to multiple mapping of a button or thresholded axis to Action(s). The associated action of a modifier is emitted both when the modifier is pressed down, and when it is released. These are typically used with Toggle actions so that modifier keys such as SHIFT can be combined with chorded letter input.

Axis Mouse

The mouse mapping maps a single thresholded axis to a linear mouse profile. When the axis passes the threshold, the relative difference is used to set the mouse velocity. The linear profile allows for smooth, intuitive mouse output from the axis position.

Note: Thresholded Axis

A thresholded axis can be thought of as an axis input with a dead-zone and a threshold direction. If the axis passes the dead-zone in the indicated direction, it can be thought of as "pressed", and when it recedes back into the dead-zone it can be thought to be "unpressed".


Actions can be split into two major categories:


These are standard actions that can be performed on a keyboard.


You can pulse key(s) and/or mouse. This can be thought of as tapping a keyboard button, or setting a mouse axis to a certain speed then back to where it was.


You can set the state of keys/axes directly. This can be thought of as holding a key down/up, or setting the mouse to a certain speed. Note that it doesn't automatically do the reverse like Toggle. If a chord is mapped to set a key to down, inputting the chord again won't change anything.


You can toggle the state of keys/axes. For keys, this means that if the key is down it's set to up, and if the key is up it's set to down. This action works really well with Modifier input. For axes, this means that if the mouse is currently set to the specified speed, it'll be set to 0, otherwise it'll be set to the specified speed.


These are special actions that act/depend on the internal state of the program.


This takes the last chord input that resulted in an OutputAction, converts it to the specified type, then executes that action. This is useful for repeating the last chord a lot. For instance, you can map A+B as a chord to Pulse the backspace key, and Y as a modifier to toggle RepeatLastChord. This means you can press A+B to press Backspace once, then press and hold Y to press and hold Backspace.


This allows you to hot swap the loaded configuration file to another one that operates on the same input device. This can be used in simple setups to create a blank configuration when you don't want there to be accidental inputs, that requires a complicated chord to switch to and from a fully mapped but sensitive keyboard configuration. More complicated setups are theoretically possible, but untested.


~116K SLoC