鼠标事件回调 [英] Mouse events callback

查看:40
本文介绍了鼠标事件回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 WinAPI SetWindowsHookEx 和 OS X Objective-c [NSEvent addLocalMonitorForEventsMatchingMask:handler:] 两者都设置了回调,然后我无休止地运行事件循环,回调在需要时触发.

I was using WinAPI SetWindowsHookEx and OS X objective-c [NSEvent addLocalMonitorForEventsMatchingMask:handler:] which both set up a callback and then i run the event loop endlessly and the callback triggers whenver it needs.

我只将这个钩子插入到我的进程/应用程序中(但如果我也可以在系统范围内进行,那就太酷了).当用户进行鼠标组合时,我会跟踪它们,如果组合匹配特定模式,它会阻止最后一次鼠标事件并执行特定功能.

I insert this hook into just my process/application (but it would be cool if I could do system wide as well). As users do mouse combinations I track them, and if a combination matches a certain pattern, it blocks the last mouse event and does a certain function.

我想知道 x11 的等价物是什么?

I was wondering what would be the x11 equivalent?

我找到了这个主题:X11 鼠标移动事件

但这似乎完全监控了所有事件,而他只是过滤掉了鼠标事件.这也是一种锁定非回调方法,这没问题,因为我是从专用线程运行此代码的.但理想情况下,我更喜欢回调方法,因为我的主线程必须向该线程发送消息,例如有关活动窗口更改的消息,如果它卡在循环中,它将永远不会停止获取该活动窗口更改消息.

But that seems to monitor absolutely all events, and he's just filtering out the mouse ones. This one is also a locking non-callback method, which is ok because i'm running this code from a dedicated thread. But ideally I would prefer a callback method because my main thread has to send messages to this thread like about the active window changing, and if its stuck in a loop it will never let up to get that active window change message.

推荐答案

如果您希望它在全局范围内工作,您可能必须为此修补内核.一些背景.

You will probably have to patch the kernel for this if you want this to work globally. Some background.

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

I'm not sure about OS X but Windows is a very insecure OS. For example, every process can install a hook via SetWindowsHookEx and monitor the mouse and keyboard - it's basically a key logger. A few years ago, no anti virus tool would report this. I don't know how it is today.

但从本质上讲,Windows 是一个协作操作系统.这意味着 GUI 运行计算机.具有控制权的应用程序(= 活动应用程序)获取所有事件.如果应用程序锁定,Windows 将锁定(鼠标和键盘已死).如果您在另一个窗口中单击并且活动应用程序显示否",则新窗口不会变为活动窗口.我记得我们做了一些事情来让事情变得更好,但这就是 Windows 过去如此不稳定的原因之一 - 某些应用程序中的一个错误导致整个系统变得错误.

But at the core, Windows is a cooperative OS. That means the GUI runs the computer. The application which has control (= the active one) gets all the events. If the application locks up, Windows locks up (mouse and keyboard are dead). If you click in another window and the active application says "No", then the new window doesn't become active. I remember that something was done to make things better but that's one of the reasons why Windows was so unstable in the past - one bug in some app and the whole system becomes buggy.

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

On Unix, the kernel doesn't care about the UI (which comes with it's own bag of problems). Instead, there is a program (a normal process) called the X server. From the kernel point of view, this program isn't any different from the others. The kernel handles mouse and keyboard. If X locks up, the keyboard still works (so you can switch to a text console, for example).

这意味着 X 读取像 /dev/input/mice 这样的设备(它合并了当前连接到您计算机的所有鼠标的所有鼠标事件).您的键盘位于 /dev/input/by-id/ 下的某个位置.这些设备由 X 维护为内核并使用.X 只是这里的客户.内核作为控制.

That means X reads devices like /dev/input/mice (which merges all mouse events from all the mice that are currently connected to your computer). Your keyboard is somewhere under /dev/input/by-id/. These devices are maintained be the kernel and used by X. X is just a customer here. Kernel as control.

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

If a program uses the X library, that means it creates a socket connection to the X server. The server processes the mouse and keyboard events sent by the kernel devices. These are turned into XEvent structures and send to the client. Rendering happens in the server, the client sends drawing commands to the server.

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

Which makes it hard to take control of mouse and keyboard from an X client - it's pretty far away from the source. If you create artificial events, they get flagged as "synthetic" and most programs ignore those - they are a security threat.

上面列出的设备只能由 root 读取,因此也不容易听取用户所做的一切.

The devices listed above can only be read by root, so it's also not easy to listen to everything that the user does.

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

All in all, if you want to do this for all programs on the X display, you will need a programming running as root and probably a kernel module which allows you to inject events and expose them as a new event device under /dev/input/. And you need to configure X to listen to your new device. And even then, I don't think you can cancel events from other devices, just add your own.

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

If you need this just for a single application, then things are much easier. First, you need to add an event listener to all the windows which you create. In the handler, you can then analyze the mouse movements. Use the necessary Button*Mask and *MotionMask bits to get the events that you need.

如果您不关心安全性,那么您可以让您的应用程序接受合成事件并只注入您的新事件.问题是 X 没有取消事件"的概念.您也许可以使用事件传播规则来实现您想要的;请参阅此页面上的设备事件传播":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

If you don't care about security, you can then make your application accept synthetic events and just inject your new events. The problem is that X has no concept of "cancel event". You may be able to use the event propagation rules to achieve what you want; see "Propagation of Device Events" on this page: 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.

You should probably also read chapter 2 which gives an overview of X.

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

One more thing: X is not thread safe. You must not call X functions from outside of the main thread. If you do, you'll get errors or your program will crash.

相关:

这篇关于鼠标事件回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆