防止窗口获得输入焦点

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

我开发了一个程序,允许我控制客户端和 X11 服务器之间的 X11 通信。我想用它来控制提供给客户端的鼠标和键盘输入。另外,我想运行客户端程序,同时能够与其他窗口交互。

不幸的是,每当我向程序发送“假”鼠标单击或“假”键盘按钮单击时,窗口都会获得输入焦点。这不是我想要的,因为它会从当时拥有的任何窗口中窃取输入焦点。

我已经尝试了多种方法,例如通过不将

SetInputFocus
请求转发到 X11 服务器并伪造
GetInputFocus
响应来阻止客户端请求输入焦点,等等,但我的尝试总是导致客户端窗口冻结。

请向我推荐一种解决此问题的方法。

x11
1个回答
0
投票

您看过 XTEST 扩展协议吗?

https://www.x.org/releases/X11R7.7/doc/xextproto/xtest.html

X11 的

XTEST
扩展是在 X11 上发送“假”输入的标准方法,并且可能比自己制作和发送原始事件更好地处理一些边缘情况。

一个简单的解决方案,尽管有点 hacky,是在使用

XTEST
发送输入后,立即使用
XSetInputFocus()
将焦点恢复到原始窗口。这可能会导致非常短暂的焦点切换,但如果做得足够快,可能几乎不会被注意到。

另一种值得尝试的方法是在发送任何输入之前尝试“锁定焦点”在窗口上,这样您可以使用窗口管理器功能和 X11 功能的组合强制焦点保留在当前活动的窗口上。模拟输入后,如果您愿意,您可以释放此焦点锁定。

从这个意义上说,这可能是解决这个问题的更好方法,使用“WM_HINTS”之类的东西来防止目标窗口获得焦点。

例如使用

WM_HINTS

#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main() {
    Display *display = XOpenDisplay(NULL);
    if (!display) {
        return 1; // fail if couldn't open the display
    }

    // Where 0xSOME_WINDOW_ID is ID of the target window you want to prevent gaining focus
    Window targetWindow = 0xSOME_WINDOW_ID;

    XWMHints *hints = XAllocWMHints();


    hints->input = False; // hint the window manager not to give focus to this window
    hints->flags = InputHint;

    XSetWMHints(display, targetWindow, hints);
    XFree(hints);

    XCloseDisplay(display);
    return 0;
}

但是

WM_HINTS
只是 - 提示...没有办法知道给定的 WM 是否会尊重输入提示而不尝试它。

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