XSetInputFocus 失败

发布于 2024-12-07 22:35:24 字数 1502 浏览 0 评论 0 原文

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

因此,我没有分享我的庞大代码,而是在互联网上找到了一个较小的演示并尝试修改它。我采用了 Xlib 中的事件处理代码,如 中所示 rel="nofollow">Xlib编程教程我找到了。我尝试添加以下行:

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. 请求焦点使用XSetInputFocus 使用 RevertToNoneRevertToParent (均失败)

我怀疑它必须做一些事情,因为我需要处理使用 XNextEvent 创建窗口,直到我完成处理窗口的重新父子关系,但在这种情况下,我不知道我应该等到什么时候(尝试此操作之前我应该​​接收哪些事件?)。我目前正在程序中第一次调用 XNextEvent 之前执行此操作。

任何帮助将不胜感激。提前致谢!

In my Xlib application, I need to set up the keyboard to focus on a specific component, and I though of doing it with XSetInputFocus. For some reason I always get a BadMatch error even though my window is visible (and the man pages say that the cause for this error is a window which is not visible/mapped). When I say it's visible, I mean that I can see it on the screen, and I know the list of requests was flushed already.

So, instead of sharing my huge code, I found a smaller demo on the internet and tried to modify it. I took the event handling code in Xlib as presented in the example of an Xlib programming tutorial I found. I tried adding the following line:

XSetInputFocus (display, win, RevertToNone, CurrentTime);

Just before the line

/* perform an events loop */

The error I got was:

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

This is exactly the same error I got in my own application with exactly the same sequence of events:

  1. Create a window with XCreateSimpleWindow (that shuold be an InputOutput window)
  2. Use XSelectInput and choose in the mask to also get KeyPressMask)
  3. Map the window (XMapWindow)
  4. Request focus using XSetInputFocus using either RevertToNone or RevertToParent (both fail)

I suspect it has to do something with the fact that I need to process the events of the window creation using XNextEvent, untill I finish handling the reparenting of the window, but in that case I don't know untill when should I wait (which events should I receive before atempting this?). I am currently doing this before the first call to XNextEvent in my program.

Any help would be highly appriciated. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

走走停停 2024-12-14 22:35:24

昨天我也遇到了类似的问题...这是因为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);

希望这有帮助!

I had a similar issue just yesterday... It's because the X server processes events asynchroniously; thus you need to wait for the window to be mapped before trying to use XSetInputFocus()...

You should call XIfEvent() to determine this.

An example (written in 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);

Hope this helps!

与风相奔跑 2024-12-14 22:35:24

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

For me a simplified solution also worked:
After a call to XMapWindow() I just called XSync() before performing a XSetInputFocus().

早茶月光 2024-12-14 22:35:24

我用这里找到的代码一劳永逸地处理了这个问题:
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”设计的命令。

I dealt with this problem once and for all with the code found here:
https://www.ultraengine.com/community/blogs/entry/2690-linux-development-progress/

Have never had a problem since. It's a little scary but since the application has
total control (I think and hope) over any time a window is mapped / unmapped it should be fine.

XInputSetFocus is the only command I have encountered that uses this "rest-of-API-is-asynchronous-but-I-want-what-I-want-right-now" design.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文