linebender/druid · warning

unexpected mouse wheel button

Error message

unexpected mouse wheel button: {}

What it means

When translating X11 button-press events for scroll wheels into `WheelEvent` deltas, druid-shell maps only X11 button codes 4–7 (vertical, horizontal, and shifted variants). Any other button arriving in a wheel-handling context hits the wildcard arm and returns this error, meaning an unexpected hardware/pointer button (e.g. tilt-wheel, extra mouse buttons) was routed to the scroll handler.

Solutions

  1. Check the device's button mapping with `xinput get-button-map` and remap extra buttons away from the wheel-handling range.
  2. Update druid/druid-shell — newer versions may map more buttons or ignore unknown ones gracefully.
  3. If this is your build, change the `_ =>` arm to ignore unknown buttons instead of erroring (or map them to wheel deltas as needed).
  4. Reproduce with `xev` to see the actual button detail code your device sends and handle it explicitly.

Example fix

// before
_ => return Err(anyhow!("unexpected mouse wheel button: {}", button)),
// after
_ => {
    log::debug!("ignoring unexpected mouse wheel button: {}", button);
    return Ok(());
}
Defensive patterns

Strategy: validation

Validate before calling

// check button codes your device emits before relying on wheel handling
// $ xev -event button  # observe 'button <n>' in ButtonPress events
// only buttons 4-7 are treated as wheel events by druid-shell x11 backend

Type guard

fn is_wheel_button(detail: u8) -> bool {
    matches!(detail, 4..=7)
}

Prevention

When it happens

Trigger: An X11 ButtonPress event with `detail` outside 4..=7 (e.g. buttons 8/9 from side buttons, unusual drivers, or remapped input devices) is dispatched through the wheel-event translation code in the X11 window backend.

Common situations: Gaming mice or keyboards with extra buttons, exotic input drivers or emulator/virtualization environments emitting non-standard button codes, custom XInput mappings (xinput set-button-map) that shift button numbers.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at druid-shell/src/backend/x11/window.rs:1155

        self.with_handler(|h| h.mouse_up(&mouse_event));
        Ok(())
    }

    pub fn handle_wheel(&self, event: &xproto::ButtonPressEvent) -> Result<(), Error> {
        let button = event.detail;
        let mods = key_mods(event.state);
        let scale = self.scale.get();

        // We use a delta of 120 per tick to match the behavior of Windows.
        let is_shift = mods.shift();
        let delta = match button {
            4 if is_shift => (-120.0, 0.0),
            4 => (0.0, -120.0),
            5 if is_shift => (120.0, 0.0),
            5 => (0.0, 120.0),
            6 => (-120.0, 0.0),
            7 => (120.0, 0.0),
            _ => return Err(anyhow!("unexpected mouse wheel button: {}", button)),
        };
        let mouse_event = MouseEvent {
            pos: Point::new(event.event_x as f64, event.event_y as f64).to_dp(scale),
            buttons: mouse_buttons(event.state),
            mods: key_mods(event.state),
            count: 0,
            focus: false,
            button: MouseButton::None,
            wheel_delta: delta.into(),
        };

        self.with_handler(|h| h.wheel(&mouse_event));
        Ok(())
    }

    pub fn handle_motion_notify(
        &self,
        motion_notify: &xproto::MotionNotifyEvent,

View on GitHub (pinned to 0f8b1195e4)