You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过XCB发送GetDeviceInfo XKB请求返回BadAccess错误如何解决

问题根源

你遇到的BadAccess错误核心原因是使用XKB相关请求前没有先显式初始化并启用X服务端的XKB扩展,X服务端默认会拒绝未提前声明使用XKB扩展的客户端发送的相关请求。


解决步骤

第一步:确认依赖配置

你的Rust项目中xcb crate必须启用xkb feature,xkbcommon-sys crate版本要和系统安装的libxkbcommon库版本匹配。

第二步:连接XCB后先初始化XKB扩展

在获取原始连接指针、调用xkbcommon相关函数前,先执行XKB扩展初始化逻辑:

use xcb::xkb;

let (conn, screen_num) = Connection::connect(None)?;

// 1. 确认X服务端存在XKB扩展
let xkb_ext = conn.get_extension_data(&xkb::XKB_EXTENSION)
    .ok_or(Error::XkbExtensionNotFound)?;

// 2. 请求启用指定版本的XKB扩展,最低要求1.0版本即可
let use_ext_cookie = xkb::use_extension(
    &conn,
    xkb::USE_EXTENSION_MAJOR_VERSION as u16,
    xkb::USE_EXTENSION_MINOR_VERSION as u16
);
let use_ext_reply = use_ext_cookie.wait()?;
if !use_ext_reply.supported() {
    return Err(Error::XkbExtensionUnsupported);
}

// 3. 注册需要使用的XKB事件与映射掩码,获取核心键盘访问权限
let event_mask = xkb::EventType::NEW_KEYBOARD_NOTIFY
    | xkb::EventType::MAP_NOTIFY
    | xkb::EventType::STATE_NOTIFY;
let map_mask = xkb::MapPart::KEY_TYPES
    | xkb::MapPart::KEY_SYMS
    | xkb::MapPart::MODIFIER_MAP
    | xkb::MapPart::VIRTUAL_MODS;

xkb::select_events(
    &conn,
    xkb::ID_USE_CORE_KBD,
    event_mask as u16,
    event_mask as u16,
    map_mask as u16,
    map_mask as u16,
    None
).check()?;

// 之后再执行你原有的xkbcommon初始化逻辑即可
let raw_conn = conn.get_raw_conn() as *mut xkbcommon_sys::xcb_connection_t;
let context = unsafe { xkb_context_new(XKB_CONTEXT_NO_FLAGS) };
// ... 原有后续代码

其他注意事项

  • 不要在Wayland环境下通过XWayland测试该逻辑,部分XWayland实现会限制XKB扩展的访问权限,建议使用原生X11会话测试
  • 如果需要捕获全局键盘输入,你还需要额外通过xcb_grab_keyboard请求获取键盘抓取权限,否则只能捕获当前进程窗口内的按键事件
  • 拿到有效device_id后,调用xkb_x11_keymap_new_from_device创建keymap,再创建xkb_state实例,就可以通过xkb_state_key_get_utf8接口将按键事件的keycode转换为对应的Unicode字符。

内容的提问来源于stack exchange,提问作者Ian S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:06:00