繁体   English   中英

Linux x11 XGrabKeyboard()导致键盘被冻结

[英]Linux x11 XGrabKeyboard() cause keyboard to be frozen

我正在编写一个需要监听用户键盘的程序。

我使用函数XGrabKeyboard(),这是我的代码:

XGrabKeyboard(pDisplay, DefaultRootWindow(pDisplay), True, GrabModeAsync, GrabModeAsync, CurrentTime);
XEvent event;
while (true)
{
  XNextEvent(pDisplay, &event);
  switch (event.type)
  {
  ...
  }
}

但它会导致键盘和光标被冻结。

我查看了手册页,它只说:“第三个参数指定一个布尔值,指示是否像往常一样报告键盘事件。”

我尝试了true或false或第3个参数,GrabModeAsync和GrabModeSync用于第4和第5个参数,但它不起作用。

调用XGrabKeyboard()后,键盘被冻结,鼠标单击不响应。

有任何想法吗?

XGrabKeyboard()(如果成功 - 请务必检查返回值),将所有关键事件重定向到您的客户端。

因此,如果while(true)内的“...”没有正确处理这些键事件,或者没有ungrab(XUngrabKeyboard)或释放同步事件(XAllowEvents,仅适用于GrabModeSync),那么键盘似乎会锁定起来。

boolean参数是owner_events,它指示是否始终向提供给XGrabKeyboard的窗口报告键事件,或者将它们报告给它们通常在没有抓取的情况下进入的窗口。 通常,您需要False(报告到抓取窗口)。

对于XGrabKeyboard的典型用法(我不知道你的用例),你想要的参数是:

  • 抓取窗口=您的应用中与抓取原因相关的一些窗口
  • owner_events = False将所有事件发送到该窗口
  • pointer_mode =不同于指针的Async
  • keyboard_mode = Async只是重定向所有键事件,避免需要AllowEvents
  • time =事件触发抓取的时间戳,理想情况下,或者通过更改属性并从PropertyNotify获取时间戳生成的时间戳

但是,这取决于。 为了给出任何确定的答案,您可能需要发布一个可编译的程序,我认为该错误很可能出现在代码的“...”部分。 尝试将您的应用缩小到可能由其他人运行的单个文件测试用例。 或者解释一下为什么你要抓住你想要在大局中完成什么。

我无法帮助XGrabKeyboard功能 - 我之前没有使用它,也不知道它是如何工作的 - 但我可以建议另一种获取键盘事件的方法。

使用XCreateWindow创建窗口时,最后一个参数是XSetWindowAttributes对象。 此对象具有成员event_mask,您可以使用该成员选择窗口将接收的事件。

我这样设置我的:

XSetWindowAttributes setWindAttrs
setWindAttrs.event_mask = ExposureMask           
                        | KeyPressMask  
                        | KeyReleaseMask    
                        | ButtonPressMask 
                        | ButtonReleaseMask;

这意味着如果在创建窗口时将此对象传递给XCreateWindow,则会收到键盘按键和鼠标按键单击的事件。

另外另一个注意事项是你可以使用XPending(pDisplay)检查是否还有等待处理的事件 - 所以它可以在你的while(true)行中替换为true

编辑:你的冻结问题也可能是你在while循环中的任何地方都没有返回false? 它可能会被卡在无限循环中,除非你刚刚为帖子删除了那个位。 尝试用上面提到的xpending替换true,它可以解决问题,或者只是在处理事件后返回false,但这只会处理每帧一个事件,而不是像XPending那样处理所有当前挂起的事件,我假设这就是你想要做的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM