【问题标题】:Qt: monitor global cursor click event with X11?Qt:用 X11 监控全局光标点击事件?
【发布时间】:2012-04-10 00:33:09
【问题描述】:

我现在想在 X11 中捕获全局鼠标点击事件

我尝试安装 x11event 过滤器,但它无法在全局范围内工作。

class XApplication: public QApplication
{
  public:
    XApplication (int & argc, char **argv):
        QApplication (argc , argv)
    {
    }

protected:
    bool x11EventFilter (XEvent *e)
    {
        qDebug() << "X11 Event: " << e->type;
        return QApplication::x11EventFilter(e);
    }
};

更新

我的意思是在窗口之外,当我点击窗口时,上面的代码有效。

【问题讨论】:

  • 定义“全局鼠标点击”。单击应用程序窗口内的任意位置?单击任何窗口内的任意位置,包括应用程序窗口之外?您确定 Qt 已订阅以接收您想要的事件吗?我的猜测是过滤器只会向您显示您的 Qt 应用程序订阅接收的事件......

标签: qt events mouseevent xorg qt4.7


【解决方案1】:

您可以使用 QX11Info 类从 Qt 查询 X11 信息。请参阅其文档。然后你可以使用它的原始 Xlib。

您可以使用XGrabPointer()。如果你使用它,其他应用程序在抓取指针时不会收到指针事件。 man XGrabPointer 会帮助你。

订阅事件的“正常”方式是在窗口上使用XSelectInput(),但问题是您必须在每个现有窗口上调用 XSelectInput。查看它的手册页...

我知道 xxf86dga 扩展有一些与鼠标相关的调用,但我不确定它们是做什么的。

XQueryPointer() 是另一种查询指针状态而不窃取其他窗口事件的方法。

我能想到的唯一其他地方是 XInput 扩展,但我不确定它是否对您有帮助。

请参阅xev 源代码以获取有关处理 X11 事件的良好参考:http://cgit.freedesktop.org/xorg/app/xev

使用 XGrabPointer 的示例代码:

#include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>

int main(void)
{
        Display *d;
        Window root;

        d = XOpenDisplay(NULL);
        assert(d);

        root = DefaultRootWindow(d);

        XGrabPointer(d, root, False, ButtonPressMask | ButtonReleaseMask |
                     PointerMotionMask, GrabModeAsync, GrabModeAsync, None,
                     None, CurrentTime);

        XEvent ev;
        while (1) {                     
                XNextEvent(d, &ev);  
                switch (ev.type) { 
                case ButtonPress:
                        printf("Button press event!\n");
                        break;
                case ButtonRelease:
                        printf("Button release event!\n");
                        break;
                case MotionNotify:
                        printf("Motion notify event!\n");
                        break;
                default:
                        printf("Unknown event...\n");
                } 
        } 

        XCloseDisplay(d);
        return 0;
}

编译使用:gcc x11mouse.c -o x11mouse -lX11

【讨论】:

  • 我认为XSelectInput 或等效项可以应用于整个显示器,而不仅仅是孤立的每个窗口,因此无论特定窗口处于活动状态如何都会产生事件。至少使用 python-xlib 你得到了它,而 IIRC 它映射到 XSelectInput 但它实际上可能映射到其他一些 X11 API。无论哪种方式,您都不需要单独捕获每个窗口以获得全面覆盖。至少在我迄今为止的短暂经历中。
猜你喜欢
  • 2015-01-30
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 2013-02-05
  • 1970-01-01
相关资源
最近更新 更多