【问题标题】:Sending Keystrokes to a X Window将击键发送到 X 窗口
【发布时间】:2013-05-23 13:13:58
【问题描述】:

我目前正在尝试使用 xdotool 向进程发送密钥(我知道它可能不适用于所有未设置 _NET_WM_PID 的进程)。我无法从焦点向其他窗口发送击键。如果您将击键发送到CURRENTWINDOW,它确实有效。下面是我用来测试 xdotool 功能的 sn-p。

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 无法将键发送到焦点窗口以外的任何其他窗口。

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

[我在 Ubuntu 13.04 上运行它。]


编辑

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

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

【问题讨论】:

  • 只是一个评论:我发现 sikuli 在尝试向 Windows 发送任意鼠标和键盘事件时非常有用。如果你没有绑定到 xdotool,你可能想试试 sikuli。
  • 感谢您的建议。我没有绑定到 xdotool。我已经通过 Xlib 和 Xtest 实现了一个解决方案。如果我需要发送任意鼠标事件,我会研究它。谢谢。
  • @swtdrgn 你能分享你的 Xlib 和 Xtest 替代解决方案吗?

标签: c++ ubuntu x11 xdotool


【解决方案1】:

直接来自xdotool手册:

发送事件说明

如果您尝试将按键输入发送到特定窗口,并且确实如此 似乎没有工作,那么很可能您的应用程序正在忽略 xdotool 正在生成的事件。这很常见。

向特定窗口发送击键使用不同的 API 只需键入活动窗口。如果您指定 'xdotool 类型 --window 12345 hello' xdotool 将生成关键事件并发送它们 直接到窗口 12345。但是,X11 服务器会设置一个特殊标志 以这种方式生成的所有事件(参见 XEvent.xany.send_event X11 的手册)。许多程序观察到这个标志并拒绝这些事件。

需要注意的是,对于键和鼠标事件,我们只使用 以特定窗口为目标时的 XSendEvent。否则,我们使用 XTEST。

有些程序可以配置为接受事件,即使它们是 由 xdotool 生成。寻求您的申请文件 帮助。

具体应用笔记(来自作者测试):* Firefox 3 似乎在没有焦点时忽略所有输入。 * xterm 可以 使用 ctrl+leftclick 运行时配置,'Allow SendEvents' * gnome-terminal 似乎默认接受生成的输入。

【讨论】:

  • 不能 xdotool 只提供一种设置标志的方法吗?与能够覆盖这种“忽略”行为的应用相比,无法覆盖这种“忽略”行为的应用要多得多,因此这似乎更有意义。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
相关资源
最近更新 更多