【问题标题】:Cannot ungrab keyboard after XGrabKeyboardXGrabKeyboard 后无法取消抓取键盘
【发布时间】:2019-04-12 11:54:43
【问题描述】:

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

【问题讨论】:

    标签: c++ x11 xlib


    【解决方案1】:

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

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

    同样有效:

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

    更新 - 也有效:

    XFlush(dpy);
    

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

    【讨论】:

    • 谢谢。当我在命令行应用程序中测试它时它可以正常工作,但是当我将它嵌入到 Qt 应用程序中时问题仍然存在。每当我打电话给QCoreApplication::exec 时,都会忽略 unrab。事实上,如果我再次尝试调用grab,我会得到AlreadyGrabbed。
    • @JoséTomásTocino 可能应该用自己的 MCVE 提出自己的问题,不确定您到底在做什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2014-06-19
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多