slint-ui/slint · error

Error compiling keymap

Error message

Error compiling keymap

What it means

In the linuxkms backend's calloop input handling, the first key event lazily creates an xkbcommon `Keymap` via `Keymap::new_from_names` with empty RMLVO names (using libxkbcommon defaults). If libxkbcommon cannot compile a keymap from those defaults, the code panics with "Error compiling keymap". This means no usable keyboard layout could be constructed for the session.

Solutions

  1. Install the xkeyboard-config data files (e.g. `apt install xkb-data` or the distro equivalent) so libxkbcommon can compile the default keymap.
  2. Verify libxkbcommon was built with keymap-from-names support and that XKB data path env vars (XKB_DATADIR/XKB_CONFIG_ROOT) point to valid data.
  3. Explicitly pass a known-good layout/model/rules to `Keymap::new_from_names` instead of empty strings in a patched backend build.
  4. As a workaround, supply a compiled keymap file via `Keymap::new_from_string` and adjust the backend to use it.

Example fix

// before
let keymap = xkb::Keymap::new_from_names(&xkb_context, "", "", "", "", None, 0)
    .expect("Error compiling keymap");

// after: fail gracefully / fall back
let keymap = xkb::Keymap::new_from_names(&xkb_context, "", "", "", "", None, 0)
    .or_else(|| {
        let rules = std::fs::read_to_string("/custom/keymap.xkb").ok()?;
        xkb::Keymap::new_from_string(&xkb_context, rules, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS)
    })
    .unwrap_or_else(|| eprintln!("xkbcommon keymap unavailable; keyboard input disabled"));
Defensive patterns

Strategy: fallback

Validate before calling

// probe keymap compilability before running keyboard-dependent code
let probe = xkb::Context::new(xkb::CONTEXT_NO_FLAGS)
    .and_check();
// on embedded targets, verify /usr/share/X11/xkb exists at startup
assert!(std::path::Path::new("/usr/share/X11/xkb").exists(), "xkb data missing");

Prevention

When it happens

Trigger: Receiving a key event in `process_events` when `keystate` is not yet initialized and `xkb::Keymap::new_from_names(&ctx, "", "", "", "", None, 0)` fails — typically when the libxkbcommon data files (keycodes/types/compat/symbols) are missing or the xkbcommon build can't produce a default keymap.

Common situations: Minimal or embedded Linux systems (kiosks, automotive HMI, embedded boards) without /usr/share/X11/xkb data or with a stripped libxkbcommon; broken XKB_CONFIG/XKB_DATADIR environment; musl/embedded builds missing keymap data packages.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/609dd061bce86dc4. Report an issue: GitHub.

Appendix: source

Thrown at internal/backends/linuxkms/calloop_backend/input.rs:328

                        let pos = take_touch_pos(&mut self.last_touch_positions, slot);
                        window.dispatch_event(WindowEvent::internal(InternalEvent::Touch {
                            id: slot,
                            position: logical_point_from_api(pos),
                            phase: i_slint_core::input::TouchPhase::Cancelled,
                        }));
                    }
                    _ => {}
                },
                input::Event::Keyboard(input::event::KeyboardEvent::Key(key_event)) => {
                    // On Linux key codes have a fixed offset of 8: https://docs.rs/xkbcommon/0.6.0/xkbcommon/xkb/struct.Keycode.html
                    let key_code = xkb::Keycode::new(key_event.key() + 8);
                    let state = key_event.key_state();

                    let xkb_key_state = self.keystate.get_or_insert_with(|| {
                        let xkb_context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
                        let keymap =
                            xkb::Keymap::new_from_names(&xkb_context, "", "", "", "", None, 0)
                                .expect("Error compiling keymap");
                        xkb::State::new(&keymap)
                    });

                    let sym = xkb_key_state.key_get_one_sym(key_code);

                    xkb_key_state.update_key(
                        key_code,
                        match state {
                            input::event::tablet_pad::KeyState::Pressed => xkb::KeyDirection::Down,
                            input::event::tablet_pad::KeyState::Released => xkb::KeyDirection::Up,
                        },
                    );

                    let control = xkb_key_state
                        .mod_name_is_active(xkb::MOD_NAME_CTRL, xkb::STATE_MODS_EFFECTIVE);
                    let alt = xkb_key_state
                        .mod_name_is_active(xkb::MOD_NAME_ALT, xkb::STATE_MODS_EFFECTIVE);

View on GitHub (pinned to bb937076de)