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

如何在XRecord回调函数(XRecordInterceptProc)中取消按键事件?

在XRecordInterceptProc回调中取消按键事件的实现方法

要在XRecordInterceptProc回调里取消按键事件,核心逻辑是阻止目标事件传递到对应的应用窗口,以下是具体实现方案:

方法1:全局拦截并丢弃指定按键

初始化XRecord时创建支持拦截的上下文(需包含键盘事件范围),在回调中识别目标按键并直接丢弃:

#include <X11/Xlib.h>
#include <X11/extensions/Xrecord.h>

Display *dpy;

void myRecordCallback(XPointer closure, XRecordInterceptData *data) {
    if (data->category != XRecordFromServer) {
        XRecordFreeData(data);
        return;
    }

    XEvent *event = (XEvent *)data->data;
    // 拦截键码为38(对应键盘A键)的按下事件
    if (event->type == KeyPress && event->xkey.keycode == 38) {
        // 直接丢弃,不做转发
        XRecordFreeData(data);
        return;
    }

    // 非目标事件,转发回X服务器
    XSendEvent(dpy, DefaultRootWindow(dpy), False, 0, event);
    XFlush(dpy);
    XRecordFreeData(data);
}

// 初始化XRecord上下文的示例代码
void initXRecord() {
    dpy = XOpenDisplay(NULL);
    XRecordClientSpec clients = XRecordAllClients;
    XRecordRange *range = XRecordAllocRange();
    memset(range, 0, sizeof(XRecordRange));
    // 捕获键盘按下/释放事件
    range->device_events.first = KeyPress;
    range->device_events.last = KeyRelease;

    XRecordContext ctx = XRecordCreateContext(dpy, 0, &clients, 1, &range, 1);
    XFree(range);

    XRecordEnableContext(dpy, ctx, myRecordCallback, NULL);
    XRecordFreeContext(dpy, ctx);
    XCloseDisplay(dpy);
}

方法2:针对特定窗口拦截按键

如果只需要取消某个特定窗口的按键事件,可以在回调中检查事件的目标窗口:

Window targetWin; // 预先获取需要拦截的窗口ID

void myRecordCallback(XPointer closure, XRecordInterceptData *data) {
    if (data->category != XRecordFromServer) {
        XRecordFreeData(data);
        return;
    }

    XEvent *event = (XEvent *)data->data;
    if ((event->type == KeyPress || event->type == KeyRelease) &&
        event->xkey.window == targetWin && event->xkey.keycode == 38) {
        // 丢弃目标窗口的指定按键事件
        XRecordFreeData(data);
        return;
    }

    // 正常转发其他事件
    XSendEvent(dpy, event->xkey.window, False, 0, event);
    XFlush(dpy);
    XRecordFreeData(data);
}

关键注意事项

  • 确保XRecord上下文为拦截模式:创建XRecordContext时,使用XRecordAllClients或指定目标客户端,同时正确设置事件范围。
  • 必须调用XRecordFreeData释放回调接收的事件数据,避免内存泄漏。
  • XSendEvent的参数要匹配事件的原始目标,否则可能导致事件传递异常。

内容的提问来源于stack exchange,提问作者Slendi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:05:15