8 releases (breaking)
Uses new Rust 2024
| 0.7.0 | Jul 14, 2026 |
|---|---|
| 0.6.0 | Jun 12, 2026 |
| 0.5.1 | Jun 8, 2026 |
| 0.4.0 | May 26, 2026 |
| 0.1.0 | May 14, 2026 |
#133 in Accessibility
105KB
2.5K
SLoC
InfiniKey
Tool that allows programmable keyboards to send arbitrary Unicode characters. For example, you can use it for things like:
- Emoji 🌈 ✅ ✨
- Non-latin scripts
א ߒ ش - Special characters
€ » « - Other symbols
⯅ × ∞
Key Features
- Independent of your operating system's keymap
- Cross-platform: Windows & Linux (Wayland only)
- Written in Rust to be fast, reliable and secure
- 100% human made. No AI was used to generate, transform or augment any code or documentation written for InfiniKey. To the best of my knowledge, the same is true for those parts of the InfiniKey code which were copied from Espanso.
Details
InfiniKey listens for keyboard events, specifically keypresses of F13 to F24. When the end of a sequence is detected, InfiniKey converts it into Unicode codepoints and sends it to the OS.
Comparison
A similar thing could be achieved with Espanso or AutoHotkey's "hotstring" feature:
When those tools detect a specific phrases such as :date,
they send simulated backspace key presses to remove the trigger phrase and then send the replacement text, for example December 7, 2024.
Compared to that approach, InfiniKey offers several advantages:
- Relying on function keys which are otherwise unused means that the original key events are harmless and there is no need to undo them. This avoids problems that occur in Chrome or Electron-based applications where sometimes, parts of the replacement text get lost or the text caret ends up in the wrong position.
- InfiniKey does not need to be configured for specific sequences, you only need to configure your keyboard to send the sequence for the characters you want.
Various design choices result in these potential disadvantages:
- InfiniKey cannot be used with non-programmable keyboards.
- It does not offer dynamic expansion such as the date example above. It also cannot invoke scripts or third-party tools.
Security and Privacy
- InfiniKey operates 100% locally. There are no network calls whatsoever.
- To avoid accidentally logging sensitive data, or being misused as a keylogger, InfiniKey entirely ignores letter and number keys.
- The privileges required on Linux systems to access the input device are only acquired briefly at startup and then dropped irreversibly.
To limit its attack surface, InfiniKey does not support being run as root or as a user within the
inputgroup. - Before injection,
EnterandTabcodepoints are removed from the received sequence.
Known shortcut collisions & solutions
- Linux
- General
- Several function keys in the F13-F24 range have special mappings by default. Here is how to neutralize them:
- KDE Plasma
- Open System Settings, select "Keyboard" and then
click the
Key Bindingsbutton in the top right corner. Check "Configure keyboard options", then enter "F13" in the search bar. Check "Use F13-F24 as usual function keys". ClickApply.
- Open System Settings, select "Keyboard" and then
click the
- Other desktop environments
- Follow the instructions in Matthew Sanabria's article Functional Keys with X Keyboard Extension (XKB).
- KDE Plasma
- Several function keys in the F13-F24 range have special mappings by default. Here is how to neutralize them:
- Firefox:
F14(Undo) andF18(Paste)- No workaround known. InfiniKey's default configuration avoids these keys.
- General
- Windows
- Microsoft OneNote:
F16(Backspace)- No workaround known. InfiniKey's default configuration avoids this key.
- Microsoft OneNote:
Installation
Linux
- Prerequisites:
cargoandrustc, v1.89 or above- Install via rustup (recommended) or as a system package (may be outdated)
- System packages: C compiler & libudev
- Fedora:
sudo dnf install cc libudev-devel - Ubuntu:
sudo apt install gcc
- Fedora:
- Build and install
cargo install infinikey - Enable permissions
sudo setcap cap_dac_override=p $(which ik-daemon) - Set up systemd service on user level
infinikey service register - Start InfiniKey
systemctl --user start infinikey
Windows
- Prerequisites:
cargoandrustc, v1.89 or above- Install via rustup
- Build and install
cargo install infinikey - Set up autostart shortcut
infinikey service register - Start InfiniKey
ik-daemon background
Basic usage
- Decide on the characters or character sequences you want to type, for example
🌐on one key and(◕‿◕)on another. - Use the InfiniKey CLI to encode them.
- By default, each mapping is printed as a list of function keys:
infinikey encode -m "🌐:globe" "(◕‿◕):face"🌐 globe F19, F22, F13, F20, F23, F23, F13, F22, F17, F17, F13, F24 (◕‿◕) face F17, F20, F19, F20, F17, F20, F21, F23, F15, F17, F23, F20, F17, F20, F13, F15, F19, F23, F23, F20, F17, F20, F21, F23, F15, F17, F20, F21, F15, F24 - Passing the
--zmkoption generates a ready-to-use snippet for ZMK keyboards:infinikey encode -m "🌐:globe" "(◕‿◕):face" --zmk#define IK_12(name, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12) \ name: name { \ label = #name; \ compatible = "zmk,behavior-macro"; \ #binding-cells = <0>; \ wait-ms = <0>; \ tap-ms = <2>; \ bindings \ = <¯o_tap &kp k1 &kp k2 &kp k3 &kp k4 &kp k5 &kp k6 &kp k7 &kp k8 &kp k9 &kp k10 &kp k11 &kp k12> \ ; \ }; #define IK_30(name, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30) \ name: name { \ label = #name; \ compatible = "zmk,behavior-macro"; \ #binding-cells = <0>; \ wait-ms = <0>; \ tap-ms = <2>; \ bindings \ = <¯o_tap &kp k1 &kp k2 &kp k3 &kp k4 &kp k5 &kp k6 &kp k7 &kp k8 &kp k9 &kp k10 &kp k11 &kp k12 &kp k13 &kp k14 &kp k15 &kp k16 &kp k17 &kp k18 &kp k19 &kp k20 &kp k21 &kp k22 &kp k23 &kp k24 &kp k25 &kp k26 &kp k27 &kp k28 &kp k29 &kp k30> \ ; \ }; // 🌐 IK_12(globe, F19, F22, F13, F20, F23, F23, F13, F22, F17, F17, F13, F24) // (◕‿◕) IK_30(face, F17, F20, F19, F20, F17, F20, F21, F23, F15, F17, F23, F20, F17, F20, F13, F15, F19, F23, F23, F20, F17, F20, F21, F23, F15, F17, F20, F21, F15, F24)
- By default, each mapping is printed as a list of function keys:
- Configure your keyboard to send the respective function key sequence for the desired keys.
- For non-ZMK keyboards, see the manual or firmware documentation for instructions. Have the keyboard send the sequence as regular keypresses with short wait/tap times. Usually, about 2 milliseconds should be sufficient.
- For ZMK-based keyboards, you can paste the generated snippet into a
macros { }block in the keymap / device tree. Then, map the desired keys to the new behaviors. In the example above, you would use&globeand&faceinstead of built-in behaviors such as&kp.
Acknowledgements
InfiniKey's low-level event detection and text injection capabilities are based on Espanso. Without their great work, InfiniKey would not have been possible.
License
InfiniKey as a whole is licensed under the GPL 3.0 or later. Some parts are licensed under the CC BY 3.0 license.
All files state their individual copyright and license following the REUSE specification.
Dependencies
~4–20MB
~261K SLoC