linebender/druid · error

only xkb keymap supported for now

Error message

only xkb keymap supported for now

What it means

Guard in the wayland keyboard handler: when the compositor sends a wl_keyboard keymap event whose format is not XkbV1, the backend cannot build an xkb keymap and aborts. It fires when connecting to a compositor that advertises a non-xkb keymap format (e.g. no_keymap or a future format); druid-shell only implements xkb keymap decoding.

Solutions

  1. Run under a compositor that provides xkb v1 keymaps (standard wlroots/GNOME/KDE compositors)
  2. Implement keymap-format fallback handling (e.g. `NoKeymap`) in the backend
  3. File/update an upstream issue; treat the panic site as the extension point

Example fix

// before
if !matches!(format, wl_keyboard::KeymapFormat::XkbV1) {
    panic!("only xkb keymap supported for now");
}

// after
if format != wl_keyboard::KeymapFormat::XkbV1 {
    tracing::warn!("non-xkb keymap unsupported; ignoring");
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

if keymap_format != wl_keyboard::KeymapFormat::XkbV1 { /* skip or fallback before calling consume */ }

Type guard

fn is_xkb_v1(f: wl_keyboard::KeymapFormat) -> bool { matches!(f, wl_keyboard::KeymapFormat::XkbV1) }

Prevention

When it happens

Trigger: The Wayland compositor advertises a `KeymapFormat` other than `XkbV1` in the `wl_keyboard::Event::Keymap` event handled by `consume`.

Common situations: Unusual or minimal compositors, remote/desktop-sharing setups, or alternative keyboard backends that do not provide an xkb keymap.

Related errors


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/6a8e54757cf36b96. Report an issue: GitHub.

Appendix: source

Thrown at druid-shell/src/backend/wayland/keyboard.rs:141

        );
        event.mods = self.xkb_mods.get();

        if let Err(cause) = keystroke.queue.send(event) {
            tracing::error!("failed to send Druid key event: {:?}", cause);
        }
    }

    fn consume(
        &mut self,
        seat: u32,
        event: wl_keyboard::Event,
        keyqueue: calloop::channel::Sender<KeyEvent>,
    ) {
        tracing::trace!("consume {:?} -> {:?}", seat, event);
        match event {
            wl_keyboard::Event::Keymap { format, fd, size } => {
                if !matches!(format, wl_keyboard::KeymapFormat::XkbV1) {
                    panic!("only xkb keymap supported for now");
                }

                // TODO to test memory ownership we copy the memory. That way we can deallocate it
                // and see if we get a segfault.
                let keymap_data = unsafe {
                    buffers::Mmap::from_raw_private(
                        fd,
                        size.try_into().unwrap(),
                        0,
                        size.try_into().unwrap(),
                    )
                    .unwrap()
                    .as_ref()
                    .to_vec()
                };

                // keymap data is '\0' terminated.
                let keymap = self.xkb_context.keymap_from_slice(&keymap_data);

View on GitHub (pinned to 0f8b1195e4)