Linux X11读取鼠标按键事件返回重复字段值异常排查
X11鼠标扩展事件读取值重复错位问题修复
问题根因
你注册的是XInput 1.x扩展的设备按键事件(从输出的事件类型69、70也能看出来,这不是核心X11协议固定编号为4/5的原生鼠标按键事件),但读取事件字段时错误使用了核心协议对应的event.xbutton联合体成员。XEvent是C语言实现的标记联合体结构,不同事件类型对应联合体里不同的成员段,内存布局完全独立:
- 核心鼠标按键事件(
ButtonPress/ButtonRelease)才会把数据写入xbutton成员段,对应结构体是XButtonEvent - 你通过
DeviceButtonPress/DeviceButtonRelease宏注册的扩展设备事件,数据写入的是xdevicebutton成员段,对应结构体是XDeviceButtonEvent
你强行用xbutton的内存偏移去读xdevicebutton段的数据,必然出现字段错位,你看到的x和state值相同、y和button值相同,只是错位后内存值刚好重复的巧合,不是事件本身的问题。
修复代码
只需要修改事件读取部分的字段访问逻辑,把event.xbutton全部替换为event.xdevicebutton即可:
if( XCheckTypedEvent(display, event_type, &event) ) { outputFile << "Type: " << event.type << ' '; switch(i) { case BTN_PRESS_EVENT: outputFile << "ButtonPress"; outputFile << "\tx=" << event.xdevicebutton.x_root << " y=" << event.xdevicebutton.y_root; outputFile << " state=" << event.xdevicebutton.state << " button=" << event.xdevicebutton.button; break; case BTN_RELEASE_EVENT: outputFile << "ButtonRelease"; outputFile << "\tx=" << event.xdevicebutton.x_root << " y=" << event.xdevicebutton.y_root; outputFile << " state=" << event.xdevicebutton.state << " button=" << event.xdevicebutton.button; break; } outputFile << std::endl; }
补充说明
你当前使用的XInput 1.x接口已经被废弃,新开发的X11输入相关程序建议迁移到XInput 2(XI2)接口,功能更完善,事件处理逻辑也更清晰。
内容的提问来源于stack exchange,提问作者Felix.leg
相关产品推荐
相关产品推荐

