Skip to main content

Python bindings for eitype - type text on Wayland using the Emulated Input (EI) protocol

Project description

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
pixi run build

# Install CLI
pixi run install-cli

# Run tests
pixi run test

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

cargo install --path .

Python

pip install maturin
maturin develop --features python

Usage

# Type text (uses XDG RemoteDesktop portal by default)
eitype "Hello, World!"

# Type with delay between keys (10ms)
eitype -d 10 "Slow typing..."

# Press special keys
eitype -k return
eitype -k tab
eitype -k escape

# Hold modifier while typing
eitype -M ctrl c  # Ctrl+C

# Press and release a modifier
eitype -P shift

# Multiple texts
eitype "First line" -k return "Second line"

# Verbose output
eitype -v "Debug mode"
eitype -vv "More debug"

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.).

eitype "Hello"

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):

eitype --reset-token "Hello"

Direct Socket

Use the -s flag to specify a socket path, or set the LIBEI_SOCKET environment variable to bypass the portal:

eitype -s /path/to/ei/socket "Hello"
# or
export LIBEI_SOCKET=eis-0
eitype "Hello"

Special Keys

Supported special key names (case-insensitive):

  • escape, esc
  • return, enter
  • tab
  • backspace
  • delete
  • insert
  • home, end
  • pageup, pagedown
  • up, down, left, right
  • f1 through f12
  • space
  • capslock, numlock, scrolllock
  • print, printscreen
  • pause, menu

Modifier Keys

Supported modifier names (case-insensitive):

  • shift, lshift, rshift
  • ctrl, control, lctrl, rctrl
  • alt, lalt, ralt, altgr
  • super, meta, win, lsuper, rsuper

Keyboard Layout

eitype uses XKB for keyboard layout handling. The keymap is determined in the following order:

  1. EI server keymap - If the EI server provides a keymap, it is used automatically
  2. CLI/environment configuration - If no server keymap, uses specified layout
  3. System default - Falls back to the system's default XKB configuration

CLI Options

# Use German keyboard layout
eitype -l de "Hallo Welt"

# Use US Dvorak layout
eitype -l us --variant dvorak "Hello"

# Full XKB configuration
eitype -l us --variant dvorak --model pc104 --options "ctrl:nocaps" "Hello"

# Select a specific layout index when multiple layouts are available
eitype --layout-index 1 "Hello"

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)
eitype --layout-index 1 "Hello"

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
export XKB_DEFAULT_LAYOUT=de
eitype "Hallo"

# Override with CLI
XKB_DEFAULT_LAYOUT=de eitype -l fr "Bonjour"  # Uses French layout

Python Usage

from eitype import EiType, EiTypeConfig

# Simple connection via portal
typer = EiType.connect_portal()
typer.type_text("Hello from Python!")
typer.press_key("Return")

# With custom configuration
config = EiTypeConfig(layout="de", delay_ms=10)
typer = EiType.connect_portal(config)
typer.type_text("Hallo Welt!")

# Modifier keys
typer.hold_modifier("ctrl")
typer.press_key("c")
typer.release_modifiers()

Token Persistence (for long-running apps)

For applications that run continuously (like voice typing tools), you can save and reuse the portal authorization token:

from eitype import EiType

# First run - will show authorization dialog
typer, token = EiType.connect_portal_with_token()
if token:
    save_to_config(token)  # Save for next time

# Subsequent runs - no dialog needed
saved_token = load_from_config()
typer, _ = EiType.connect_portal_with_token(saved_token)
typer.type_text("No dialog this time!")

Rust Library Usage

Add to your Cargo.toml:

[dependencies]
eitype = { path = "../eitype" }  # or from crates.io when published
use eitype::{EiType, EiTypeConfig, EiTypeError};

fn main() -> Result<(), EiTypeError> {
    // Connect via portal
    let mut typer = EiType::connect_portal(EiTypeConfig::default())?;

    // Type text
    typer.type_text("Hello from Rust!")?;
    typer.press_key("Return")?;

    // With modifiers
    typer.hold_modifier("ctrl")?;
    typer.press_key("c")?;
    typer.release_modifiers()?;

    Ok(())
}

Development

# Set up dev environment with pre-commit hooks
pixi run -e dev install-hooks

# Run linting (cargo fmt + clippy)
pixi run -e dev lint

Requirements

  • Rust 1.70+
  • Python 3.10+ (only for Python bindings)
  • libxkbcommon (handled automatically by pixi, or install manually)

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

eitype-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

eitype-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

eitype-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

eitype-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

eitype-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

File details

Details for the file eitype-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for eitype-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 70521afd39c80f7bf4f7df31e8cc2cec4f23f5054d0b4a4eb2e47cb8601259d0
MD5 11aaa0509497c585721cf62b70ef268e
BLAKE2b-256 bc75fe9be9e6d708e06209f854d9f70305e0666d6d3af6f4eef2722cb172040a

See more details on using hashes here.

Provenance

The following attestation bundles were made for eitype-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on Adam-D-Lewis/eitype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eitype-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for eitype-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cfb99523daa7c52c429bab9124a5b9fca877643981b3ca67b28ab9bd4097af07
MD5 090287cfd4d8fcebbf419aaa8a71a575
BLAKE2b-256 464d956e84f87d7db8a32946c3633a398b3115fe63888db5bb06c3e05fd7561c

See more details on using hashes here.

Provenance

The following attestation bundles were made for eitype-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on Adam-D-Lewis/eitype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eitype-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for eitype-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 65af25a161f8e20bf34fcaf88854fc61ac35ddfa393fb8444cf2ca5752668f74
MD5 29aba6b411394ef4c6ef76d7233dd233
BLAKE2b-256 411cd96331858b8215fb3d64fb5f98913926569faf11310080981d12e7d85155

See more details on using hashes here.

Provenance

The following attestation bundles were made for eitype-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on Adam-D-Lewis/eitype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eitype-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for eitype-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5050830b6042cc2e1e60eaa015c111265efdecc2b8f7b4b522fc93bbbaaaad98
MD5 c47bae68ca5b0e72df0d3ef2ee8df9c5
BLAKE2b-256 e3a25bf66451da88ca9cea490241a5f4d6686d54cd09fb3dfce485c08af6a730

See more details on using hashes here.

Provenance

The following attestation bundles were made for eitype-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on Adam-D-Lewis/eitype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eitype-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for eitype-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe37a060b1eed5c466668d7bb03a03f62b1391101daa965286bc4af61c5d4542
MD5 dc1dfb0a3be695e1e8dcfc8d89fae667
BLAKE2b-256 3883a50d1063a38798a90563b912b1934384d20e792b4e56b8a657f3ac417e06

See more details on using hashes here.

Provenance

The following attestation bundles were made for eitype-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on Adam-D-Lewis/eitype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page