XGrabKeyboard后无法取消键盘键盘

时间:2019-04-12 11:54:43

标签: c++ x11 xlib

我正在开发一个应在一段时间内冻结所有输入(包括键盘和鼠标)的应用程序。我尝试使用XGrabKeyboard,但无法使用XUngrabKeyboard恢复其效果,它什么也没做。

这是一个您可以轻松编译的最小示例:

#include <iostream>
#include <thread>
#include <chrono>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/cursorfont.h>


int main(int argc, char *argv[])
{
    Display * dpy = nullptr;

    dpy = XOpenDisplay(0);

    if(!dpy)
    {
        std::cerr << "Error" << std::endl;
        return 1;
    }

    std::cerr << "Grabbing..." << std::endl;

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);

    std::cerr << "Waiting 2 secs, you shouldn't be able to type anything" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));


    std::cerr << "Ungrabbing..." << std::endl;
    XUngrabKeyboard(dpy, CurrentTime);

    std::cerr << "Try to type now" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}

您可以看到您无法再写任何东西。我尝试单击终端,以防丢失焦点或其他任何东西,但无济于事。程序完成后,将释放键盘。

不确定XGrabKeyboard调用中的参数是否与我有关系,我尝试过修改它们(同步与异步等)。但是没有区别。

1 个答案:

答案 0 :(得分:1)

XSync(dpy, true);之后添加XUngrabKeyboard(*)可使代码以您期望的方式运行。因此,可能需要在事件队列恢复之前处理所有捕获的事件吗?

(*):实际上并没有这样做,这只是为了证明问题出在排队事件上

也可以工作:

XUngrabKeyboard(dpy, CurrentTime);
XEvent foo;
while (XPending(dpy)) XNextEvent(dpy, &foo);

更新-也可以:

XFlush(dpy);

所以...问题是未真正发送未成年人?