eitype
A library and CLI tool for typing text using the Emulated Input (EI) protocol on Wayland.
Features
- Type text using the EI (Emulated Input) protocol
- Support for special keys (enter, tab, escape, arrows, function keys, etc.)
- Support for modifier keys (shift, ctrl, alt, super)
- XDG RemoteDesktop portal support with session persistence
- Direct socket connection support
- Configurable delay between key events
- Keyboard layout configuration via CLI or environment variables
- Python bindings for use in Python applications
- Rust library for integration into other Rust projects
Installation
Using pixi (recommended)
Pixi handles all dependencies (including libxkbcommon) automatically:
# Build and install Python bindings
# Install CLI
# Run tests
Manual Installation
System Dependencies
If not using pixi, install the required system libraries first:
| Distribution | Command |
|---|---|
| Debian/Ubuntu | sudo apt install libxkbcommon-dev |
| Fedora/RHEL | sudo dnf install libxkbcommon-devel |
| Arch Linux | sudo pacman -S libxkbcommon |
| openSUSE | sudo zypper install libxkbcommon-devel |
CLI
Python
Usage
# Type text (uses XDG RemoteDesktop portal by default)
# Type with delay between keys (10ms)
# Press special keys
# Hold modifier while typing
# Press and release a modifier
# Multiple texts
# Verbose output
Connection Methods
XDG RemoteDesktop Portal (Default)
By default, eitype connects via the XDG RemoteDesktop portal. This works with desktop environments that support it (GNOME, KDE, etc.).
Session Persistence
eitype automatically saves a session token to avoid the authorization dialog on subsequent runs. The token is stored at ~/.cache/eitype/restore_token.
- First run: Shows the authorization dialog, saves token for future use
- Subsequent runs: Uses saved token, no dialog needed
- Token expiration: If the token becomes invalid, a new dialog will appear
To force a new authorization dialog (clear the saved token):
Direct Socket
Use the -s flag to specify a socket path, or set the LIBEI_SOCKET environment variable to bypass the portal:
# or
Special Keys
Supported special key names (case-insensitive):
escape,escreturn,entertabbackspacedeleteinserthome,endpageup,pagedownup,down,left,rightf1throughf12spacecapslock,numlock,scrolllockprint,printscreenpause,menu
Modifier Keys
Supported modifier names (case-insensitive):
shift,lshift,rshiftctrl,control,lctrl,rctrlalt,lalt,ralt,altgrsuper,meta,win,lsuper,rsuper
Keyboard Layout
eitype uses XKB for keyboard layout handling. The keymap is determined in the following order:
- EI server keymap - If the EI server provides a keymap, it is used automatically
- CLI/environment configuration - If no server keymap, uses specified layout
- System default - Falls back to the system's default XKB configuration
CLI Options
# Use German keyboard layout
# Use US Dvorak layout
# Full XKB configuration
# Select a specific layout index when multiple layouts are available
Multi-Layout Keymaps
When the EI server provides a keymap with multiple layouts (e.g., Dvorak + QWERTY), eitype uses layout index 0 by default. This is typically correct since layout 0 is the first/active layout.
If you need to use a different layout, specify it with --layout-index:
# Use the second layout (index 1)
Use -vv to see all available layouts in the keymap.
Environment Variables
You can also set keyboard layout via environment variables (CLI options take precedence):
XKB_DEFAULT_LAYOUT- Keyboard layout (e.g., "us", "de", "fr")XKB_DEFAULT_VARIANT- Layout variant (e.g., "dvorak", "colemak", "nodeadkeys")XKB_DEFAULT_MODEL- Keyboard model (e.g., "pc104", "pc105")XKB_DEFAULT_OPTIONS- XKB options (e.g., "ctrl:nocaps")XKB_DEFAULT_RULES- XKB rules file
# Set German layout via environment
# Override with CLI
XKB_DEFAULT_LAYOUT=de
Python Usage
# Simple connection via portal
=
# With custom configuration
=
=
# Modifier keys
Token Persistence (for long-running apps)
For applications that run continuously (like voice typing tools), you can save and reuse the portal authorization token:
# First run - will show authorization dialog
, =
# Save for next time
# Subsequent runs - no dialog needed
=
, =
Rust Library Usage
Add to your Cargo.toml:
[]
= { = "../eitype" } # or from crates.io when published
use ;
Development
# Set up dev environment with pre-commit hooks
# Run linting (cargo fmt + clippy)
Requirements
- Rust 1.70+
- Python 3.10+ (only for Python bindings)
- libxkbcommon (handled automatically by pixi, or install manually)
License
Apache 2.0