gpt4 book ai didi

c++ - XTestFakeButtonEvent 和 XSendEvent 之间的区别

转载 作者:太空狗 更新时间:2023-10-29 21:14:03 26 4
gpt4 key购买 nike

我正在尝试通过 x11 为 ubuntu 编写简单的鼠标点击器。

首先,我编写了点击过程的第一个变体(基于 XSendEvent):

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

void mouseClick(int button)
{
Display *display = XOpenDisplay(NULL);

XEvent event;

if(display == NULL)
{
std::cout << "clicking error 0" << std::endl;
exit(EXIT_FAILURE);
}

memset(&event, 0x00, sizeof(event));

event.type = ButtonPress;
event.xbutton.button = button;
event.xbutton.same_screen = True;

XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);

event.xbutton.subwindow = event.xbutton.window;

while(event.xbutton.subwindow)
{
event.xbutton.window = event.xbutton.subwindow;
XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
}

if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0)
std::cout << "clicking error 1" << std::endl;

XFlush(display);

event.type = ButtonRelease;
event.xbutton.state = 0x100;

if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0)
std::cout << "clicking error 2" << std::endl;

XFlush(display);

XCloseDisplay(display);
}

此代码在除 chrome 之外的所有应用程序上都能正常工作(在 mozilla 上也能正常工作)。

所以我写了第二个变体(基于 XTestFakeButtonEvent):

#include <X11/extensions/XTest.h>

void SendClick(int button, Bool down)
{
Display *display = XOpenDisplay(NULL);
XTestFakeButtonEvent(display, button, down, CurrentTime);
XFlush(display);
XCloseDisplay(display);
}

而且这段代码在任何情况下都可以正常工作,包括 chrome。

调用这些函数非常简单

// XSendEvent variant
mouseClick(1);

// XTestFakeButtonEvent variant
SendClick(1, true); // press lmb
SendClick(1, false); // release lmb

1:帮助我理解我在第一个变体中做错了什么(或者 chrome 可能有什么错误)。

1.1:当我使用 XOpenDisplay(NULL); 打开显示时,我认为我正在尝试发送不需要的窗口的事件。 chrome 与 x11 服务器有不同的连接系统吗?

2:在应用程序中使用第二种变体是个好主意吗?它很短,适用于我拥有的每个应用程序)

附言要编译此代码,您需要添加 -lX11 -lXtst libs

最佳答案

XSendEvent 生成标记为已发送的事件。服务器发送的事件没有被标记。

   typedef struct {
int type;
unsigned long serial;
Bool send_event;  // <----- here
Display *display;
Window window;
} XAnyEvent;

出于安全原因,某些应用程序会忽略设置了此标志的事件。想想以某种方式访问​​您的 X11 服务器的恶意软件 — 它可以通过发送这些事件来欺骗任何应用程序做它想做的事。

在您自己的机器上使用第二个变体是完全可以的,但它依赖于一个可以禁用的扩展(同样,出于安全原因),因此不一定适用于其他人的 X11 服务器。

关于c++ - XTestFakeButtonEvent 和 XSendEvent 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42013047/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com