A cross-platform Rust library for implementing Input Method Engines (IME) using native protocols.
imekit provides native protocol implementations for creating input methods:
- Linux/Wayland:
zwp_input_method_v2andzwp_text_input_v3protocols - Linux/X11: XIM (X Input Method) protocol
- Linux/IBus: IBus D-Bus interface (fallback when Wayland protocol unavailable)
- Windows: Text Services Framework (TSF)
- macOS: Input Method Kit (IMK)
This is not a text insertion library. It implements the actual IME protocols that allow you to:
- Register as an input method with the system
- Receive text input context (surrounding text, content type)
- Commit text and preedit strings
- Create popup surfaces for candidate windows
| Feature | Description |
|---|---|
log |
Enable logging via the log crate |
tracing |
Enable logging via the tracing crate |
ibus |
Enable IBus support for Linux (via zbus D-Bus interface) |
| Platform | Protocol | Status |
|---|---|---|
| Linux/Wayland | zwp_input_method_v2 |
✅ Full support |
| Linux/Wayland | zwp_text_input_v3 |
✅ Full support |
| Linux/X11 | XIM | ✅ Full support |
| Linux/IBus | D-Bus | ✅ Full support (with ibus feature) |
| Windows | TSF (Text Services Framework) | ✅ Full support |
| macOS | CGEvent/NSTextInputClient | ✅ Full support |
| Compositor | Support |
|---|---|
| sway | ✅ Full support |
| Hyprland | ✅ Full support |
| KDE Plasma | ✅ Good support |
| GNOME/Mutter | ibus feature) |
| wlroots-based | ✅ Generally supported |
Add to your Cargo.toml:
[dependencies]
imekit = "0.1"
# Optional: Enable logging
imekit = { version = "0.1", features = ["log"] }
# Optional: Enable IBus fallback for GNOME/Mutter
imekit = { version = "0.1", features = ["ibus"] }use imekit::{InputMethod, InputMethodEvent};
fn main() -> Result<(), imekit::Error> {
// Auto-detects Wayland vs X11 on Linux
// Falls back to IBus if Wayland protocol unavailable (with `ibus` feature)
let mut im = InputMethod::new()?;
loop {
while let Some(event) = im.next_event() {
match event {
InputMethodEvent::Activate { serial } => {
println!("IME activated");
// Commit text when activated
im.commit_string("Hello! 👋")?;
im.commit(serial)?;
}
InputMethodEvent::SurroundingText { text, cursor, anchor } => {
println!("Context: {} (cursor: {})", text, cursor);
}
InputMethodEvent::Deactivate => {
println!("IME deactivated");
}
_ => {}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}use imekit::wayland_impl::{TextInput, TextInputEvent};
fn main() -> Result<(), imekit::Error> {
let mut ti = TextInput::new()?;
ti.enable();
ti.commit();
loop {
while let Some(event) = ti.next_event() {
match event {
TextInputEvent::CommitString { text } => {
if let Some(text) = text {
println!("Received: {}", text);
}
}
TextInputEvent::PreeditString { text, .. } => {
if let Some(text) = text {
println!("Composing: {}", text);
}
}
_ => {}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}#[cfg(feature = "ibus")]
use imekit::ibus_impl::IBusInputMethod;
fn main() -> Result<(), imekit::Error> {
#[cfg(feature = "ibus")]
{
// Create IBus input method directly
let im = IBusInputMethod::new()?;
// Use im...
}
Ok(())
}- Compositor with
zwp_input_method_v2support libwayland-devfor Wayland client libraries
- X11 display server with XTest extension
libx11-devandlibxtst-devfor X11 libraries
- IBus daemon running
- D-Bus session bus available
- Windows 8+ with TSF support
- macOS 10.5+ with Accessibility permissions
Licensed under either of:
- Apache License, Version 2.0
- MIT license