使用XSendEvent发送XKeyEvent时,系统第一次没有响应,然后在XCloseDisplay上响应

时间:2018-02-24 11:37:50

标签: c++ c++11 x11 xlib

我有代码:

// Send a fake key press event to the window.
XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, XKeysymToKeycode(display, key), modifier);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);


// Send a fake key release event to the window.
event = createKeyEvent(display, winFocus, winRoot, false, XKeysymToKeycode(display, key), modifier);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

根据我的理解,将键盘事件发送到系统,首先按下然后发布。这是有效的,但是第一个事件不会发生,但是当程序结束时它会发送另一个事件。我的理论是它推迟了一个事件? 是否有一些缓冲区被保存在需要冲洗的一次发送中?

因此,例如我模拟按下一个键5次,它键入4次然后当调用XCloseDisplay时键入5。当在每次按下之间施加延迟时,它是第一个没有出现的延迟。

提前感谢您的帮助。如果需要,我可以提供有关周围代码的更多详细信息。

**编辑:**添加了最小,完整且可验证的示例:

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <unistd.h>

// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYCODE1 XK_a

// Function to create a keyboard event
XKeyEvent createKeyEvent(Display *display, Window &win,
                           Window &winRoot, bool press,
                           int keycode, int modifiers)
{
   XKeyEvent event;

   event.display     = display;
   event.window      = win;
   event.root        = winRoot;
   event.subwindow   = None;
   event.time        = CurrentTime;
   event.x           = 1;
   event.y           = 1;
   event.x_root      = 1;
   event.y_root      = 1;
   event.same_screen = True;
   event.keycode     = XKeysymToKeycode(display, keycode);
   event.state       = modifiers;

   if(press)
      event.type = KeyPress;
   else
      event.type = KeyRelease;

   return event;
}

main()
{
   // Obtain the X11 display.
   Display *display = XOpenDisplay(0);
   if(display == NULL)
      return -1;

   // Get the root window for the current display.
   Window winRoot = XDefaultRootWindow(display);

   usleep(2000000);

   for (int i = 0; i < 5; ++i)
   {

      // Find the window which has the current keyboard focus.
      Window winFocus;
      int    revert;
      XGetInputFocus(display, &winFocus, &revert);

      // Send a fake key press event to the window.
      XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, KEYCODE1, 0);
      XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

      printf("keydown\n");

      usleep(1000000);

      // Send a fake key release event to the window.
      event = createKeyEvent(display, winFocus, winRoot, false, KEYCODE1, 0);
      XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

      printf("keyup\n");
   }

   usleep(2000000);

   // Done.aaaaa
   XCloseDisplay(display);
   return 0;
}

0 个答案:

没有答案