3 releases

new 0.1.2 Jan 26, 2025
0.1.1 Jan 23, 2025
0.1.0 Jan 21, 2025

#536 in Parser implementations

Download history 121/week @ 2025-01-15 348/week @ 2025-01-22

469 downloads per month
Used in 2 crates

MIT/Apache

2MB
52K SLoC

KBVM

crates.io docs.rs MSRV

KBVM is a rust implementation of the XKB specification and associated protocols. It supports

  • creating keymaps from XKB files,
  • creating keymaps from RMLVO names,
  • creating keymaps from X11 connections,
  • creating a composition state machine from XCompose files, and
  • loading the RMLVO registry.

A keymap can be turned into a compositor-side state machine or a client-side lookup table.

MSRV

The MSRV is max(1.83, stable - 3).

License

This project is licensed under either of

  • Apache License, Version 2.0
  • MIT License

at your option.


lib.rs:

KBVM is an implementation of the XKB specification and associated protocols.

At its core, KBVM provides two types:

  • StateMachine, a compositor-side keyboard state machine.
  • LookupTable, a client-side lookup table that can be used to look up keysyms.

These types can be created from XKB keymaps or RMLVO names by using an xkb::Context.

Additionally, KBVM provides other tools from the XKB ecosystem:

  • ComposeTables can be created from XCompose files as a simple input method.
  • XKB keymaps can be loaded from X11 connections via integration with the x11rb crate.
  • The RMLVO registry can be loaded to display the available RMLVO names to users.

While XKB keymaps can be used to create StateMachines and LookupTables, it is also possible to created these objects manually with the Builder type. To retain compatibility with XKB, any LookupTable can be turned into an XKB keymap.

Manually created StateMachines allow you to run arbitrary logic when keys are pressed and released. For example, you can use this logic to implement sticky keys, radio groups, locked keys, key redirection, latching keys, etc.

The common compositor pattern

If you are developing a wayland compositor, you might use this crate as follows:

  1. For each seat, the user configures either an XKB map directly or a set of RMLVO names from which you have to create an XKB map.

  2. Either way, you use an xkb::Context and either keymap_from_bytes or keymap_from_names to create an xkb::Keymap.

  3. You can format this keymap as a string by using Keymap::format. You send this keymap to clients via the wl_keyboard.keymap event.

  4. You then use Keymap::to_builder followed by Builder::build_state_machine to create a StateMachine.

  5. Whenever you receive a libinput key event, you feed it into the StateMachine with StateMachine::handle_key. This in turn produces a number of Events that you forward to clients.

    The handle_key documentation contains an example showing how to do this correctly.

If you are also handling keyboard shortcuts in your compositor, you will likely also want to create a LookupTable as described in the next section.

The common client pattern

If you are developing a wayland client, you might use this crate as follows:

  1. For each seat, you receive a keymap via the wl_keyboard.keymap event.
  2. You use an xkb::Context and keymap_from_bytes to create an xkb::Keymap from the buffer from the event.
  3. You then use Keymap::to_builder followed by Builder::build_lookup_table to create a LookupTable.
  4. You create a Components object to store the active modifiers and group of the keyboard.
  5. Whenever you receive a wl_keyboard.modifiers event, you update the Components as shown in Components::update_effective.
  6. Whenever you receive a wl_keyboard.key event for a key press, you use LookupTable::lookup to look up the keysyms produced by this event, using the effective modifiers and group from your Components.

Dependencies

~3–18MB
~184K SLoC