【问题标题】:Linux: Xautomation with fake mouse pointerLinux:带有假鼠标指针的 Xautomation
【发布时间】:2020-01-06 15:00:13
【问题描述】:

我使用here 概述的xinput 命令创建了一个假鼠标指针,它会产生一个悬停在我屏幕中心的第二个指针。

我现在想使用xte 命令将其自动化,但不幸的是xte 似乎只能控制我希望保持空闲的硬件鼠标。

xte 的手册页没有任何标志来指定要控制哪个指针。 我想知道是否有人有任何想法?

注意:第二个指针纯粹是为了让我能够在运行图形管道的同时在同一台计算机上工作


编辑:所以通过查看 xte 源,我发现了对 XQueryPointer 的引用

Bool XQueryPointer(display, w, root_return, child_return, root_x_return, root_y_return, 
                     win_x_return, win_y_return, mask_return)
      Display *display;
      Window w;
      Window *root_return, *child_return;
      int *root_x_return, *root_y_return;
      int *win_x_return, *win_y_return;
      unsigned int *mask_return;

//Arguments:
display         Specifies the connection to the X server.
w               Specifies the window.
root_return     Returns the root window that the pointer is in.
child_return    Returns the child window that the pointer is located in, if any.
root_x_return
root_y_return   Return the pointer coordinates relative to the root window's origin.
win_x_return
win_y_return    Return the pointer coordinates relative to the specified window.
mask_return     Returns the current state of the modifier keys and pointer buttons. 

来自 Xlib 类,如您所见,它只返回第一个鼠标指针,不提供另一个选项。


Edit2:查看 libx11-dev 源代码,我发现在 ./src/QuPntr.c 和 Xlibint.h 中提到了它,但代码越来越难以阅读,我在这里超出了我的深度

【问题讨论】:

    标签: linux mouse xinput


    【解决方案1】:

    xinput 使用 XI2 扩展来允许多个指针。 该库 (X11/extensions/XInput2.h) 提供了以“XI”为前缀的函数,这些函数接受设备参数(xinput --list 引用的相同),例如 XIQueryPointer、XIWarpPointer 或 XIGetClientPointer。 因此,如果您的自动化工具不支持 XI2,您可以通过编程方式控制您的假指针。

    以更简单的方式,将硬件设备(从设备)xinput --reattach 指向新指针(主设备)就足够了。

    我知道答案很晚,但我通过网络搜索发现了这个问题,所以我添加了我所知道的以供参考。

    【讨论】:

      【解决方案2】:

      实际上在 xte.c 的源代码中并没有提到 XQueryPointer(在 xmousepos.c 中只有几个,这是不同工具的代码)。 在您提出问题之前,我检查了一些旧版本。

      相关函数有XIWarpPointer和XTestFakeDeviceButtonEvent。如此处简化的源代码所示:

      #include <X11/Xlib.h>
      #include <X11/extensions/XInput2.h>
      #include <X11/extensions/XTest.h>
      int main (int argc, char *argv[])
      {
        int delta_x = 500, delta_y = 160;
        Display *display = XOpenDisplay(0);
        Window root = DefaultRootWindow(display);
        XIWarpPointer(display, 14, None, root, 0, 0, 0, 0, delta_x, delta_y);
        XDevice *device = NULL;
        device = XOpenDevice(display, 16);
        XTestFakeDeviceButtonEvent(display, device, 1, True, 0, 0, CurrentTime);
        XTestFakeDeviceButtonEvent(display, device, 1, False, 0, 0, CurrentTime);
        XCloseDisplay(display);
      }
      

      xte -i 16 "mousemove 500 160" "mouseclick 1" 做同样的事情。

      但是可能会困扰您的事情(至少它困扰我):被点击的窗口获得焦点,实际上使您正在处理的窗口失去焦点。
      实际上,我最近问了一个问题,要求提供 XTestFakeDeviceButtonEvent 的替代方法(Sending a button press event for a second pointing device;我还提供了一些示例代码,这些代码实际上执行鼠标点击而不将焦点放在窗口上,所以这是可能的,但不知道它是如何用另一个指针设备完成的) .. 另一种方法可能是使用多个 X 会话,就像这个用户所做的那样:Controlling multiple pointers with Xlib or xinput in ubuntu/linux。可悲的是,他没有共享任何代码。 我对 uinput (https://www.kernel.org/doc/html/v4.12/input/uinput.html) 有一些希望,但还没有尝试过。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-24
        • 2013-09-09
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 2010-10-15
        相关资源
        最近更新 更多