使用XCheckMaskEvent+ButtonMotionMask返回无效(0,0)鼠标位置问题咨询
问题分析与解决方法
核心问题
- 未检查
XCheckMaskEvent返回值:该函数无匹配事件时返回0,且不会修改传入的xevent结构体,原代码直接打印初始值(0,0),导致循环持续输出无效内容。 - 未指定事件监听窗口:X11需要明确指定接收事件的窗口(比如系统根窗口),并为其选择对应事件掩码,否则无法捕获真实鼠标事件。
- 事件掩码使用错误:若要捕获普通鼠标移动(无需按住按钮),应使用
PointerMotionMask;仅需捕获按住按钮时的移动,才用ButtonMotionMask。
修正后的代码
#include <stdio.h> #include <X11/Xlib.h> #include <stdlib.h> #include <unistd.h> Display *display; XEvent xevent; Window root_window; int main(int argc, char **argv){ // 打开显示连接 if( (display = XOpenDisplay(NULL)) == NULL ){ fprintf(stderr, "无法打开X显示连接\n"); return -1; } // 获取系统根窗口 root_window = DefaultRootWindow(display); // 为根窗口注册鼠标移动事件监听 XSelectInput(display, root_window, PointerMotionMask); while (1) { // 仅捕获到有效事件时才处理 if(XCheckMaskEvent(display, PointerMotionMask, &xevent)){ if(xevent.type == MotionNotify){ printf("x_root: %d y_root: %d\n", xevent.xmotion.x_root, xevent.xmotion.y_root); } } // 降低循环CPU占用 usleep(1000); } XCloseDisplay(display); return 0; }
关键修改点
- 新增
XSelectInput调用,为根窗口注册PointerMotionMask事件,让X11将鼠标移动事件发送到程序。 - 检查
XCheckMaskEvent返回值,仅在捕获到有效事件时打印坐标。 - 增加
MotionNotify事件类型判断,确保处理的是目标事件。 - 添加
usleep(1000)减少循环对CPU的占用。
编译命令
gcc -Wall -lX11 mouse_motion.c -o mouse_motion
内容的提问来源于stack exchange,提问作者Cheetaiean
相关产品推荐
相关产品推荐

