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

使用XCheckMaskEvent+ButtonMotionMask返回无效(0,0)鼠标位置问题咨询

问题分析与解决方法

核心问题

  1. 未检查XCheckMaskEvent返回值:该函数无匹配事件时返回0,且不会修改传入的xevent结构体,原代码直接打印初始值(0,0),导致循环持续输出无效内容。
  2. 未指定事件监听窗口:X11需要明确指定接收事件的窗口(比如系统根窗口),并为其选择对应事件掩码,否则无法捕获真实鼠标事件。
  3. 事件掩码使用错误:若要捕获普通鼠标移动(无需按住按钮),应使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:27:30