XGrabKeyboard后无法取消键盘

问题描述 投票:0回答:1

我正在开发一个应用程序,它应该冻结键盘和鼠标的所有输入一段时间。我尝试过使用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调用中的参数有关,我尝试修改它们(Sync vs Async等)。但没有区别。

c++ x11 xlib
1个回答
1
投票

XSync(dpy, true);之后添加XUngrabKeyboard(*)会使代码按照您期望的方式运行。因此,您可能必须处理在事件队列恢复之前抓取的所有事件?

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

还有效:

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

更新 - 也有效:

XFlush(dpy);

所以...问题是ungrab实际上并没有发送?

© www.soinside.com 2019 - 2024. All rights reserved.