【问题标题】:XSetInputFocus failsXSetInputFocus 失败
【发布时间】:2011-10-01 01:48:18
【问题描述】:

在我的 Xlib 应用程序中,我需要将键盘设置为专注于特定组件,我想用XSetInputFocus 来做。出于某种原因,即使我的窗口是可见的,我总是会收到 BadMatch 错误(并且手册页说导致此错误的原因是一个不可见/映射的窗口)。当我说它可见时,我的意思是我可以在屏幕上看到它,并且我知道请求列表已经被刷新。

因此,我没有分享我庞大的代码,而是在互联网上找到了一个较小的演示并尝试对其进行修改。我采用了 Xlib 中的事件处理代码,如我发现的 example 中的 Xlib programming tutorial 所示。我尝试添加以下行:

XSetInputFocus (display, win, RevertToNone, CurrentTime);

就在行前

/* perform an events loop */

我得到的错误是:

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  42 (X_SetInputFocus)
  Serial number of failed request:  12
  Current serial number in output stream:  12

这与我在自己的应用程序中遇到的错误完全相同,事件序列完全相同:

  1. 使用XCreateSimpleWindow 创建一个窗口(应该是InputOutput 窗口)
  2. 使用XSelectInput 并在掩码中选择也可以得到KeyPressMask)
  3. 映射窗口 (XMapWindow)
  4. 使用XSetInputFocusRevertToNoneRevertToParent 请求焦点(均失败)

我怀疑这与我需要使用XNextEvent 处理窗口创建事件这一事实有关,直到我完成对窗口的重新父级处理,但在那种情况下,我不知道什么时候我应该等待(在尝试此之前我应该​​收到哪些事件?)。在我的程序中第一次调用 XNextEvent 之前,我目前正在这样做。

任何帮助都会受到高度评价。提前致谢!

【问题讨论】:

    标签: keyboard focus xlib


    【解决方案1】:

    我昨天遇到了类似的问题...这是因为 X 服务器异步处理事件;因此您需要等待窗口被映射后才能尝试使用 XSetInputFocus()...

    您应该调用 XIfEvent() 来确定这一点。

    一个例子(用freepascal编写):

    // The filter-function, here you should return true if
    //  the event parameter matches the one you want
    //  in this case, I match the type to be MapNotify and the window to be the correct one
    Function WaitForNotify(aDPY: PDisplay; anEvent: PXEvent; arg: TXPointer): LongBool; cdecl;
    Begin
        Result:= (anEvent^._type = MapNotify) and (anEvent^.xmap.window = TWindow(arg));
    End;
    
    // XIfEvent cycles through the event cue, and evaluates each event through
    //  the function you provide it
    XIfEvent(dpy, @event, @WaitForNotify, TXPointer(xWindow));
    
    // Then, once this call returns, you're shure you've got focus and you can safely call
    //  XSetInpuFocus()
    XSetInputFocus(dpy, XWindow, RevertToNone, CurrentTime);
    

    希望这会有所帮助!

    【讨论】:

    • 正如我在问题中所说的“我的窗口是可见的”,所以我认为这表明地图事件已被处理。但是,我确实遵循了您的建议并尝试了 XIfEvent。恐怕它对我的完整代码没有帮助,但这也可能是其中的一个错误。当我可以得到它时,我会用我给出的例子来尝试它。谢谢你的建议,我试试看!
    【解决方案2】:

    对我来说,一个简化的解决方案也有效: 在调用XMapWindow() 之后,我刚刚调用了XSync(),然后执行了XSetInputFocus()

    【讨论】:

      【解决方案3】:

      我用这里找到的代码一劳永逸地处理了这个问题: https://www.ultraengine.com/community/blogs/entry/2690-linux-development-progress/

      从那以后再也没有遇到过问题。这有点吓人,但由于应用程序有 在任何时候映射/取消映射窗口的总控制(我认为并希望)应该没问题。

      XInputSetFocus 是我遇到的唯一使用这种“rest-of-API-is-asynchronous-but-I-want-what-I-want-right-now”设计的命令。

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 2016-01-22
      • 1970-01-01
      • 2013-02-24
      • 2011-01-17
      • 1970-01-01
      相关资源
      最近更新 更多