将击键发送到 X 窗口 [英] Sending Keystrokes to a X Window

查看:67
本文介绍了将击键发送到 X 窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently experimenting with xdotool to send keys to a process (I understand that it may not work for all processes that does not set _NET_WM_PID). I have trouble sending keystrokes to windows other from the focus. It does work if you are sending keystrokes to the CURRENTWINDOW. Below is the snippet that I used to test xdotool's functionality.

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

In additional to testing xdotool's functionality, I've looked into xdotool's source code. Interestingly, I found that they are using Xtest to send keystrokes to the focused window (CURRENTWINDOW) and X11's XSendEvent for other windows. I turned to xdotool because I couldn't get XSendEvent to work and Xtest cannot send keys to any other windows than the focused window.

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

Am I not using the xdotool correctly? Does xdotool not work with all *nix OS with X11?

[我在 Ubuntu 13.04 上运行这个.]

[I am running this on Ubuntu 13.04.]

编辑

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

So, it looks like that does work but not for all windows that it finds. For example, it works for firefox but not gedit and gnome-terminal although it found gedit and gnome-terminal by its pid. It behaves differently if I used CURRENTWINDOW.

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

So, it would be great if someone can explain why is this so. Like, is it related the force send flag in an XEvent?

推荐答案

直接来自 xdotool 手册:

Directly from the xdotool manual:

发送活动笔记

如果您尝试将键输入发送到特定窗口,并且确实如此似乎不起作用,那么您的应用程序很可能忽略了xdotool 正在生成的事件.这是相当普遍的.

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.

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

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.

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

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.

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

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

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

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.

这篇关于将击键发送到 X 窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆