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

C语言Xorg编程中XNextEvent仅前三次返回 窗口静止时无响应

问题分析与解决

你的代码本身不存在逻辑错误,问题出在对X11事件模型的机制理解偏差:

  • XNextEvent是阻塞调用,只有当你注册监听的事件产生时才会返回,没有匹配事件时会一直挂起等待。
  • 你通过XSelectInput(dis, win, ExposureMask | KeyPressMask)仅注册了两类事件监听:
    • Expose事件:仅在窗口需要重绘时触发,包括首次显示、被遮挡后重新露出、调整窗口大小、切换全屏等场景,这就是你操作窗口时XNextEvent会恢复返回的原因。
    • KeyPress事件:仅在窗口获得焦点时,按下键盘按键才会触发。
  • 前三次调用XNextEvent正常返回,是窗口首次调用XMapRaised显示时,窗口管理器会连续推送2~3次初始Expose事件,这批初始事件处理完成后没有新的匹配事件产生,XNextEvent自然会进入阻塞状态。

验证方法

运行程序后点击窗口使其获得焦点,按下任意键盘按键,就能看到对应的printf输出,验证事件监听逻辑本身是正常的。

非阻塞轮询的修改方案

如果你需要窗口静止无事件时也能运行自定义逻辑,可以用XPending先判断是否有待处理事件,没有的话直接执行业务代码即可,参考修改如下:

#include <X11/keysym.h> // 新增头文件用于识别按键

// 其余原有代码保持不变

int main(){
    init();

    while (1){
        if (XPending(dis) > 0) { // 先判断有没有待处理的事件
            XNextEvent(dis, &event);
            if (event.type == Expose){
                printf("Will this execute? Prolly not.\n");
            } else if (event.type == KeyPress) {
                // 示例:按ESC键退出程序
                if (XLookupKeysym(&event.xkey, 0) == XK_Escape) {
                    close_program();
                }
            }
            printf("Will this execute? no.\n");
        }
        // 此处编写窗口静止时需要执行的逻辑
        usleep(16000); // 控制循环帧率约为60FPS,避免CPU空转占用过高
    } 
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 12:57:01