linebender/druid · critical

keyboard event processing failed

Error message

keyboard event processing failed

What it means

After initializing the keyboard event loop, the Wayland backend runs `eventloop.dispatch(Duration::from_secs(60), ...)` in a loop-ish dispatch call; a dispatch returning Err (internal calloop error, dispatcher callback failure, or io error on the event source) is unwrapped with expect('keyboard event processing failed'), panicking the keyboard thread and ending key input/repeat handling.

Solutions

  1. Update druid-shell and calloop — dispatch error handling in the wayland keyboard backend has been improved in newer versions.
  2. Check for panics/errors inside the keyboard dispatch callback; fix the underlying source error.
  3. Verify the wayland connection remains alive; reconnect handling (compositor restart) may be required.
  4. In a patched build, replace expect with a logged error so keyboard failure degrades gracefully instead of killing the thread.
  5. Reproduce with WAYLAND_DEBUG=1 to identify which event/source fails and report upstream.

Example fix

// before
eventloop.dispatch(std::time::Duration::from_secs(60), &mut (signal, Keyboard::default()), |_ignored| {})
    .expect("keyboard event processing failed");

// after
if let Err(e) = eventloop.dispatch(std::time::Duration::from_secs(60), &mut (signal, Keyboard::default()), |_ignored| {}) {
    tracing::error!("keyboard event dispatch failed: {e}");
}
Defensive patterns

Strategy: try-catch

Try / catch

// wrap dispatch instead of expect:
match eventloop.dispatch(timeout, &mut state, |_ignored| {}) {
    Ok(()) => {}
    Err(e) => log::error!("keyboard dispatch failed: {e}"), // log and continue/reconnect
}

Prevention

When it happens

Trigger: calloop dispatch returning Err during keyboard event processing: the inserted rx source or the key-repeat timer fails, the wayland connection's rx channel errors, or the dispatcher state (LoopSignal, Keyboard) is corrupted; also raised if dispatch is called on an already-signaled/dead loop.

Common situations: Wayland compositor restarts or connection drops mid-session; key-repeat timer misbehaving after rapid key events; panics inside the dispatched callback propagating out as dispatch errors; long-running sessions hitting resource exhaustion.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

            // generate repeat keypresses.
            handle
                .insert_source(repeat, |event, timer, state| {
                    timer.add_timeout(state.1.repeat.rate, event.clone());
                    state.1.keystroke(&event);
                })
                .unwrap();

            tracing::debug!("keyboard event loop initiated");
            eventloop
                .run(
                    std::time::Duration::from_secs(60),
                    &mut (signal, Keyboard::default()),
                    |_ignored| {
                        tracing::trace!("keyboard event loop idle");
                    },
                )
                .expect("keyboard event processing failed");
            tracing::debug!("keyboard event loop completed");
        });

        state
    }
}

struct ModMap(u32, Modifiers);

impl ModMap {
    fn merge(self, m: Modifiers, mods: u32, locked: u32) -> Modifiers {
        if self.0 & mods == 0 && self.0 & locked == 0 {
            return m;
        }

        m | self.1
    }
}

View on GitHub (pinned to 0f8b1195e4)