鼠标事件回调

Mouse events callback

我正在使用 WinAPI SetWindowsHookEx 和 OS X objective-c [NSEvent addLocalMonitorForEventsMatchingMask:handler:] 它们都设置了一个回调然后我 运行 事件循环无休止地和回调在需要时触发。

我将这个挂钩插入到我的 process/application 中(但如果我也可以在系统范围内进行操作,那就太棒了)。当用户进行鼠标组合时,我会跟踪它们,如果组合匹配特定模式,它会阻止最后的鼠标事件并执行特定功能。

我想知道 x11 等效项是什么?

我找到了这个主题:X11 Mouse Movement Event

但这似乎绝对监控所有事件,他只是过滤掉鼠标事件。这也是一种锁定非回调方法,这没关系,因为我 运行 从专用线程中调用此代码。但理想情况下,我更喜欢回调方法,因为我的主线程必须向这个线程发送消息,比如关于活动 window 的变化,如果它卡在一个循环中,它永远不会放松以获得那个活动 window 更改消息。

如果你想让它在全球范围内工作,你可能必须为此修补内核。一些背景。

我不确定 OS X,但 Windows 是一个非常不安全的 OS。例如,每个进程都可以通过 SetWindowsHookEx 安装一个钩子并监控鼠标和键盘——它基本上是一个键盘记录器。几年前,没有反病毒工具会报告这一点。不知道今天怎么样

但本质上,Windows 是一个合作社 OS。这意味着 GUI 运行计算机。具有控制权的应用程序(=活动的应用程序)获取所有事件。如果应用程序锁定,Windows 锁定(鼠标和键盘已死)。如果您单击另一个 window 并且活动应用程序显示 "No",则新的 window 不会变为活动状态。我记得有人做了一些事情来让事情变得更好,但这就是为什么 Windows 过去如此不稳定的原因之一 - 某些应用程序中的一个错误,整个系统都会出现错误。

在 Unix 上,内核不关心 UI(它有自己的问题包)。取而代之的是一个名为 X 服务器的程序(一个正常进程)。从内核的角度来看,这个程序与其他程序没有任何不同。内核处理鼠标和键盘。如果 X 锁定,键盘仍然有效(例如,您可以切换到文本控制台)。

这意味着 X 读取类似 /dev/input/mice 的设备(它合并了当前连接到您计算机的所有鼠标的所有鼠标事件)。你的键盘在 /dev/input/by-id/ 下面的某个地方。这些设备由内核维护,X 使用。X 只是这里的客户。内核作为控件。

如果程序使用 X 库,则意味着它会创建到 X 服务器的套接字连接。服务器处理内核设备发送的鼠标和键盘事件。这些被转换成 XEvent 结构并发送给客户端。渲染发生在服务端,客户端向服务端发送绘图命令。

这使得很难从 X 客户端控制鼠标和键盘 - 它离源代码很远。如果您创建人为事件,它们会被标记为 "synthetic" 并且大多数程序会忽略这些 - 它们是安全威胁。

上面列出的设备只能被root读取,所以也不容易听到用户所做的一切。

总而言之,如果你想对 X 显示器上的所有程序都这样做,你将需要一个编程 运行 作为 root 并且可能需要一个允许你注入事件的内核模块并将它们作为 /dev/input/ 下的新事件设备公开。您需要配置 X 来收听您的新设备。即便如此,我认为您也无法取消来自其他设备的事件,只需添加您自己的即可。

如果您只是为单个应用程序需要它,那么事情就容易多了。首先,您需要为您创建的所有 windows 添加一个事件监听器。然后在处理程序中,您可以分析鼠标移动。使用必要的 Button*Mask*MotionMask 位来获取您需要的事件。

如果您不关心安全性,则可以让您的应用程序接受合成事件并只注入您的新事件。问题是X没有"cancel event"的概念。您也许可以使用事件传播规则来实现您想要的;请参阅此页面上的 "Propagation of Device Events":http://menehune.opt.wfu.edu/Kokua/Irix_6.5.21_doc_cd/usr/share/Insight/library/SGI_bookshelves/SGI_Developer/books/XLib_PG/sgi_html/ch08.html

您可能还应该阅读第 2 章,其中概述了 X。

还有一件事:X 不是线程安全的。您不得 从主线程外部调用 X 函数。如果你这样做,你会得到错误或者你的程序会崩溃。

相关: