J'essaie d'écrire un simple clicker de souris pour Ubuntu via x11.Différence entre XTestFakeButtonEvent et XSendEvent
Pour la première variante i a d'abord écrit (basé sur XSendEvent) de la procédure en cliquant sur:
#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);
}
Ce code fonctionne très bien sur toutes les applications sauf chrome (avec des œuvres mozilla bien aussi).
j'ai donc écrit deuxième variante (basée sur 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);
}
Et ce code fonctionne très bien everyvere comprennent chrome.
appel de ces fonctions est très simple
// XSendEvent variant
mouseClick(1);
// XTestFakeButtonEvent variant
SendClick(1, true); // press lmb
SendClick(1, false); // release lmb
1: aidez-moi à comprendre ce que je fais mal (ou ce mal dans le chrome peut-être) dans la première variante.
1.1: Je pense que j'essaye d'envoyer l'événement pas pour la fenêtre nécessaire, quand j'ouvre l'affichage avec XOpenDisplay (NULL) ;. Le chrome a-t-il un système de connexion différent avec le serveur x11? 2: est-ce une bonne idée d'utiliser une deuxième variante dans les applications? C'est assez court et fonctionne bien avec chaque application que j'ai)
P.S. Pour compiler ce code, vous devez ajouter -lX11 -lXtst libs
Thx man. Comme je comprends chrome avoir une protection anti-clicker et vous ne pouvez pas utiliser XSendEvent parce XSendEvent permettre d'envoyer cliquez non seulement pour la fenêtre active, mais pour toute fenêtre, de sorte que vous pouvez faire des clics dans la fenêtre non active pendant que l'utilisateur ne voit pas) Je suis regardé le code source de xdotool._xdo_mousebutton utilise XTestFakeButtonEvent si vous envoyez un clic sur CURRENTWINDOW et XSendEvent dans les autres cas. – goldstar