c++ - 将击键发送到 X 窗口

标签 c++ ubuntu x11 xdotool

我目前正在尝试使用 xdotool 将 key 发送到进程(我知道它可能不适用于所有未设置 _NET_WM_PID 的进程)。我无法将击键发送到焦点以外的窗口。如果您将击键发送到 CURRENTWINDOW,它就可以工作。下面是我用来测试 xdotool 功能的代码片段。

extern "C"{
  #include <xdo.h>
}
//extern "C" xdo_window_search
#include <iostream>
#include <string.h>

using namespace std;

int main(){
    xdo_t* p_xdo = xdo_new(NULL);

    // Allocate memory for search query.
    xdo_search_t s;
    // Clear the allocated memory.
    memset(&s, 0, sizeof(xdo_search_t));
    // Set the search query.
    s.pid = 1916;
    s.max_depth = -1;
    s.searchmask = SEARCH_PID;
    s.require = xdo_search::SEARCH_ANY;
    // Allocate memory for output
    Window* windows;
    int no_windows;
    xdo_window_search(p_xdo,&s,&windows,&no_windows);
    cout << no_windows << endl;
    // Prints all windows' names with matching criteria
    for( int i=0;i<no_windows;i++ ){
        unsigned char * name;
        int size;
        int type;
        xdo_get_window_name(p_xdo,windows[i],&name,&size,&type);
        cout << i << ":" << name << endl;
    }
    for( int i=0;i<no_windows;i++ ){
        xdo_type(p_xdo,windows[i],"Hello World",0);
    }
    //xdo_type(p_xdo,CURRENTWINDOW,"Hello World",0); // This does work.
    return 0;
}

除了测试 xdotool 的功能外,我还查看了 xdotool 的源代码。有趣的是,我发现他们正在使用 Xtest 将击键发送到聚焦窗口 (CURRENTWINDOW),并使用 X11 的 XSendEvent 发送其他窗口。我求助于 xdotool,因为我无法让 XSendEvent 工作,而且 Xtest 无法将 key 发送到焦点窗口以外的任何其他窗口。

我没有正确使用 xdotool 吗? xdotool 是否不适用于所有带有 X11 的 *nix 操作系统?

[我在 Ubuntu 13.04 上运行它。]


编辑

因此,它看起来确实有效,但不适用于它找到的所有窗口。例如,它适用于 firefox 但不适用于 gedit 和 gnome-terminal,尽管它通过其 pid 找到了 gedit 和 gnome-terminal。如果我使用 CURRENTWINDOW,它的行为会有所不同。

所以,如果有人能解释为什么会这样就太好了。比如,它与 XEvent 中的强制发送标志相关吗?

最佳答案

直接来自 xdotool 手册:

SENDEVENT NOTES

If you are trying to send key input to a specific window, and it does not appear to be working, then it's likely your application is ignoring the events xdotool is generating. This is fairly common.

Sending keystrokes to a specific window uses a different API than simply typing to the active window. If you specify 'xdotool type --window 12345 hello' xdotool will generate key events and send them directly to window 12345. However, X11 servers will set a special flag on all events generated in this way (see XEvent.xany.send_event in X11's manual). Many programs observe this flag and reject these events.

It is important to note that for key and mouse events, we only use XSendEvent when a specific window is targeted. Otherwise, we use XTEST.

Some programs can be configured to accept events even if they are generated by xdotool. Seek the documentation of your application for help.

Specific application notes (from the author's testing): * Firefox 3 seems to ignore all input when it does not have focus. * xterm can be configured while running with ctrl+leftclick, 'Allow SendEvents' * gnome-terminal appears to accept generated input by default.

关于c++ - 将击键发送到 X 窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16714928/

相关文章:

c++ - 用于嵌入 python 的应用程序的 PTVS 插件

linux - 自动重新运行,Linux

selenium - EC2 上的 XVFB 和 Selenium - 无法在 VNC 查看器上查看 Chrome UI

drawing - 使用 Xlib 启用抗锯齿

C++ (LINUX) 使用 DevIL 设置 X11 窗口背景

c++ - 使用输出迭代器的通用函数示例不起作用

c++ - 如何在数据以二进制零结尾时初始化 std::string

c++ - 从数组构造

ruby-on-rails - 一个最初建立在 Ubuntu 上的 Rails 项目可以在 Mac 环境上运行吗?

检查点和重新启动 X11 应用程序