通过文件描述符或套接字轮询 X 事件

Poll X events via file descriptor or socket

因为 X 是服务器,我有办法通过套接字而不是使用 XNextEvent?

来监听 X 事件

我有一个程序通过 epoll 监视系统事件,在主线程的循环 运行 中调用 epoll_wait。由于我无法弄清楚如何通过文件描述符侦听 X 事件,我不得不求助于 运行 一个单独线程中的 XNextEvent 专用循环,并在调用周围放置互斥锁事件发生时调用的函数。

这是我为轮询 X 事件编写的函数,如果有人好奇的话。我目前只监听与键盘布局切换相关的事件。

void* xevent_loop(void*) {
  int xkbEventType;
  XkbQueryExtension(dpy, 0, &xkbEventType, 0, 0, 0);
  XkbSelectEventDetails(dpy,
    XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask,
    XkbGroupStateMask);
  XSync(dpy, False);

  for (XEvent e;;) {
    XNextEvent(dpy, &e);
    if (e.type == xkbEventType) {
      XkbEvent* xkbe = (XkbEvent*) &e;
      if (xkbe->any.xkb_type == XkbStateNotify) {
        pthread_mutex_lock(&setroot_mutex);
        fmt_kbd_layout(xkbe->state.group);
        setroot();
        pthread_mutex_unlock(&setroot_mutex);
      }
    }
  }
  return NULL;
}

您可以通过在显示器上使用宏 ConnectionNumber(dpy) 来获取连接的文件描述符。见 man ConnectionNumber:

The ConnectionNumber macro returns a connection number for the specified display.

这可用于 select()poll() 以检查事件是否准备就绪。 定义在/usr/include/X11/Xlib.h.