2

我有一个使用 Xlib 库在屏幕上模拟鼠标的应用程序。

我使用了 XQueryPointer 和 XWarpPointer 函数,我可以使用它们来模拟鼠标移动和单击。我的问题是我不能“拖动”一个元素(它是一个带有一些块的接口,您可以在用 C++ 编写并在 Ubuntu 上启动的 Qt 应用程序中移动这些块)。

我使用了这个提取物的许多部分:

发送 X11 点击事件不适用于某些窗口

这个功能可以帮助我吗?

::XGrabPointer(mDisplay, window, True,
           ButtonPressMask |
             ButtonReleaseMask |
             PointerMotionMask |
             FocusChangeMask |
             EnterWindowMask |
              LeaveWindowMask,
           GrabModeAsync,
           GrabModeAsync,
           RootWindow(mDisplay, DefaultScreen(mDisplay)),
           None,
           CurrentTime);

你有什么主意吗?

先感谢您。

4

2 回答 2

2

如果您可以生成子进程,您可以轻松地使用xdotool它,如下所示:

xdotool mousedown 1
sleep 0.5
xdotool mousemove_relative --sync 200 200
sleep 0.5
xdotool mouseup 1

http://www.semicomplete.com/projects/xdotool/

http://tuxradar.com/content/xdotool-script-your-mouse

如果您想在 C 中使用库自己执行此操作,源代码xdotool将作为一个很好的起点。XTest

于 2017-11-01T01:26:15.637 回答
1

您可以通过将XMotionEvent发送到窗口来实现此目的。X11 知道它是一个拖动事件的方法是检查状态。因此,如果状态是与 Button1Mask 的 OR,则意味着当 Button1 被按下时动作完成。

我在这里粘贴伪代码。您可能希望根据您的用例填充 XMotionEvent 的相关字段。

Display *OpenedDisplay = XOpenDisplay(NULL);

int ret = 0,screen = 0;
XMotionEvent xbpe;

Window dummy;
unsigned int mask,dummyUInt;
int dummyInt;

int screencount = ScreenCount(xbpe.display);
for (int i = 0; i < screencount; i++) {
    Screen *screenPointer = ScreenOfDisplay(xbpe.display, i);
    ret = XQueryPointer(xbpe.display, RootWindowOfScreen(screenPointer), &dummy, &dummy,
                        &dummyInt, &dummyInt, &dummyInt, &dummyInt, &mask);
    if (ret == True) {
      screen = i;
      break;
    }
}

xbpe.type = MotionNotify;
xbpe.display = OpenedDisplay;
xbpe.window = wid;
xbpe.root = RootWindow(xbpe.display, screen);
xbpe.subwindow = None;
xbpe.time = CurrentTime;
xbpe.x = src_x;
xbpe.y = src_y;

xbpe.state = mask;
xbpe.is_hint = NotifyNormal;
xbpe.same_screen = True; /* Should we detect if window is on the same screen as cursor? */

XWindowAttributes attr;
ret = XGetWindowAttributes(xbpe.display, wid, &attr);
if(ret == 0){
    qDebug() << wid <<"XGetWindowAttributes unsuccessfull returning early";
    return;
}
/**************************** This is key here *******************/
if(isDrag){
    xbpe.state |= Button1Mask;
}

ret = XSendEvent(xbpe.display, wid, False, PointerMotionMask|ButtonMotionMask|MotionNotify, (XEvent *)&xbpe);
XFlush(OpenedDisplay);
XCloseDisplay(OpenedDisplay);

我建议浏览xdotool的源代码。它没有专门涵盖您的问题,但为您提供了有关填充 X*Event 字段的足够信息。

于 2019-03-14T09:27:22.057 回答